Example usage for org.objectweb.asm.tree AbstractInsnNode INVOKE_DYNAMIC_INSN

List of usage examples for org.objectweb.asm.tree AbstractInsnNode INVOKE_DYNAMIC_INSN

Introduction

In this page you can find the example usage for org.objectweb.asm.tree AbstractInsnNode INVOKE_DYNAMIC_INSN.

Prototype

int INVOKE_DYNAMIC_INSN

To view the source code for org.objectweb.asm.tree AbstractInsnNode INVOKE_DYNAMIC_INSN.

Click Source Link

Document

The type of InvokeDynamicInsnNode instructions.

Usage

From source file:co.paralleluniverse.fibers.instrument.InstrumentMethod.java

License:Open Source License

public boolean collectCodeBlocks() {
    final int numIns = mn.instructions.size();

    codeBlocks[0] = FrameInfo.FIRST;//from w ww. j  a va2s .c o m
    for (int i = 0; i < numIns; i++) {
        final Frame f = frames[i];
        if (f != null) { // reachable ?
            AbstractInsnNode in = mn.instructions.get(i);
            if (in.getType() == AbstractInsnNode.METHOD_INSN
                    || in.getType() == AbstractInsnNode.INVOKE_DYNAMIC_INSN) {
                Boolean susp = true;
                if (in.getType() == AbstractInsnNode.METHOD_INSN) {
                    final MethodInsnNode min = (MethodInsnNode) in;
                    int opcode = min.getOpcode();

                    if (isReflectInvocation(min.owner, min.name))
                        db.log(LogLevel.DEBUG,
                                "Reflective method call at instruction %d is assumed suspendable", i);
                    else if (isMethodHandleInvocation(min.owner, min.name))
                        db.log(LogLevel.DEBUG,
                                "MethodHandle invocation at instruction %d is assumed suspendable", i);
                    else if (isInvocationHandlerInvocation(min.owner, min.name))
                        db.log(LogLevel.DEBUG,
                                "InvocationHandler invocation at instruction %d is assumed suspendable", i);
                    else {
                        SuspendableType st = db.isMethodSuspendable(min.owner, min.name, min.desc, opcode);
                        if (st == SuspendableType.NON_SUSPENDABLE)
                            susp = false;
                        else if (st == null) {
                            db.log(LogLevel.WARNING,
                                    "Method not found in class - assuming suspendable: %s#%s%s (at%s#%s)",
                                    min.owner, min.name, min.desc, className, mn.name);
                            susp = true;
                        } else if (susp)
                            db.log(LogLevel.DEBUG, "Method call at instruction %d to %s#%s%s is suspendable", i,
                                    min.owner, min.name, min.desc);
                        if (st == SuspendableType.SUSPENDABLE_SUPER)
                            this.hasSuspendableSuperCalls = true;
                    }
                } else { // invoke dynamic
                    final InvokeDynamicInsnNode idin = (InvokeDynamicInsnNode) in;
                    if (idin.bsm.getOwner().equals("java/lang/invoke/LambdaMetafactory")) { // lambda
                        db.log(LogLevel.DEBUG, "Lambda at instruction %d", i);
                        susp = false;
                    } else
                        db.log(LogLevel.DEBUG,
                                "InvokeDynamic Method call at instruction %d to is assumed suspendable", i);
                }

                if (susp) {
                    FrameInfo fi = addCodeBlock(f, i);
                    splitTryCatch(fi);
                } else {
                    if (in.getType() == AbstractInsnNode.METHOD_INSN) {// not invokedynamic
                        final MethodInsnNode min = (MethodInsnNode) in;
                        db.log(LogLevel.DEBUG, "Method call at instruction %d to %s#%s%s is not suspendable", i,
                                min.owner, min.name, min.desc);
                        int blockingId = isBlockingCall(min);
                        if (blockingId >= 0 && !isAllowedToBlock(className, mn.name)) {
                            int mask = 1 << blockingId;
                            if (!db.isAllowBlocking()) {
                                throw new UnableToInstrumentException(
                                        "blocking call to " + min.owner + "#" + min.name + min.desc, className,
                                        mn.name, mn.desc);
                            } else if ((warnedAboutBlocking & mask) == 0) {
                                warnedAboutBlocking |= mask;
                                db.log(LogLevel.WARNING, "Method %s#%s%s contains potentially blocking call to "
                                        + min.owner + "#" + min.name + min.desc, className, mn.name, mn.desc);
                            }
                        }
                    }
                }
            }
        }
    }
    addCodeBlock(null, numIns);

    return numCodeBlocks > 1;
}

