List of usage examples for org.objectweb.asm Opcodes ARETURN
int ARETURN
To view the source code for org.objectweb.asm Opcodes ARETURN.
Click Source Link
From source file:org.gradle.api.internal.model.NamedObjectInstantiator.java
License:Apache License
private ClassGeneratingLoader loaderFor(Class<?> publicClass) { ////from w w w .j a v a2 s . com // Generate implementation class // FormattingValidationProblemCollector problemCollector = new FormattingValidationProblemCollector( "Named implementation class", ModelType.of(publicClass)); visitFields(publicClass, problemCollector); if (problemCollector.hasProblems()) { throw new GradleException(problemCollector.format()); } AsmClassGenerator generator = new AsmClassGenerator(publicClass, "$Impl"); Type implementationType = generator.getGeneratedType(); ClassWriter visitor = generator.getVisitor(); Type publicType = Type.getType(publicClass); Type superClass; String[] interfaces; if (publicClass.isInterface()) { superClass = OBJECT; interfaces = new String[] { publicType.getInternalName(), MANAGED.getInternalName() }; } else { superClass = publicType; interfaces = INTERFACES_FOR_ABSTRACT_CLASS; } visitor.visit(V1_5, ACC_PUBLIC | ACC_SYNTHETIC, implementationType.getInternalName(), null, superClass.getInternalName(), interfaces); // // Add name field // visitor.visitField(ACC_PRIVATE, NAME_FIELD, STRING.getDescriptor(), null, null); // // Add constructor // MethodVisitor methodVisitor = visitor.visitMethod(ACC_PUBLIC, CONSTRUCTOR_NAME, RETURN_VOID_FROM_STRING, null, EMPTY_STRINGS); methodVisitor.visitCode(); // Call this.super() methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, superClass.getInternalName(), CONSTRUCTOR_NAME, RETURN_VOID, false); // Set this.name = param1 methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); methodVisitor.visitVarInsn(Opcodes.ALOAD, 1); methodVisitor.visitFieldInsn(Opcodes.PUTFIELD, implementationType.getInternalName(), NAME_FIELD, STRING.getDescriptor()); // Done methodVisitor.visitInsn(Opcodes.RETURN); methodVisitor.visitMaxs(0, 0); methodVisitor.visitEnd(); // // Add `getName()` // methodVisitor = visitor.visitMethod(ACC_PUBLIC, "getName", RETURN_STRING, null, EMPTY_STRINGS); methodVisitor.visitCode(); // return this.name methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); methodVisitor.visitFieldInsn(Opcodes.GETFIELD, implementationType.getInternalName(), NAME_FIELD, STRING.getDescriptor()); methodVisitor.visitInsn(Opcodes.ARETURN); methodVisitor.visitMaxs(0, 0); methodVisitor.visitEnd(); // // Add `toString()` // methodVisitor = visitor.visitMethod(ACC_PUBLIC, "toString", RETURN_STRING, null, EMPTY_STRINGS); methodVisitor.visitCode(); // return this.name methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); methodVisitor.visitFieldInsn(Opcodes.GETFIELD, implementationType.getInternalName(), NAME_FIELD, STRING.getDescriptor()); methodVisitor.visitInsn(Opcodes.ARETURN); methodVisitor.visitMaxs(0, 0); methodVisitor.visitEnd(); visitor.visitEnd(); generator.define(); // // Generate factory class // generator = new AsmClassGenerator(publicClass, "$Factory"); visitor = generator.getVisitor(); visitor.visit(V1_5, ACC_PUBLIC | ACC_SYNTHETIC, generator.getGeneratedType().getInternalName(), null, CLASS_GENERATING_LOADER.getInternalName(), EMPTY_STRINGS); // // Add constructor // methodVisitor = visitor.visitMethod(ACC_PUBLIC, CONSTRUCTOR_NAME, RETURN_VOID, null, EMPTY_STRINGS); methodVisitor.visitCode(); // Call this.super() methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, CLASS_GENERATING_LOADER.getInternalName(), CONSTRUCTOR_NAME, RETURN_VOID, false); // Done methodVisitor.visitInsn(Opcodes.RETURN); methodVisitor.visitMaxs(0, 0); methodVisitor.visitEnd(); // // Add factory method // methodVisitor = visitor.visitMethod(ACC_PUBLIC, "load", RETURN_OBJECT_FROM_STRING, null, EMPTY_STRINGS); methodVisitor.visitCode(); // Call return new <implClass>(param1) methodVisitor.visitTypeInsn(Opcodes.NEW, implementationType.getInternalName()); methodVisitor.visitInsn(Opcodes.DUP); methodVisitor.visitVarInsn(Opcodes.ALOAD, 1); methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, implementationType.getInternalName(), CONSTRUCTOR_NAME, RETURN_VOID_FROM_STRING, false); methodVisitor.visitInsn(Opcodes.ARETURN); methodVisitor.visitMaxs(0, 0); methodVisitor.visitEnd(); visitor.visitEnd(); Class<Object> factoryClass = generator.define(); try { return (ClassGeneratingLoader) factoryClass.getConstructor().newInstance(); } catch (Exception e) { throw UncheckedException.throwAsUncheckedException(e); } }
From source file:org.gradle.groovy.scripts.AsmBackedEmptyScriptGenerator.java
License:Apache License
private <T extends Script> Class<? extends T> generateEmptyScriptClass(Class<T> type) { ClassWriter visitor = new ClassWriter(ClassWriter.COMPUTE_MAXS); String typeName = type.getName() + "_Decorated"; Type generatedType = Type.getType("L" + typeName.replaceAll("\\.", "/") + ";"); Type superclassType = Type.getType(type); visitor.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, generatedType.getInternalName(), null, superclassType.getInternalName(), new String[0]); // Constructor String constructorDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, new Type[0]); MethodVisitor methodVisitor = visitor.visitMethod(Opcodes.ACC_PUBLIC, "<init>", constructorDescriptor, null, new String[0]); methodVisitor.visitCode();// w w w .ja va2 s. com // super() methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, superclassType.getInternalName(), "<init>", constructorDescriptor); methodVisitor.visitInsn(Opcodes.RETURN); methodVisitor.visitMaxs(0, 0); methodVisitor.visitEnd(); // run() method String runDesciptor = Type.getMethodDescriptor(Type.getType(Object.class), new Type[0]); methodVisitor = visitor.visitMethod(Opcodes.ACC_PUBLIC, "run", runDesciptor, null, new String[0]); methodVisitor.visitCode(); // return null methodVisitor.visitInsn(Opcodes.ACONST_NULL); methodVisitor.visitInsn(Opcodes.ARETURN); methodVisitor.visitMaxs(0, 0); methodVisitor.visitEnd(); visitor.visitEnd(); byte[] bytecode = visitor.toByteArray(); return (Class<T>) ReflectionUtil.invoke(type.getClassLoader(), "defineClass", new Object[] { typeName, bytecode, 0, bytecode.length }); }
From source file:org.gradle.initialization.ExceptionDecoratingClassGenerator.java
License:Apache License
private <T> Class<? extends T> doGenerate(Class<T> type) { ClassWriter visitor = new ClassWriter(ClassWriter.COMPUTE_MAXS); String typeName = StringUtils.substringBeforeLast(type.getName(), ".") + ".LocationAware" + type.getSimpleName();/*from w ww. j a v a2 s .c o m*/ Type generatedType = Type.getType("L" + typeName.replaceAll("\\.", "/") + ";"); Type superclassType = Type.getType(type); visitor.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, generatedType.getInternalName(), null, superclassType.getInternalName(), new String[] { Type.getType(LocationAwareException.class).getInternalName() }); Type helperType = Type.getType(ExceptionHelper.class); Type throwableType = Type.getType(Throwable.class); Type scriptSourceType = Type.getType(ScriptSource.class); Type integerType = Type.getType(Integer.class); // GENERATE private ExceptionHelper helper; visitor.visitField(Opcodes.ACC_PRIVATE, "helper", helperType.getDescriptor(), null, null); // GENERATE <init>(<type> target, ScriptSource source, Integer lineNumber) String methodDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { superclassType, scriptSourceType, integerType }); MethodVisitor methodVisitor = visitor.visitMethod(Opcodes.ACC_PUBLIC, "<init>", methodDescriptor, null, new String[0]); methodVisitor.visitCode(); boolean noArgsConstructor; try { type.getConstructor(type); noArgsConstructor = false; } catch (NoSuchMethodException e) { try { type.getConstructor(); noArgsConstructor = true; } catch (NoSuchMethodException e1) { throw new IllegalArgumentException(String.format( "Cannot create subtype for exception '%s'. It needs a zero-args or copy constructor.", type.getName())); } } if (noArgsConstructor) { // GENERATE super() methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, superclassType.getInternalName(), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[0])); // END super() } else { // GENERATE super(target) methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); methodVisitor.visitVarInsn(Opcodes.ALOAD, 1); methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, superclassType.getInternalName(), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { superclassType })); // END super(target) } // GENERATE helper = new ExceptionHelper(this, target, source, lineNumber) methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); methodVisitor.visitTypeInsn(Opcodes.NEW, helperType.getInternalName()); methodVisitor.visitInsn(Opcodes.DUP); methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); methodVisitor.visitVarInsn(Opcodes.ALOAD, 1); methodVisitor.visitVarInsn(Opcodes.ALOAD, 2); methodVisitor.visitVarInsn(Opcodes.ALOAD, 3); methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, helperType.getInternalName(), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { throwableType, throwableType, scriptSourceType, integerType })); methodVisitor.visitFieldInsn(Opcodes.PUTFIELD, generatedType.getInternalName(), "helper", helperType.getDescriptor()); // END helper = new ExceptionHelper(target) methodVisitor.visitInsn(Opcodes.RETURN); methodVisitor.visitMaxs(0, 0); methodVisitor.visitEnd(); // END <init>(<type> target, ScriptSource source, Integer lineNumber) for (Method method : ExceptionHelper.class.getDeclaredMethods()) { // GENERATE public <type> <method>() { return helper.<method>(); } methodDescriptor = Type.getMethodDescriptor(Type.getType(method.getReturnType()), new Type[0]); methodVisitor = visitor.visitMethod(Opcodes.ACC_PUBLIC, method.getName(), methodDescriptor, null, new String[0]); methodVisitor.visitCode(); methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); methodVisitor.visitFieldInsn(Opcodes.GETFIELD, generatedType.getInternalName(), "helper", helperType.getDescriptor()); methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, helperType.getInternalName(), method.getName(), methodDescriptor); methodVisitor.visitInsn(Opcodes.ARETURN); methodVisitor.visitMaxs(0, 0); methodVisitor.visitEnd(); // END public <type> <method>() { return helper.<method>(); } } visitor.visitEnd(); byte[] bytecode = visitor.toByteArray(); return (Class<T>) ReflectionUtil.invoke(type.getClassLoader(), "defineClass", new Object[] { typeName, bytecode, 0, bytecode.length }); }
From source file:org.jacoco.core.internal.analysis.AC_MethodAnalyzerTest.java
License:Open Source License
private void createIfBranch() { final Label l0 = new Label(); method.visitLabel(l0);//from w w w . j a v a 2 s . co m method.visitLineNumber(1001, l0); method.visitVarInsn(Opcodes.ILOAD, 1); Label l1 = new Label(); method.visitJumpInsn(Opcodes.IFEQ, l1); final Label l2 = new Label(); method.visitLabel(l2); method.visitLineNumber(1002, l2); method.visitLdcInsn("a"); method.visitInsn(Opcodes.ARETURN); method.visitLabel(l1); method.visitLineNumber(1003, l1); method.visitLdcInsn("b"); method.visitInsn(Opcodes.ARETURN); }
From source file:org.jacoco.core.internal.analysis.filter.FinallyFilter.java
License:Open Source License
private static void filter(final IFilterOutput output, final List<TryCatchBlockNode> tryCatchBlocks, final TryCatchBlockNode catchAnyBlock) { final AbstractInsnNode e = next(catchAnyBlock.handler); final int size = size(e); if (size <= 0) { return;/* w w w . j av a 2s.c o m*/ } // Determine instructions inside regions final Set<AbstractInsnNode> inside = new HashSet<AbstractInsnNode>(); for (final TryCatchBlockNode t : tryCatchBlocks) { if (t.handler == catchAnyBlock.handler) { AbstractInsnNode i = t.start; while (i != t.end) { inside.add(i); i = i.getNext(); } } } // Find and merge duplicates at exits of regions for (final TryCatchBlockNode t : tryCatchBlocks) { if (t.handler == catchAnyBlock.handler) { boolean continues = false; AbstractInsnNode i = t.start; while (i != t.end) { switch (i.getType()) { case AbstractInsnNode.FRAME: case AbstractInsnNode.LINE: case AbstractInsnNode.LABEL: break; case AbstractInsnNode.JUMP_INSN: final AbstractInsnNode jumpTarget = next(((JumpInsnNode) i).label); if (!inside.contains(jumpTarget)) { merge(output, size, e, jumpTarget); } continues = i.getOpcode() != Opcodes.GOTO; break; default: switch (i.getOpcode()) { case Opcodes.IRETURN: case Opcodes.LRETURN: case Opcodes.FRETURN: case Opcodes.DRETURN: case Opcodes.ARETURN: case Opcodes.RETURN: case Opcodes.ATHROW: continues = false; break; default: continues = true; break; } break; } i = i.getNext(); } i = next(i); if (continues && !inside.contains(i)) { merge(output, size, e, i); } } if (t != catchAnyBlock && t.start == catchAnyBlock.start && t.end == catchAnyBlock.end) { final AbstractInsnNode i = next(next(t.handler)); if (!inside.contains(i)) { // javac's empty catch - merge after ASTORE merge(output, size, e, i); } } } }
From source file:org.jacoco.core.internal.analysis.filter.KotlinCoroutineFilterTest.java
License:Open Source License
@Test public void should_filter_suspending_lambdas_generated_by_Kotlin_1_3_30() { final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0, "invokeSuspend", "(Ljava/lang/Object;)Ljava/lang/Object;", null, null); context.classAnnotations.add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC); m.visitLabel(new Label()); final Range range1 = new Range(); range1.fromInclusive = m.instructions.getLast(); m.visitMethodInsn(Opcodes.INVOKESTATIC, "kotlin/coroutines/intrinsics/IntrinsicsKt", "getCOROUTINE_SUSPENDED", "()Ljava/lang/Object;", false); m.visitVarInsn(Opcodes.ASTORE, 4);//from w w w . ja v a2s.c om m.visitVarInsn(Opcodes.ALOAD, 0); // line of "runBlocking" m.visitFieldInsn(Opcodes.GETFIELD, "Target", "label", "I"); final Label dflt = new Label(); final Label state0 = new Label(); final Label state1 = new Label(); m.visitTableSwitchInsn(0, 1, dflt, state0, state1); m.visitLabel(state0); { m.visitVarInsn(Opcodes.ALOAD, 1); m.visitMethodInsn(Opcodes.INVOKESTATIC, "kotlin/ResultKt", "throwOnFailure", "(Ljava/lang/Object;)V", false); range1.toInclusive = m.instructions.getLast(); } // line before "suspendingFunction" m.visitInsn(Opcodes.NOP); // line of "suspendingFunction" m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "", "suspendingFunction", "(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;", false); m.visitInsn(Opcodes.DUP); final Range range2 = new Range(); range2.fromInclusive = m.instructions.getLast(); m.visitVarInsn(Opcodes.ALOAD, 4); final Label continuationLabelAfterLoadedResult = new Label(); m.visitJumpInsn(Opcodes.IF_ACMPNE, continuationLabelAfterLoadedResult); // line of "runBlocking" m.visitVarInsn(Opcodes.ALOAD, 4); m.visitInsn(Opcodes.ARETURN); m.visitLabel(state1); m.visitVarInsn(Opcodes.ALOAD, 0); m.visitFieldInsn(Opcodes.GETFIELD, "Target", "I$0", "I"); m.visitVarInsn(Opcodes.ISTORE, 3); { m.visitVarInsn(Opcodes.ALOAD, 1); m.visitMethodInsn(Opcodes.INVOKESTATIC, "kotlin/ResultKt", "throwOnFailure", "(Ljava/lang/Object;)V", false); } m.visitVarInsn(Opcodes.ALOAD, 1); range2.toInclusive = m.instructions.getLast(); m.visitLabel(continuationLabelAfterLoadedResult); // line after "suspendingFunction" m.visitInsn(Opcodes.NOP); m.visitInsn(Opcodes.ARETURN); m.visitLabel(dflt); final Range range0 = new Range(); range0.fromInclusive = m.instructions.getLast(); m.visitTypeInsn(Opcodes.NEW, "java/lang/IllegalStateException"); m.visitInsn(Opcodes.DUP); m.visitLdcInsn("call to 'resume' before 'invoke' with coroutine"); m.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/IllegalStateException", "<init>", "(Ljava/lang/String;)V", false); m.visitInsn(Opcodes.ATHROW); range0.toInclusive = m.instructions.getLast(); filter.filter(m, context, output); assertIgnored(range0, range1, range2); }
From source file:org.jacoco.core.internal.analysis.filter.KotlinCoroutineFilterTest.java
License:Open Source License
/** * <pre>//from w w w .ja v a2 s . c o m * runBlocking { * val x = 42 * nop(x) * suspendingFunction() * nop(x) * } * </pre> */ @Test public void should_filter_suspending_lambdas() { final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0, "invokeSuspend", "(Ljava/lang/Object;)Ljava/lang/Object;", null, null); context.classAnnotations.add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC); m.visitLabel(new Label()); final Range range1 = new Range(); range1.fromInclusive = m.instructions.getLast(); m.visitMethodInsn(Opcodes.INVOKESTATIC, "kotlin/coroutines/intrinsics/IntrinsicsKt", "getCOROUTINE_SUSPENDED", "()Ljava/lang/Object;", false); m.visitVarInsn(Opcodes.ASTORE, 4); m.visitVarInsn(Opcodes.ALOAD, 0); // line of "runBlocking" m.visitFieldInsn(Opcodes.GETFIELD, "Target", "label", "I"); final Label dflt = new Label(); final Label state0 = new Label(); final Label state1 = new Label(); m.visitTableSwitchInsn(0, 1, dflt, state0, state1); m.visitLabel(state0); { m.visitVarInsn(Opcodes.ALOAD, 1); m.visitInsn(Opcodes.DUP); m.visitTypeInsn(Opcodes.INSTANCEOF, "kotlin/Result$Failure"); Label label = new Label(); m.visitJumpInsn(Opcodes.IFEQ, label); m.visitTypeInsn(Opcodes.CHECKCAST, "kotlin/Result$Failure"); m.visitFieldInsn(Opcodes.GETFIELD, "kotlin/Result$Failure", "exception", "Ljava/lang/Throwable"); m.visitInsn(Opcodes.ATHROW); m.visitInsn(Opcodes.POP); range1.toInclusive = m.instructions.getLast(); m.visitLabel(label); } // line before "suspendingFunction" m.visitInsn(Opcodes.NOP); // line of "suspendingFunction" m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "", "suspendingFunction", "(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;", false); m.visitInsn(Opcodes.DUP); final Range range2 = new Range(); range2.fromInclusive = m.instructions.getLast(); m.visitVarInsn(Opcodes.ALOAD, 4); final Label continuationLabelAfterLoadedResult = new Label(); m.visitJumpInsn(Opcodes.IF_ACMPNE, continuationLabelAfterLoadedResult); // line of "runBlocking" m.visitVarInsn(Opcodes.ALOAD, 4); m.visitInsn(Opcodes.ARETURN); m.visitLabel(state1); m.visitVarInsn(Opcodes.ALOAD, 0); m.visitFieldInsn(Opcodes.GETFIELD, "Target", "I$0", "I"); m.visitVarInsn(Opcodes.ISTORE, 3); { m.visitVarInsn(Opcodes.ALOAD, 1); m.visitInsn(Opcodes.DUP); m.visitTypeInsn(Opcodes.INSTANCEOF, "kotlin/Result$Failure"); final Label label = new Label(); m.visitJumpInsn(Opcodes.IFEQ, label); m.visitTypeInsn(Opcodes.CHECKCAST, "kotlin/Result$Failure"); m.visitFieldInsn(Opcodes.GETFIELD, "kotlin/Result$Failure", "exception", "Ljava/lang/Throwable"); m.visitInsn(Opcodes.ATHROW); m.visitInsn(Opcodes.POP); m.visitLabel(label); } m.visitVarInsn(Opcodes.ALOAD, 1); range2.toInclusive = m.instructions.getLast(); m.visitLabel(continuationLabelAfterLoadedResult); // line after "suspendingFunction" m.visitInsn(Opcodes.NOP); m.visitInsn(Opcodes.ARETURN); m.visitLabel(dflt); final Range range0 = new Range(); range0.fromInclusive = m.instructions.getLast(); m.visitTypeInsn(Opcodes.NEW, "java/lang/IllegalStateException"); m.visitInsn(Opcodes.DUP); m.visitLdcInsn("call to 'resume' before 'invoke' with coroutine"); m.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/IllegalStateException", "<init>", "(Ljava/lang/String;)V", false); m.visitInsn(Opcodes.ATHROW); range0.toInclusive = m.instructions.getLast(); filter.filter(m, context, output); assertIgnored(range0, range1, range2); }
From source file:org.jacoco.core.internal.analysis.filter.KotlinCoroutineFilterTest.java
License:Open Source License
/** * <pre>//from ww w .j a v a2 s .com * suspend fun example() { * suspendingFunction() * nop() * } * </pre> */ @Test public void should_filter_suspending_functions() { final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, Opcodes.ACC_STATIC, "example", "(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;", null, null); context.classAnnotations.add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC); final int continuationArgumentIndex = 0; final int continuationIndex = 2; m.visitVarInsn(Opcodes.ALOAD, continuationArgumentIndex); final Range range1 = new Range(); range1.fromInclusive = m.instructions.getLast(); m.visitTypeInsn(Opcodes.INSTANCEOF, "ExampleKt$example$1"); final Label createStateInstance = new Label(); m.visitJumpInsn(Opcodes.IFEQ, createStateInstance); m.visitVarInsn(Opcodes.ALOAD, continuationArgumentIndex); m.visitTypeInsn(Opcodes.CHECKCAST, "ExampleKt$example$1"); m.visitVarInsn(Opcodes.ASTORE, continuationIndex); m.visitVarInsn(Opcodes.ALOAD, continuationIndex); m.visitFieldInsn(Opcodes.GETFIELD, "ExampleKt$example$1", "label", "I"); m.visitLdcInsn(Integer.valueOf(Integer.MIN_VALUE)); m.visitInsn(Opcodes.IAND); m.visitJumpInsn(Opcodes.IFEQ, createStateInstance); m.visitVarInsn(Opcodes.ALOAD, continuationIndex); m.visitInsn(Opcodes.DUP); m.visitFieldInsn(Opcodes.GETFIELD, "ExampleKt$example$1", "label", "I"); m.visitLdcInsn(Integer.valueOf(Integer.MIN_VALUE)); m.visitInsn(Opcodes.ISUB); m.visitFieldInsn(Opcodes.PUTFIELD, "ExampleKt$example$1", "label", "I"); final Label afterCoroutineStateCreated = new Label(); m.visitJumpInsn(Opcodes.GOTO, afterCoroutineStateCreated); m.visitLabel(createStateInstance); m.visitTypeInsn(Opcodes.NEW, "ExampleKt$example$1"); m.visitInsn(Opcodes.DUP); m.visitVarInsn(Opcodes.ALOAD, continuationArgumentIndex); m.visitMethodInsn(Opcodes.INVOKESPECIAL, "ExampleKt$example$1", "<init>", "(Lkotlin/coroutines/Continuation;)V", false); m.visitVarInsn(Opcodes.ASTORE, continuationIndex); m.visitLabel(afterCoroutineStateCreated); m.visitVarInsn(Opcodes.ALOAD, continuationIndex); m.visitFieldInsn(Opcodes.GETFIELD, "ExampleKt$example$1", "result", "Ljava/lang/Object;"); m.visitVarInsn(Opcodes.ASTORE, 1); m.visitMethodInsn(Opcodes.INVOKESTATIC, "kotlin/coroutines/intrinsics/IntrinsicsKt", "getCOROUTINE_SUSPENDED", "()Ljava/lang/Object;", false); // line of "fun" m.visitVarInsn(Opcodes.ASTORE, 3); m.visitVarInsn(Opcodes.ALOAD, continuationIndex); m.visitFieldInsn(Opcodes.GETFIELD, "ExampleKt$example$1", "label", "I"); final Label dflt = new Label(); final Label state0 = new Label(); final Label state1 = new Label(); m.visitTableSwitchInsn(0, 1, dflt, state0, state1); m.visitLabel(state0); { m.visitVarInsn(Opcodes.ALOAD, 1); m.visitInsn(Opcodes.DUP); m.visitTypeInsn(Opcodes.INSTANCEOF, "kotlin/Result$Failure"); Label label = new Label(); m.visitJumpInsn(Opcodes.IFEQ, label); m.visitTypeInsn(Opcodes.CHECKCAST, "kotlin/Result$Failure"); m.visitFieldInsn(Opcodes.GETFIELD, "kotlin/Result$Failure", "exception", "Ljava/lang/Throwable"); m.visitInsn(Opcodes.ATHROW); m.visitInsn(Opcodes.POP); range1.toInclusive = m.instructions.getLast(); m.visitLabel(label); } // line of "suspendingFunction" m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "", "suspendingFunction", "(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;", false); m.visitInsn(Opcodes.DUP); final Range range2 = new Range(); range2.fromInclusive = m.instructions.getLast(); m.visitVarInsn(Opcodes.ALOAD, 3); final Label continuationLabelAfterLoadedResult = new Label(); m.visitJumpInsn(Opcodes.IF_ACMPNE, continuationLabelAfterLoadedResult); // line of "fun" m.visitVarInsn(Opcodes.ALOAD, 3); m.visitInsn(Opcodes.ARETURN); m.visitLabel(state1); { m.visitVarInsn(Opcodes.ALOAD, 1); m.visitInsn(Opcodes.DUP); m.visitTypeInsn(Opcodes.INSTANCEOF, "kotlin/Result$Failure"); final Label label = new Label(); m.visitJumpInsn(Opcodes.IFEQ, label); m.visitTypeInsn(Opcodes.CHECKCAST, "kotlin/Result$Failure"); m.visitFieldInsn(Opcodes.GETFIELD, "kotlin/Result$Failure", "exception", "Ljava/lang/Throwable"); m.visitInsn(Opcodes.ATHROW); m.visitInsn(Opcodes.POP); m.visitLabel(label); } m.visitVarInsn(Opcodes.ALOAD, 1); range2.toInclusive = m.instructions.getLast(); m.visitLabel(continuationLabelAfterLoadedResult); // line after "suspendingFunction" m.visitInsn(Opcodes.NOP); m.visitInsn(Opcodes.ARETURN); m.visitLabel(dflt); final Range range0 = new Range(); range0.fromInclusive = m.instructions.getLast(); m.visitTypeInsn(Opcodes.NEW, "java/lang/IllegalStateException"); m.visitInsn(Opcodes.DUP); m.visitLdcInsn("call to 'resume' before 'invoke' with coroutine"); m.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/IllegalStateException", "<init>", "(Ljava/lang/String;)V", false); m.visitInsn(Opcodes.ATHROW); range0.toInclusive = m.instructions.getLast(); filter.filter(m, context, output); assertIgnored(range0, range1, range2); }
From source file:org.jacoco.core.internal.analysis.filter.TryWithResourcesEcjFilterTest.java
License:Open Source License
/** * ECJ for//from w ww.j av a 2s . c om * * <pre> * try (r1 = ...; r2 = ...; r3 = ...) { * return ... * } finally { * ... * } * </pre> * * generates * * <pre> * ACONST_NULL * astore primaryExc * ACONST_NULL * astore suppressedExc * * ... * ASTORE r1 * ... * ASTORE r2 * ... * ASTORE r3 * * ... // body * * ALOAD r3 * IFNULL n * ALOAD r3 * INVOKEVIRTUAL close:()V * n: * ALOAD r2 * IFNULL n * ALOAD r2 * INVOKEVIRTUAL close:()V * n: * ALOAD r1 * IFNULL n * ALOAD r1 * INVOKEVIRTUAL close:()V * n: * * ... // finally on normal path * ARETURN * * ASTORE primaryExc * ALOAD r3 * IFNULL n * ALOAD r3 * INVOKEVIRTUAL close:()V * n: * ALOAD primaryExc * ATHROW * * ASTORE suppressedExc * ALOAD primaryExc * IFNONNULL s * ALOAD suppressedExc * ASTORE primaryExc * GOTO e * s: * ALOAD primaryExc * ALOAD suppressedExc * IF_ACMPEQ e * ALOAD primaryExc * ALOAD suppressedExc * INVOKEVIRTUAL java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V * e: * * ALOAD r2 * IFNULL n * ALOAD r2 * INVOKEVIRTUAL close:()V * n: * ALOAD primaryExc * ATHROW * * ASTORE suppressedExc * ALOAD primaryExc * IFNONNULL s * ALOAD suppressedExc * ASTORE primaryExc * GOTO e * s: * ALOAD primaryExc * ALOAD suppressedExc * IF_ACMPEQ e * ALOAD primaryExc * ALOAD suppressedExc * INVOKEVIRTUAL java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V * e: * * ALOAD r1 * IFNULL n * ALOAD r1 * INVOKEVIRTUAL close:()V * n: * ALOAD primaryExc * ATHROW * * ASTORE suppressedExc * ALOAD primaryExc * IFNONNULL s * ALOAD suppressedExc * ASTORE primaryExc * GOTO e * s: * ALOAD primaryExc * ALOAD suppressedExc * IF_ACMPEQ e * ALOAD primaryExc * ALOAD suppressedExc * INVOKEVIRTUAL java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V * e: * * ALOAD primaryExc * ATHROW * * ... // additional handlers for catch blocks and finally on exceptional path * </pre> */ @Test public void ecj_noFlowOut() { final Range range0 = new Range(); final Range range1 = new Range(); final Label handler = new Label(); m.visitTryCatchBlock(handler, handler, handler, null); // primaryExc = null m.visitInsn(Opcodes.ACONST_NULL); m.visitVarInsn(Opcodes.ASTORE, 1); // suppressedExc = null m.visitInsn(Opcodes.ACONST_NULL); m.visitVarInsn(Opcodes.ASTORE, 2); // body m.visitInsn(Opcodes.NOP); { // nextIsEcjClose("r0") final Label label = new Label(); m.visitVarInsn(Opcodes.ALOAD, 5); range0.fromInclusive = m.instructions.getLast(); m.visitJumpInsn(Opcodes.IFNULL, label); m.visitVarInsn(Opcodes.ALOAD, 5); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "Fun$Resource", "close", "()V", false); m.visitLabel(label); } { // nextIsEcjClose("r1") final Label label = new Label(); m.visitVarInsn(Opcodes.ALOAD, 4); m.visitJumpInsn(Opcodes.IFNULL, label); m.visitVarInsn(Opcodes.ALOAD, 4); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "Fun$Resource", "close", "()V", false); m.visitLabel(label); } { // nextIsEcjClose("r2") final Label label = new Label(); m.visitVarInsn(Opcodes.ALOAD, 3); m.visitJumpInsn(Opcodes.IFNULL, label); m.visitVarInsn(Opcodes.ALOAD, 3); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "Fun$Resource", "close", "()V", false); range0.toInclusive = m.instructions.getLast(); m.visitLabel(label); } // finally m.visitInsn(Opcodes.NOP); m.visitInsn(Opcodes.ARETURN); // catch (any primaryExc) m.visitLabel(handler); range1.fromInclusive = m.instructions.getLast(); m.visitVarInsn(Opcodes.ASTORE, 1); { // nextIsEcjCloseAndThrow("r0") m.visitVarInsn(Opcodes.ALOAD, 5); final Label throwLabel = new Label(); m.visitJumpInsn(Opcodes.IFNULL, throwLabel); m.visitVarInsn(Opcodes.ALOAD, 5); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "Fun$Resource", "close", "()V", false); m.visitLabel(throwLabel); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitInsn(Opcodes.ATHROW); } { // nextIsEcjSuppress m.visitVarInsn(Opcodes.ASTORE, 2); m.visitVarInsn(Opcodes.ALOAD, 1); final Label suppressStart = new Label(); m.visitJumpInsn(Opcodes.IFNONNULL, suppressStart); m.visitVarInsn(Opcodes.ALOAD, 2); m.visitVarInsn(Opcodes.ASTORE, 1); final Label suppressEnd = new Label(); m.visitJumpInsn(Opcodes.GOTO, suppressEnd); m.visitLabel(suppressStart); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitVarInsn(Opcodes.ALOAD, 2); m.visitJumpInsn(Opcodes.IF_ACMPEQ, suppressEnd); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitVarInsn(Opcodes.ALOAD, 2); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "addSuppressed", "(Ljava/lang/Throwable;)V", false); m.visitLabel(suppressEnd); } { // nextIsEcjCloseAndThrow("r1") m.visitVarInsn(Opcodes.ALOAD, 4); final Label throwLabel = new Label(); m.visitJumpInsn(Opcodes.IFNULL, throwLabel); m.visitVarInsn(Opcodes.ALOAD, 4); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "Fun$Resource", "close", "()V", false); m.visitLabel(throwLabel); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitInsn(Opcodes.ATHROW); } { // nextIsEcjSuppress m.visitVarInsn(Opcodes.ASTORE, 2); m.visitVarInsn(Opcodes.ALOAD, 1); final Label suppressStart = new Label(); m.visitJumpInsn(Opcodes.IFNONNULL, suppressStart); m.visitVarInsn(Opcodes.ALOAD, 2); m.visitVarInsn(Opcodes.ASTORE, 1); final Label suppressEnd = new Label(); m.visitJumpInsn(Opcodes.GOTO, suppressEnd); m.visitLabel(suppressStart); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitVarInsn(Opcodes.ALOAD, 2); m.visitJumpInsn(Opcodes.IF_ACMPEQ, suppressEnd); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitVarInsn(Opcodes.ALOAD, 2); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "addSuppressed", "(Ljava/lang/Throwable;)V", false); m.visitLabel(suppressEnd); } { // nextIsEcjCloseAndThrow("r2") m.visitVarInsn(Opcodes.ALOAD, 3); final Label throwLabel = new Label(); m.visitJumpInsn(Opcodes.IFNULL, throwLabel); m.visitVarInsn(Opcodes.ALOAD, 3); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "Fun$Resource", "close", "()V", false); m.visitLabel(throwLabel); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitInsn(Opcodes.ATHROW); } { // nextIsEcjSuppress m.visitVarInsn(Opcodes.ASTORE, 2); m.visitVarInsn(Opcodes.ALOAD, 1); final Label suppressStart = new Label(); m.visitJumpInsn(Opcodes.IFNONNULL, suppressStart); m.visitVarInsn(Opcodes.ALOAD, 2); m.visitVarInsn(Opcodes.ASTORE, 1); final Label suppressEnd = new Label(); m.visitJumpInsn(Opcodes.GOTO, suppressEnd); m.visitLabel(suppressStart); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitVarInsn(Opcodes.ALOAD, 2); m.visitJumpInsn(Opcodes.IF_ACMPEQ, suppressEnd); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitVarInsn(Opcodes.ALOAD, 2); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "addSuppressed", "(Ljava/lang/Throwable;)V", false); m.visitLabel(suppressEnd); } // throw primaryExc m.visitVarInsn(Opcodes.ALOAD, 1); m.visitInsn(Opcodes.ATHROW); range1.toInclusive = m.instructions.getLast(); // additional handlers m.visitInsn(Opcodes.NOP); filter.filter(m, context, output); assertIgnored(range0, range1); }
From source file:org.jacoco.core.internal.analysis.filter.TryWithResourcesJavacFilterTest.java
License:Open Source License
/** * javac 9 for//from w w w.j a va 2 s .c o m * * <pre> * try (r0 = open(...); r1 = new ...) { * return ... * } finally { * ... * } * </pre> * * generates * * <pre> * ... * ASTORE r0 * ACONST_NULL * ASTORE primaryExc0 * * ... * ASTORE r1 * ACONST_NULL * ASTORE primaryExc1 * * ... // body * * ALOAD primaryExc1 * ALOAD r1 * INVOKESTATIC $closeResource:(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V * * ALOAD r0 * IFNULL n * ALOAD primaryExc0 * ALOAD r0 * INVOKESTATIC $closeResource:(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V * n: * * ... // finally on normal path * ARETURN * * ASTORE t * ALOAD t * ASTORE primaryExc1 * ALOAD t * ATHROW * * ASTORE t * ALOAD primaryExc1 * ALOAD r1 * INVOKESTATIC $closeResource:(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V * ALOAD t * ATHROW * * ASTORE t * ALOAD t * ASTORE primaryExc0 * ALOAD t * ATHROW * * ASTORE t * ALOAD r0 * IFNULL n * ALOAD primaryExc0 * ALOAD r0 * INVOKESTATIC $closeResource:(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V * n: * ALOAD t * ATHROW * * ... // additional handlers for catch blocks and finally on exceptional path * </pre> */ @Test public void javac9() { final Range range0 = new Range(); final Range range1 = new Range(); final Range range2 = new Range(); final Range range3 = new Range(); final Label handler1 = new Label(); m.visitTryCatchBlock(handler1, handler1, handler1, "java/lang/Throwable"); final Label handler2 = new Label(); m.visitTryCatchBlock(handler2, handler2, handler2, "java/lang/Throwable"); // r0 = open(...) m.visitVarInsn(Opcodes.ASTORE, 1); // primaryExc0 = null m.visitInsn(Opcodes.ACONST_NULL); m.visitVarInsn(Opcodes.ASTORE, 2); // r1 = new .. m.visitVarInsn(Opcodes.ASTORE, 3); // primaryExc1 = null m.visitInsn(Opcodes.ACONST_NULL); m.visitVarInsn(Opcodes.ASTORE, 4); // body m.visitInsn(Opcodes.NOP); m.visitInsn(Opcodes.ACONST_NULL); m.visitVarInsn(Opcodes.ASTORE, 5); // $closeResource(primaryExc1, r1) m.visitVarInsn(Opcodes.ALOAD, 4); range0.fromInclusive = m.instructions.getLast(); m.visitVarInsn(Opcodes.ALOAD, 3); m.visitMethodInsn(Opcodes.INVOKESTATIC, "Fun", "$closeResource", "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V", false); range0.toInclusive = m.instructions.getLast(); // if (r0 != null) m.visitVarInsn(Opcodes.ALOAD, 1); range2.fromInclusive = m.instructions.getLast(); final Label l11 = new Label(); m.visitJumpInsn(Opcodes.IFNULL, l11); // $closeResource(primaryExc0, r0) m.visitVarInsn(Opcodes.ALOAD, 2); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitMethodInsn(Opcodes.INVOKESTATIC, "Fun", "$closeResource", "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V", false); range2.toInclusive = m.instructions.getLast(); m.visitLabel(l11); // finally m.visitInsn(Opcodes.NOP); m.visitVarInsn(Opcodes.ALOAD, 5); m.visitInsn(Opcodes.ARETURN); // catch (Throwable t) m.visitLabel(handler1); range1.fromInclusive = m.instructions.getLast(); m.visitVarInsn(Opcodes.ASTORE, 5); // primaryExc1 = t m.visitVarInsn(Opcodes.ALOAD, 5); m.visitVarInsn(Opcodes.ASTORE, 4); // throw t m.visitVarInsn(Opcodes.ALOAD, 5); m.visitInsn(Opcodes.ATHROW); // catch (any t) m.visitVarInsn(Opcodes.ASTORE, 6); // $closeResource(primaryExc1, r1) m.visitVarInsn(Opcodes.ALOAD, 4); m.visitVarInsn(Opcodes.ALOAD, 3); m.visitMethodInsn(Opcodes.INVOKESTATIC, "Fun", "$closeResource", "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V", false); m.visitVarInsn(Opcodes.ALOAD, 6); m.visitInsn(Opcodes.ATHROW); range1.toInclusive = m.instructions.getLast(); // catch (Throwable t) m.visitLabel(handler2); range3.fromInclusive = m.instructions.getLast(); m.visitVarInsn(Opcodes.ASTORE, 3); // primaryExc0 = t m.visitVarInsn(Opcodes.ALOAD, 3); m.visitVarInsn(Opcodes.ASTORE, 2); // throw t m.visitVarInsn(Opcodes.ALOAD, 3); m.visitInsn(Opcodes.ATHROW); // catch (any t) m.visitVarInsn(Opcodes.ASTORE, 7); // if (r0 != null) m.visitVarInsn(Opcodes.ALOAD, 1); final Label l14 = new Label(); m.visitJumpInsn(Opcodes.IFNULL, l14); // $closeResource(primaryExc0, r0) m.visitVarInsn(Opcodes.ALOAD, 2); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitMethodInsn(Opcodes.INVOKESTATIC, "Fun", "$closeResource", "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V", false); m.visitLabel(l14); // throw t m.visitVarInsn(Opcodes.ALOAD, 7); m.visitInsn(Opcodes.ATHROW); range3.toInclusive = m.instructions.getLast(); m.visitVarInsn(Opcodes.ASTORE, 8); // finally m.visitInsn(Opcodes.NOP); m.visitVarInsn(Opcodes.ALOAD, 8); m.visitInsn(Opcodes.ATHROW); filter.filter(m, context, output); assertIgnored(range0, range1, range2, range3); }