Example usage for org.objectweb.asm Opcodes DUP

List of usage examples for org.objectweb.asm Opcodes DUP

Introduction

In this page you can find the example usage for org.objectweb.asm Opcodes DUP.

Prototype

int DUP

To view the source code for org.objectweb.asm Opcodes DUP.

Click Source Link

Usage

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);
}