From source file:co.paralleluniverse.fibers.instrument.LabelSuspendableCallSitesClassVisitor.java

License:Open Source License

@Override
public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature,
        final String[] exceptions) {
    if ((access & Opcodes.ACC_NATIVE) == 0 && !isYieldMethod(className, name)) {
        // Bytecode-level AST of a method, being a MethodVisitor itself can be filled through delegation from another visitor
        // Analyze, fill and enqueue method ASTs
        final MethodVisitor outMV = super.visitMethod(access, name, desc, signature, exceptions);

        return new MethodVisitor(ASMAPI, outMV) {
            private int currLineNumber = -1;

            @Override/*from  ww  w  .  j  av  a  2 s  .  c om*/
            public void visitLineNumber(int i, Label label) {
                currLineNumber = i;
                super.visitLineNumber(i, label);
            }

            @Override
            public void visitMethodInsn(int opcode, String owner, String name, String desc,
                    boolean isInterface) {
                final int type = AbstractInsnNode.METHOD_INSN;
                if (InstrumentMethod.isSuspendableCall(db, type, opcode, owner, name, desc)) {
                    final Label l = new Label();
                    super.visitLabel(l);
                    super.visitLineNumber(currLineNumber, l); // Force label
                }
                super.visitMethodInsn(opcode, owner, name, desc, isInterface);
            }

            @Override
            public void visitInvokeDynamicInsn(String name, String desc, Handle handle, Object... objects) {
                final int type = AbstractInsnNode.INVOKE_DYNAMIC_INSN;
                final int opcode = Opcodes.INVOKEDYNAMIC;
                if (InstrumentMethod.isSuspendableCall(db, type, opcode, handle.getOwner(), name, desc)) {
                    final Label l = new Label();
                    super.visitLabel(l);
                    super.visitLineNumber(currLineNumber, l); // Force label
                }
                super.visitInvokeDynamicInsn(name, desc, handle, objects);
            }
        };
    }
    return super.visitMethod(access, name, desc, signature, exceptions);
}

From source file:co.paralleluniverse.fibers.instrument.SuspOffsetsAfterInstrClassVisitor.java

License:Open Source License

