List of usage examples for org.objectweb.asm Opcodes DUP
int DUP
To view the source code for org.objectweb.asm Opcodes DUP.
Click Source Link
From source file:org.gradle.api.internal.model.NamedObjectInstantiator.java
License:Apache License
private ClassGeneratingLoader loaderFor(Class<?> publicClass) { ///* ww w . ja v a 2s . co m*/ // 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.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();/* ww w. ja 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.gradle.model.internal.manage.schema.extract.ManagedProxyClassGenerator.java
License:Apache License
private void writeConfigureMethod(ClassVisitor visitor, Type generatedType, ModelProperty<?> property, boolean writable) { if (!writable && property.getSchema() instanceof CompositeSchema) { // Adds a void $propName(Closure<?> cl) method that delegates to model state MethodVisitor methodVisitor = declareMethod(visitor, property.getName(), Type.getMethodDescriptor(Type.VOID_TYPE, CLOSURE_TYPE), null); putNodeStateFieldValueOnStack(methodVisitor, generatedType); putConstantOnStack(methodVisitor, property.getName()); putFirstMethodArgumentOnStack(methodVisitor); methodVisitor.visitMethodInsn(INVOKEINTERFACE, MODEL_ELEMENT_STATE_TYPE_INTERNAL_NAME, "apply", STATE_APPLY_METHOD_DESCRIPTOR, true); finishVisitingMethod(methodVisitor); return;/*from w ww . ja va 2s . c om*/ } if (!writable && property.getSchema() instanceof UnmanagedImplStructSchema) { UnmanagedImplStructSchema<?> structSchema = (UnmanagedImplStructSchema<?>) property.getSchema(); if (!structSchema.isAnnotated()) { return; } // Adds a void $propName(Closure<?> cl) method that executes the closure MethodVisitor methodVisitor = declareMethod(visitor, property.getName(), Type.getMethodDescriptor(Type.VOID_TYPE, CLOSURE_TYPE), null); putThisOnStack(methodVisitor); methodVisitor.visitMethodInsn(INVOKEVIRTUAL, generatedType.getInternalName(), property.getGetter().getName(), Type.getMethodDescriptor(Type.getType(property.getType().getConcreteClass())), false); putFirstMethodArgumentOnStack(methodVisitor); methodVisitor.visitMethodInsn(INVOKESTATIC, Type.getInternalName(ClosureBackedAction.class), "execute", Type.getMethodDescriptor(Type.VOID_TYPE, OBJECT_TYPE, CLOSURE_TYPE), false); finishVisitingMethod(methodVisitor); return; } // Adds a void $propName(Closure<?> cl) method that throws MME, to avoid attempts to convert closure to something else MethodVisitor methodVisitor = declareMethod(visitor, property.getName(), Type.getMethodDescriptor(Type.VOID_TYPE, CLOSURE_TYPE), null); putThisOnStack(methodVisitor); putConstantOnStack(methodVisitor, property.getName()); methodVisitor.visitInsn(Opcodes.ICONST_1); methodVisitor.visitTypeInsn(Opcodes.ANEWARRAY, OBJECT_TYPE.getInternalName()); methodVisitor.visitInsn(Opcodes.DUP); methodVisitor.visitInsn(Opcodes.ICONST_0); putFirstMethodArgumentOnStack(methodVisitor); methodVisitor.visitInsn(Opcodes.AASTORE); methodVisitor.visitMethodInsn(INVOKEVIRTUAL, generatedType.getInternalName(), "methodMissing", METHOD_MISSING_METHOD_DESCRIPTOR, false); finishVisitingMethod(methodVisitor); }
From source file:org.greencheek.gc.memusage.agent.AddStaticAtomicLongInitializer.java
License:Apache License
@Override public void visitCode() { super.visitCode(); // build my static initializer by calling // visitFieldInsn(int opcode, String owner, String name, String desc) // or the//from ww w . j av a 2s . co m for (MethodInfo method : annotatedMeasurableMethods) { System.out.println("Adding static initialiser for: " + method.getAnnotatedClassName() + "." + method.getFieldName()); mv.visitTypeInsn(Opcodes.NEW, "java/util/concurrent/atomic/AtomicLong"); mv.visitInsn(Opcodes.DUP); mv.visitInsn(Opcodes.LCONST_0); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/concurrent/atomic/AtomicLong", "<init>", "(J)V"); mv.visitFieldInsn(Opcodes.PUTSTATIC, method.getAnnotatedClassName(), method.getFieldName(), "Ljava/util/concurrent/atomic/AtomicLong;"); } System.out.println(); }
From source file:org.hua.ast.visitors.BytecodeGeneratorASTVisitor.java
/** * Assumes top of stack contains two strings *//* w w w .j a va 2s. c om*/ private void handleStringOperator(ASTNode node, Operator op) throws ASTVisitorException { if (op.equals(Operator.PLUS)) { mn.instructions.add(new TypeInsnNode(Opcodes.NEW, "java/lang/StringBuilder")); mn.instructions.add(new InsnNode(Opcodes.DUP)); mn.instructions.add( new MethodInsnNode(Opcodes.INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V", false)); mn.instructions.add(new InsnNode(Opcodes.SWAP)); mn.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false)); mn.instructions.add(new InsnNode(Opcodes.SWAP)); mn.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false)); mn.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false)); } else if (op.isRelational()) { LabelNode trueLabelNode = new LabelNode(); switch (op) { case EQUAL: mn.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false)); mn.instructions.add(new JumpInsnNode(Opcodes.IFNE, trueLabelNode)); break; case NOT_EQUAL: mn.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false)); mn.instructions.add(new JumpInsnNode(Opcodes.IFEQ, trueLabelNode)); break; default: ASTUtils.error(node, "Operator not supported on strings"); break; } mn.instructions.add(new InsnNode(Opcodes.ICONST_0)); LabelNode endLabelNode = new LabelNode(); mn.instructions.add(new JumpInsnNode(Opcodes.GOTO, endLabelNode)); mn.instructions.add(trueLabelNode); mn.instructions.add(new InsnNode(Opcodes.ICONST_1)); mn.instructions.add(endLabelNode); } else { ASTUtils.error(node, "Operator not recognized"); } }
From source file:org.hua.ast.visitors.BytecodeGeneratorASTVisitor.java
@Override public void visit(NewIdentifierExpression node) throws ASTVisitorException { if (node.getExpressions() != null) { node.getExpressions().accept(this); }/*from w w w .j a v a 2 s . c o m*/ mn.instructions.add(new TypeInsnNode(Opcodes.NEW, node.getIdentifier())); mn.instructions.add(new InsnNode(Opcodes.DUP)); //@TODO: fix calling parameters if (node.getExpressions() != null) { if (node.getExpressions().getExpressions().isEmpty() && Registry.getInstance() .classExists(Type.getType("Lorg/hua/customclasses/" + node.getIdentifier() + ";"))) { System.out.println("222222222222222222222222222222222222222222 " + ASTUtils.getSafeType(node).getInternalName()); mn.instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, ASTUtils.getSafeType(node).getInternalName(), "<init>", "()V", false)); } else //get parameter types and then give that as the signature if (Registry.getInstance() .classExists(Type.getType("Lorg/hua/customclasses/" + node.getIdentifier() + ";"))) { SymTable<SymTableEntry> existingClass = Registry.getInstance() .getExistingClass(Type.getType("Lorg/hua/customclasses/" + node.getIdentifier() + ";")); SymTableEntry lookup = existingClass.lookup(node.getIdentifier()); if (lookup != null) { Type[] types = lookup.getParametersTypes(); mn.instructions.add( new MethodInsnNode(Opcodes.INVOKEVIRTUAL, ASTUtils.getSafeType(node).getInternalName(), node.getIdentifier(), Type.getMethodDescriptor(Type.VOID_TYPE, types), false)); } else { ASTUtils.error(node, "Constructor not found"); } } else { ASTUtils.error(node, "Problem with called constructor"); } } LocalIndexPool pool = ASTUtils.getSafeLocalIndexPool(fd); int localIndex = pool.getLocalIndex(); System.out.println("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ " + localIndex); mn.instructions.add(new VarInsnNode(Opcodes.ASTORE, localIndex)); }
From source file:org.iobserve.mobile.instrument.bytecode.SensorBytecodeInstrumenter.java
License:Apache License
/** * {@inheritDoc}//from w w w. ja v a2 s . c o m */ @Override public void onMethodExit(final int opcode, final String owner, final String name, final String desc, final AdviceAdapter parent, final MethodVisitor mv) { if (opcode == Opcodes.ATHROW) { mv.visitInsn(Opcodes.DUP); mv.visitVarInsn(Opcodes.LLOAD, index); mv.visitMethodInsn(Opcodes.INVOKESTATIC, ANDROIDAGENT_TYPE.getInternalName(), exitBodyErrorMethod.getName(), exitBodyErrorType.getDescriptor(), false); } else { mv.visitVarInsn(Opcodes.LLOAD, index); mv.visitMethodInsn(Opcodes.INVOKESTATIC, ANDROIDAGENT_TYPE.getInternalName(), exitBodyMethod.getName(), exitBodyType.getDescriptor(), false); } }
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 ww. j a v a 2 s. c o m*/ 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 ww w . ja va 2 s.c om * 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 w w w .j a v a2s . c o m*/ * 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); }