@Override
public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature,
        final String[] exceptions) {
    if ((access & Opcodes.ACC_NATIVE) == 0 && !isYieldMethod(className, name)) {
        // Bytecode-level AST of a method, being a MethodVisitor itself can be filled through delegation from another visitor
        final MethodNode mn = new MethodNode(access, name, desc, signature, exceptions);

        // Analyze, fill and enqueue method ASTs
        final MethodVisitor outMV = super.visitMethod(access, name, desc, signature, exceptions);

        return new MethodVisitor(ASMAPI, outMV) {
            private Label currLabel = null;
            private int prevOffset = -1;
            private boolean instrumented;
            private boolean optimized = false;
            private int methodStart = -1, methodEnd = -1;

            private List<Integer> suspOffsetsAfterInstrL = new ArrayList<>();
            private int[] suspCallSites = new int[0];

            @Override/*from   w ww  .  j  a v  a  2  s.co m*/
            public AnnotationVisitor visitAnnotation(final String adesc, boolean visible) {
                if (Classes.INSTRUMENTED_DESC.equals(adesc)) {
                    instrumented = true;

                    return new AnnotationVisitor(ASMAPI) { // Only collect info
                        @Override
                        public void visit(String name, Object value) {
                            if (Instrumented.FIELD_NAME_METHOD_START.equals(name))
                                methodStart = (Integer) value;
                            else if (Instrumented.FIELD_NAME_METHOD_END.equals(name))
                                methodEnd = (Integer) value;
                            else if (Instrumented.FIELD_NAME_METHOD_OPTIMIZED.equals(name))
                                optimized = (Boolean) value;
                            else if (Instrumented.FIELD_NAME_SUSPENDABLE_CALL_SITES.equals(name))
                                suspCallSites = (int[]) value;
                            else //noinspection StatementWithEmptyBody
                            if (Instrumented.FIELD_NAME_SUSPENDABLE_CALL_SITES_OFFSETS_AFTER_INSTR.equals(name))
                                ; // Ignore, we're filling it
                            else
                                throw new RuntimeException("Unexpected `@Instrumented` field: " + name);
                        }
                    };
                }

                return super.visitAnnotation(adesc, visible);
            }

            @Override
            public void visitLocalVariable(String name, String desc, String sig, Label lStart, Label lEnd,
                    int slot) {
                super.visitLocalVariable(name, desc, sig, lStart, lEnd, slot);
            }

            @Override
            public void visitLabel(Label label) {
                if (instrumented) {
                    currLabel = label;
                }

                super.visitLabel(label);
            }

            @Override
            public void visitMethodInsn(int opcode, String owner, String name, String desc,
                    boolean isInterface) {
                if (instrumented) {
                    final int type = AbstractInsnNode.METHOD_INSN;
                    if (InstrumentMethod.isSuspendableCall(db, type, opcode, owner, name, desc)
                            && !Classes.STACK_NAME.equals(owner) && // postRestore
                    currLabel != null && currLabel.info instanceof Integer)
                        addLine();
                }

                super.visitMethodInsn(opcode, owner, name, desc, isInterface);
            }

            @Override
            public void visitInvokeDynamicInsn(String name, String desc, Handle handle, Object... objects) {
                if (instrumented) {
                    final int type = AbstractInsnNode.INVOKE_DYNAMIC_INSN;
                    final int opcode = Opcodes.INVOKEDYNAMIC;
                    if (InstrumentMethod.isSuspendableCall(db, type, opcode, handle.getOwner(), name, desc)
                            && !Classes.STACK_NAME.equals(handle.getOwner()) && // postRestore
                    currLabel != null && currLabel.info instanceof Integer)
                        addLine();
                }
                super.visitInvokeDynamicInsn(name, desc, handle, objects);
            }

            @Override
            public void visitEnd() {
                if (instrumented)
                    InstrumentMethod.emitInstrumentedAnn(db, outMV, mn, sourceName, className, optimized,
                            methodStart, methodEnd, suspCallSites, toIntArray(suspOffsetsAfterInstrL));

                super.visitEnd();
            }

            private void addLine() {
                final int currOffset = (Integer) currLabel.info;
                if (currOffset > prevOffset) {
                    suspOffsetsAfterInstrL.add(currOffset);
                    prevOffset = currOffset;
                }
            }
        };
    }

    return super.visitMethod(access, name, desc, signature, exceptions);
}

From source file:cz.vutbr.fit.xhriba01.bc.lib.AbstractNodeVisitor.java

License:Open Source License

/**
 * This method detects what type of instruction the NodeInstruction is
 * representing and calls appropriate before/visit/after methods.
 * Subclasses could rather override methods specific for particular
 * instruction type./* w ww.ja v  a2 s  .  c o  m*/
 * 
 * @param nodeInstruction the instruction node
 */
public void visitNodeInstruction(NodeInstruction nodeInstruction) {
    AbstractInsnNode asmInsn = nodeInstruction.getAsmInsnNode();
    switch (asmInsn.getType()) {
    case AbstractInsnNode.LINE:
        visitLineNumberNode((LineNumberNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.LABEL:
        visitLabelNode((LabelNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.FIELD_INSN:
        visitFieldInsn((FieldInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.IINC_INSN:
        visitIincInsn((IincInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.INSN:
        visitInsn((InsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.INT_INSN:
        visitIntInsn((IntInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.INVOKE_DYNAMIC_INSN:
        visitInvokeDynamicInsn((InvokeDynamicInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.JUMP_INSN:
        visitJumpInsn((JumpInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.LDC_INSN:
        visitLdcInsn((LdcInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.LOOKUPSWITCH_INSN:
        visitLookupSwitchInsn((LookupSwitchInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.METHOD_INSN:
        visitMethodInsn((MethodInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.MULTIANEWARRAY_INSN:
        visitMultiANewArrayInsn((MultiANewArrayInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.TABLESWITCH_INSN:
        visitTableSwitchInsn((TableSwitchInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.TYPE_INSN:
        visitTypeInsn((TypeInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.VAR_INSN:
        visitVarInsn((VarInsnNode) asmInsn, nodeInstruction);
        break;
    default:
        // shouldn't happen
        break;
    }
}

From source file:cz.vutbr.fit.xhriba01.bc.lib.AbstractNodeVisitor.java

License:Open Source License

public void afterVisitNodeInstruction(NodeInstruction nodeInstruction) {

    AbstractInsnNode asmInsn = nodeInstruction.getAsmInsnNode();

    switch (asmInsn.getType()) {
    case AbstractInsnNode.LINE:
        afterVisitLineNumberNode((LineNumberNode) asmInsn, nodeInstruction);
        break;/* w w w .  j  av  a  2s.c  o  m*/
    case AbstractInsnNode.LABEL:
        afterVisitLabelNode((LabelNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.FIELD_INSN:
        afterVisitFieldInsn((FieldInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.IINC_INSN:
        afterVisitIincInsn((IincInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.INSN:
        afterVisitInsn((InsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.INT_INSN:
        afterVisitIntInsn((IntInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.INVOKE_DYNAMIC_INSN:
        afterVisitInvokeDynamicInsn((InvokeDynamicInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.JUMP_INSN:
        afterVisitJumpInsn((JumpInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.LDC_INSN:
        afterVisitLdcInsn((LdcInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.LOOKUPSWITCH_INSN:
        afterVisitLookupSwitchInsn((LookupSwitchInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.METHOD_INSN:
        afterVisitMethodInsn((MethodInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.MULTIANEWARRAY_INSN:
        afterVisitMultiANewArrayInsn((MultiANewArrayInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.TABLESWITCH_INSN:
        afterVisitTableSwitchInsn((TableSwitchInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.TYPE_INSN:
        afterVisitTypeInsn((TypeInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.VAR_INSN:
        afterVisitVarInsn((VarInsnNode) asmInsn, nodeInstruction);
        break;
    default:
        // shouldn't happen
        break;
    }

}

From source file:de.codesourcery.asm.util.Disassembler.java

License:Apache License

private static String disassemble(AbstractInsnNode node, MethodNode method) {
    final int opCode = node.getOpcode();
    String mnemonic = Printer.OPCODES[opCode];

    switch (node.getType()) {
    case AbstractInsnNode.FIELD_INSN: // GETSTATIC, PUTSTATIC, GETFIELD , PUTFIELD
        FieldInsnNode tmp = (FieldInsnNode) node;
        mnemonic += " " + (tmp.owner + "#" + tmp.name);
        break;/*ww w .  j  a  v a  2  s.  c  o  m*/
    case AbstractInsnNode.IINC_INSN: // IINC
        IincInsnNode tmp2 = (IincInsnNode) node;
        mnemonic += " " + (tmp2.var + " , " + tmp2.incr);
        break;
    case AbstractInsnNode.INSN: // regular opcodes
        break;
    case AbstractInsnNode.INT_INSN: // BIPUSH, SIPUSH or NEWARRAY
        IntInsnNode tmp3 = (IntInsnNode) node;
        mnemonic += " " + (tmp3.operand);
        break;
    case AbstractInsnNode.INVOKE_DYNAMIC_INSN: // INVOKEDYNAMIC
        break;
    case AbstractInsnNode.JUMP_INSN: // IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE,IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL
        JumpInsnNode tmp4 = (JumpInsnNode) node;
        int index = method.instructions.indexOf(tmp4.label);
        while (method.instructions.get(index).getOpcode() == -1) {
            index++;
        }
        mnemonic += " " + index;
        break;
    case AbstractInsnNode.LDC_INSN: // load constant
        LdcInsnNode tmp5 = (LdcInsnNode) node;
        Class<?> clazz = tmp5.cst.getClass();
        if (clazz == String.class) {
            mnemonic += " \"" + tmp5.cst + "\"";
        } else if (clazz == org.objectweb.asm.Type.class) {
            org.objectweb.asm.Type type = (org.objectweb.asm.Type) tmp5.cst;
            mnemonic += " (a " + type.getClassName() + ")";
        } else {
            mnemonic += " " + tmp5.cst + " (" + tmp5.cst.getClass().getName() + ")";
        }
        break;
    case AbstractInsnNode.LOOKUPSWITCH_INSN: // LOOKUPSWITCH
        break;
    case AbstractInsnNode.METHOD_INSN: // INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC , INVOKEINTERFACE
        MethodInsnNode tmp6 = (MethodInsnNode) node;
        mnemonic += " " + (tmp6.owner + "#" + tmp6.name + "()");
        break;
    case AbstractInsnNode.MULTIANEWARRAY_INSN: // MULTIANEWARRAY
        break;
    case AbstractInsnNode.TABLESWITCH_INSN: // TABLESWITCH
        break;
    case AbstractInsnNode.TYPE_INSN: // NEW, ANEWARRAY, CHECKCAST , INSTANCEOF
        TypeInsnNode tmp8 = (TypeInsnNode) node;
        mnemonic += " " + tmp8.desc;
        break;
    case AbstractInsnNode.VAR_INSN: // ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE , RET
        VarInsnNode tmp7 = (VarInsnNode) node;
        mnemonic += "_" + tmp7.var;
        break;
    // -- VIRTUAL --
    case AbstractInsnNode.FRAME: /* VIRTUAL */
    case AbstractInsnNode.LABEL: /* VIRTUAL */
    case AbstractInsnNode.LINE: /* VIRTUAL */
    default:
        throw new RuntimeException("Internal error, unhandled node type: " + node);
    }
    return mnemonic;
}

From source file:org.lambdamatic.analyzer.ast.LambdaExpressionReader.java

License:Open Source License

/**
 * Reads the bytecode from the given {@link InsnCursor}'s <strong>current position</strong>, until
 * there is no further instruction to proceed. It is the responsability of the caller to set the
 * cursor position.//from  w  ww.j a v  a 2s .c o  m
 * 
 * @param insnCursor the instruction cursor used to read the bytecode.
 * @param expressionStack the expression stack to put on or pop from.
 * @param localVariables the local variables
 * @return a {@link List} of {@link Statement} containing the {@link Statement}
 */
private List<Statement> readStatements(final InsnCursor insnCursor, final Stack<Expression> expressionStack,
        final List<CapturedArgument> capturedArguments, final LocalVariables localVariables) {
    final List<Statement> statements = new ArrayList<>();
    while (insnCursor.hasCurrent()) {
        final AbstractInsnNode currentInstruction = insnCursor.getCurrent();
        switch (currentInstruction.getType()) {
        case AbstractInsnNode.VAR_INSN:
            final VarInsnNode varInstruction = (VarInsnNode) currentInstruction;
            switch (currentInstruction.getOpcode()) {
            // load a reference onto the stack from a local variable
            case Opcodes.ALOAD:
            case Opcodes.ILOAD:
                // load an int value from a local variable
                // Note: The 'var' operand is the index of a local variable
                // all captured arguments come before the local variable in the method signature,
                // which means that the local variables table is empty on the first slots which are
                // "allocated"
                // for the captured arguments.
                if (varInstruction.var < capturedArguments.size()) {
                    // if the variable index matches a captured argument
                    // note: not using actual captured argument but rather, use a _reference_ to it.
                    final Object capturedArgumentValue = capturedArguments.get(varInstruction.var).getValue();
                    final Class<?> capturedArgumentValueType = capturedArgumentValue != null
                            ? capturedArgumentValue.getClass()
                            : Object.class;
                    final CapturedArgumentRef capturedArgumentRef = new CapturedArgumentRef(varInstruction.var,
                            capturedArgumentValueType);
                    expressionStack.add(capturedArgumentRef);
                } else {
                    // the variable index matches a local variable
                    final LocalVariableNode var = localVariables.load(varInstruction.var);
                    expressionStack.add(new LocalVariable(var.index, var.name, readSignature(var.desc)));
                }
                break;
            case Opcodes.ASTORE:
                // store a reference into a local variable
                localVariables.store(varInstruction.var);
                break;
            default:
                throw new AnalyzeException(
                        "Unexpected Variable instruction code: " + varInstruction.getOpcode());
            }
            break;
        case AbstractInsnNode.LDC_INSN:
            // let's move this instruction on top of the stack until it
            // is used as an argument during a method call
            final LdcInsnNode ldcInsnNode = (LdcInsnNode) currentInstruction;
            final Expression constant = ExpressionFactory.getExpression(ldcInsnNode.cst);
            LOGGER.trace("Stacking constant {}", constant);
            expressionStack.add(constant);
            break;
        case AbstractInsnNode.FIELD_INSN:
            final FieldInsnNode fieldInsnNode = (FieldInsnNode) currentInstruction;
            switch (fieldInsnNode.getOpcode()) {
            case Opcodes.GETSTATIC:
                final Type ownerType = Type.getType(fieldInsnNode.desc);
                final FieldAccess staticFieldAccess = new FieldAccess(new ClassLiteral(getType(ownerType)),
                        fieldInsnNode.name);
                expressionStack.add(staticFieldAccess);
                break;

            case Opcodes.GETFIELD:
                final Expression fieldAccessParent = expressionStack.pop();
                final FieldAccess fieldAccess = new FieldAccess(fieldAccessParent, fieldInsnNode.name);
                expressionStack.add(fieldAccess);
                break;
            case Opcodes.PUTFIELD:
                final Expression fieldAssignationValue = expressionStack.pop();
                final Expression parentSource = expressionStack.pop();
                final FieldAccess source = new FieldAccess(parentSource, fieldInsnNode.name);
                final Assignment assignmentExpression = new Assignment(source, fieldAssignationValue);
                statements.add(new ExpressionStatement(assignmentExpression));
                break;
            default:
                throw new AnalyzeException("Unexpected field instruction type: " + fieldInsnNode.getOpcode());

            }
            break;
        case AbstractInsnNode.METHOD_INSN:
            final MethodInsnNode methodInsnNode = (MethodInsnNode) currentInstruction;
            final Type[] argumentTypes = Type.getArgumentTypes(methodInsnNode.desc);
            final List<Expression> args = new ArrayList<>();
            final List<Class<?>> parameterTypes = new ArrayList<>();
            Stream.of(argumentTypes).forEach(argumentType -> {
                final Expression arg = expressionStack.pop();
                final String argumentClassName = argumentType.getClassName();
                args.add(castOperand(arg, argumentClassName));
                try {
                    parameterTypes.add(ClassUtils.getClass(argumentClassName));
                } catch (Exception e) {
                    throw new AnalyzeException("Failed to find class '" + argumentClassName + "'", e);
                }
            });
            // arguments appear in reverse order in the bytecode
            Collections.reverse(args);
            switch (methodInsnNode.getOpcode()) {
            case Opcodes.INVOKEINTERFACE:
            case Opcodes.INVOKEVIRTUAL:
            case Opcodes.INVOKESPECIAL:
                // object instantiation
                if (methodInsnNode.name.equals("<init>")) {
                    final ObjectInstanciation objectVariable = (ObjectInstanciation) expressionStack.pop();
                    objectVariable.setInitArguments(args);
                } else {
                    final Expression sourceExpression = expressionStack.pop();
                    final Method javaMethod = ReflectionUtils.findJavaMethod(sourceExpression.getJavaType(),
                            methodInsnNode.name, parameterTypes);
                    final Class<?> returnType = findReturnType(insnCursor, javaMethod);
                    final MethodInvocation invokedMethod = new MethodInvocation(sourceExpression, javaMethod,
                            returnType, args);
                    expressionStack.add(invokedMethod);
                }
                break;
            case Opcodes.INVOKESTATIC:
                final Type type = Type.getObjectType(methodInsnNode.owner);
                try {
                    final Class<?> sourceClass = Class.forName(type.getClassName());
                    final Method javaMethod = ReflectionUtils.findJavaMethod(sourceClass, methodInsnNode.name,
                            parameterTypes);
                    final Class<?> returnType = findReturnType(insnCursor, javaMethod);
                    final MethodInvocation invokedStaticMethod = new MethodInvocation(
                            new ClassLiteral(sourceClass), javaMethod, returnType, args);
                    expressionStack.add(invokedStaticMethod);
                } catch (ClassNotFoundException e) {
                    throw new AnalyzeException("Failed to retrieve class for " + methodInsnNode.owner, e);
                }
                break;
            default:
                throw new AnalyzeException("Unexpected method invocation type: " + methodInsnNode.getOpcode());
            }
            break;
        case AbstractInsnNode.INVOKE_DYNAMIC_INSN:
            final InvokeDynamicInsnNode invokeDynamicInsnNode = (InvokeDynamicInsnNode) currentInstruction;
            final Handle handle = (Handle) invokeDynamicInsnNode.bsmArgs[1];
            final int argNumber = Type.getArgumentTypes(invokeDynamicInsnNode.desc).length;
            final List<CapturedArgumentRef> lambdaArgs = new ArrayList<>();
            for (int i = 0; i < argNumber; i++) {
                final Expression expr = expressionStack.pop();
                if (expr.getExpressionType() != ExpressionType.CAPTURED_ARGUMENT_REF) {
                    throw new AnalyzeException("Unexpected argument type when following InvokeDynamic call: "
                            + expr.getExpressionType());
                }
                lambdaArgs.add((CapturedArgumentRef) expr); // , expr.getValue()
            }
            Collections.reverse(lambdaArgs);
            final EmbeddedSerializedLambdaInfo lambdaInfo = new EmbeddedSerializedLambdaInfo(handle.getOwner(),
                    handle.getName(), handle.getDesc(), lambdaArgs, capturedArguments);
            final LambdaExpression lambdaExpression = LambdaExpressionAnalyzer.getInstance()
                    .analyzeExpression(lambdaInfo);
            expressionStack.add(lambdaExpression);
            break;
        case AbstractInsnNode.JUMP_INSN:
            statements.addAll(
                    readJumpInstruction(insnCursor, expressionStack, capturedArguments, localVariables));
            return statements;
        case AbstractInsnNode.INT_INSN:
            readIntInstruction((IntInsnNode) currentInstruction, expressionStack, localVariables);
            break;
        case AbstractInsnNode.INSN:
            final List<Statement> instructionStatement = readInstruction(insnCursor, expressionStack,
                    capturedArguments, localVariables);
            statements.addAll(instructionStatement);
            break;
        case AbstractInsnNode.TYPE_INSN:
            readTypeInstruction((TypeInsnNode) currentInstruction, expressionStack, localVariables);
            break;
        default:
            throw new AnalyzeException(
                    "This is embarrassing... We've reached an unexpected instruction operator: "
                            + currentInstruction.getType());
        }
        insnCursor.next();
    }
    return statements;
}

From source file:org.spoofax.interpreter.adapter.asm.ASMFactory.java

License:LGPL

public static IStrategoTerm wrap(AbstractInsnNode node) {
    if (node == null)
        return None.INSTANCE;
    switch (node.getType()) {
    case AbstractInsnNode.FIELD_INSN:
        return wrap((FieldInsnNode) node);
    case AbstractInsnNode.FRAME:
        return wrap((FrameNode) node);
    case AbstractInsnNode.IINC_INSN:
        return wrap((IincInsnNode) node);
    case AbstractInsnNode.INSN:
        return wrap((InsnNode) node);
    case AbstractInsnNode.INT_INSN:
        return wrap((IntInsnNode) node);
    case AbstractInsnNode.INVOKE_DYNAMIC_INSN:
        throw new NotImplementedException();
    case AbstractInsnNode.JUMP_INSN:
        return wrap((JumpInsnNode) node);
    case AbstractInsnNode.LABEL:
        return wrap((LabelNode) node);
    case AbstractInsnNode.LDC_INSN:
        return wrap((LdcInsnNode) node);
    case AbstractInsnNode.LINE:
        return wrap((LineNumberNode) node);
    case AbstractInsnNode.LOOKUPSWITCH_INSN:
        return wrap((LookupSwitchInsnNode) node);
    case AbstractInsnNode.METHOD_INSN:
        return wrap((MethodInsnNode) node);
    case AbstractInsnNode.MULTIANEWARRAY_INSN:
        return wrap((MultiANewArrayInsnNode) node);
    case AbstractInsnNode.TABLESWITCH_INSN:
        return wrap((TableSwitchInsnNode) node);
    case AbstractInsnNode.TYPE_INSN:
        return wrap((TypeInsnNode) node);
    case AbstractInsnNode.VAR_INSN:
        return wrap((VarInsnNode) node);
    case -1:// w  w  w. j  a va2s .  c  om
        System.err.println("Bogus " + node.getClass().getName());
        return None.INSTANCE;
    default:
        throw new IllegalArgumentException(
                "Unknown type " + node.getOpcode() + " for " + node.getClass().getName());
    }
}