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

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

Introduction

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

Prototype

public int getOpcode() 

Source Link

Document

Returns the opcode of this instruction.

Usage

From source file:org.jacoco.playground.filter.FilterTestBase.java

License:Open Source License

protected final void applyFilterTo(MethodNode method) throws IOException {
    filter.filter(method, new IFilterOutput() {

        public void ignore(InsnSubList list) {
            for (AbstractInsnNode insn : list) {
                if (insn.getOpcode() != -1) {
                    ignore(insn);//from w  w w.j a va 2  s . c  o m
                }
            }
        }

        public void ignore(AbstractInsnNode node) {
            filtered.add(target.getLabelOf(node));
        }

        public void map(AbstractInsnNode fromNode, AbstractInsnNode toNode) {
            // TODO Auto-generated method stub
        }

    });
}

From source file:org.jacoco.playground.filter.JavacFinallyFilter.java

License:Open Source License

private boolean isBlockEnd(AbstractInsnNode node, int var) {
    if (node.getOpcode() != Opcodes.ALOAD) {
        return false;
    }// w ww  . j ava 2 s . c om
    if (((VarInsnNode) node).var != var) {
        return false;
    }
    final AbstractInsnNode next = getNext(node);
    return next != null && next.getOpcode() == Opcodes.ATHROW;
}

From source file:org.jephyr.easyflow.instrument.AnalyzingMethodNode.java

License:Open Source License

private static Object[] convertValues(Collection<?> values) {
    Object[] values1 = new Object[values.size()];
    int i = 0;//from   ww  w.j a v a 2 s  .  co  m
    for (Object value : values) {
        if (value instanceof Label) {
            AbstractInsnNode next = ((AbstractInsnNode) ((Label) value).info).getNext();
            while (next.getOpcode() != NEW) {
                next = next.getNext();
            }
            values1[i] = next;
        } else {
            values1[i] = value;
        }
        i++;
    }
    return values1;
}

From source file:org.jephyr.easyflow.instrument.ContinuationMethodAdapter.java

License:Open Source License

private void addMonitorHooks(int implVarIndex) {
    AbstractInsnNode next = instructions.getFirst();
    while (next != null) {
        AbstractInsnNode node = next;
        next = next.getNext();// w w  w .ja v a  2s.  c  o  m
        int opcode = node.getOpcode();
        if (opcode == MONITORENTER || opcode == MONITOREXIT) {
            LabelNode labelNode = newLabelNode();

            instructions.insert(node, labelNode);

            Frame frame = findNextFrame(frames, node);
            Object[] stack = frame.stack;

            if (!isNextFrameNode(labelNode)) {
                instructions.insert(labelNode, newFrameNode(appendValue(ensureSize(frame.locals, implVarIndex),
                        "org/jephyr/continuation/easyflow/ContinuationImpl"), stack));
            }

            instructions.insertBefore(labelNode, new VarInsnNode(ALOAD, implVarIndex));
            instructions.insertBefore(labelNode, new JumpInsnNode(IFNULL, labelNode));

            instructions.insertBefore(labelNode, new VarInsnNode(ALOAD, implVarIndex));
            instructions.insertBefore(labelNode,
                    new MethodInsnNode(INVOKEVIRTUAL, "org/jephyr/continuation/easyflow/ContinuationImpl",
                            opcode == MONITORENTER ? "monitorEntered" : "monitorExited", "()V", false));

            updateMaxStack(stack.length + 1);
        }
    }
}

From source file:org.jephyr.easyflow.instrument.NewRelocatorMethodAdapter.java

License:Open Source License

@Override
public void visitEnd() {
    AbstractInsnNode next = instructions.getFirst();
    boolean removeFrame = false;
    int stackSize = 0;

    while (next != null) {
        AbstractInsnNode node = next;
        next = next.getNext();//from   w w  w .ja  va2  s.co m
        Object[] stack;

        switch (node.getOpcode()) {
        case -1:
            if (node instanceof FrameNode) {
                if (removeFrame) {
                    instructions.remove(node);
                } else {
                    stackSize = handleFrame((FrameNode) node);
                    removeFrame = true;
                }
            }
            break;
        case NOP:
        case LALOAD:
        case DALOAD:
        case INEG:
        case LNEG:
        case FNEG:
        case DNEG:
        case IINC:
        case I2F:
        case L2D:
        case F2I:
        case D2L:
        case I2B:
        case I2C:
        case I2S:
        case GOTO:
        case RET:
        case NEWARRAY:
        case ANEWARRAY:
        case ARRAYLENGTH:
        case CHECKCAST:
        case INSTANCEOF:
            removeFrame = false;
            break;
        case ACONST_NULL:
        case ICONST_M1:
        case ICONST_0:
        case ICONST_1:
        case ICONST_2:
        case ICONST_3:
        case ICONST_4:
        case ICONST_5:
        case FCONST_0:
        case FCONST_1:
        case FCONST_2:
        case BIPUSH:
        case SIPUSH:
        case ILOAD:
        case FLOAD:
        case I2L:
        case I2D:
        case F2L:
        case F2D:
        case JSR:
            stackSize += 1;
            updateMaxStack(stackSize);
            removeFrame = false;
            break;
        case LCONST_0:
        case LCONST_1:
        case DCONST_0:
        case DCONST_1:
        case LLOAD:
        case DLOAD:
            stackSize += 2;
            updateMaxStack(stackSize);
            removeFrame = false;
            break;
        case LDC:
            Object cst = ((LdcInsnNode) node).cst;
            stackSize += cst instanceof Long || cst instanceof Double ? 2 : 1;
            updateMaxStack(stackSize);
            removeFrame = false;
            break;
        case ALOAD:
            if (frames.get(node).locals[((VarInsnNode) node).var] instanceof AbstractInsnNode) {
                instructions.remove(node);
            } else {
                stackSize += 1;
                updateMaxStack(stackSize);
                removeFrame = false;
            }
            break;
        case IALOAD:
        case FALOAD:
        case AALOAD:
        case BALOAD:
        case CALOAD:
        case SALOAD:
        case ISTORE:
        case FSTORE:
        case IADD:
        case FADD:
        case ISUB:
        case FSUB:
        case IMUL:
        case FMUL:
        case IDIV:
        case FDIV:
        case IREM:
        case FREM:
        case ISHL:
        case ISHR:
        case IUSHR:
        case IAND:
        case IOR:
        case IXOR:
        case L2I:
        case L2F:
        case D2I:
        case D2F:
        case IFEQ:
        case IFNE:
        case IFLT:
        case IFGE:
        case IFGT:
        case IFLE:
        case TABLESWITCH:
        case LOOKUPSWITCH:
        case MONITORENTER:
        case MONITOREXIT:
            stackSize -= 1;
            removeFrame = false;
            break;
        case LSTORE:
        case DSTORE:
        case LADD:
        case DADD:
        case LSUB:
        case DSUB:
        case LMUL:
        case DMUL:
        case LDIV:
        case DDIV:
        case LREM:
        case DREM:
        case LSHL:
        case LSHR:
        case LUSHR:
        case LAND:
        case LOR:
        case LXOR:
        case FCMPL:
        case FCMPG:
        case IF_ICMPEQ:
        case IF_ICMPNE:
        case IF_ICMPLT:
        case IF_ICMPGE:
        case IF_ICMPGT:
        case IF_ICMPLE:
            stackSize -= 2;
            removeFrame = false;
            break;
        case ASTORE:
            stack = frames.get(node).stack;
            if (stack[stack.length - 1] instanceof AbstractInsnNode) {
                instructions.remove(node);
            } else {
                stackSize -= 1;
                removeFrame = false;
            }
            break;
        case IASTORE:
        case FASTORE:
        case AASTORE:
        case BASTORE:
        case CASTORE:
        case SASTORE:
        case LCMP:
        case DCMPL:
        case DCMPG:
            stackSize -= 3;
            removeFrame = false;
            break;
        case LASTORE:
        case DASTORE:
            stackSize -= 4;
            removeFrame = false;
            break;
        case POP:
            stack = frames.get(node).stack;
            if (stack[stack.length - 1] instanceof AbstractInsnNode) {
                instructions.remove(node);
            } else {
                stackSize -= 1;
                removeFrame = false;
            }
            break;
        case POP2:
            stack = frames.get(node).stack;
            if (stack[stack.length - 1] instanceof AbstractInsnNode) {
                if (stack[stack.length - 2] instanceof AbstractInsnNode) {
                    instructions.remove(node);
                } else {
                    instructions.set(node, new InsnNode(POP));
                    stackSize -= 1;
                    removeFrame = false;
                }
            } else {
                if (stack[stack.length - 2] instanceof AbstractInsnNode) {
                    instructions.set(node, new InsnNode(POP));
                    stackSize -= 1;
                } else {
                    stackSize -= 2;
                }
                removeFrame = false;
            }
            break;
        case DUP:
            stack = frames.get(node).stack;
            if (stack[stack.length - 1] instanceof AbstractInsnNode) {
                instructions.remove(node);
            } else {
                stackSize += 1;
                updateMaxStack(stackSize);
                removeFrame = false;
            }
            break;
        case DUP_X1:
            stack = frames.get(node).stack;
            if (stack[stack.length - 1] instanceof AbstractInsnNode) {
                instructions.remove(node);
            } else {
                if (stack[stack.length - 2] instanceof AbstractInsnNode) {
                    instructions.set(node, new InsnNode(DUP));
                }
                stackSize += 1;
                updateMaxStack(stackSize);
                removeFrame = false;
            }
            break;
        case DUP_X2:
            stack = frames.get(node).stack;
            if (stack[stack.length - 1] instanceof AbstractInsnNode) {
                instructions.remove(node);
            } else {
                if (stack[stack.length - 2] instanceof AbstractInsnNode) {
                    if (stack[stack.length - 3] instanceof AbstractInsnNode) {
                        instructions.set(node, new InsnNode(DUP));
                    } else {
                        instructions.set(node, new InsnNode(DUP_X1));
                    }
                } else {
                    if (stack[stack.length - 3] instanceof AbstractInsnNode) {
                        instructions.set(node, new InsnNode(DUP_X1));
                    }
                }
                stackSize += 1;
                updateMaxStack(stackSize);
                removeFrame = false;
            }
            break;
        case DUP2:
            stack = frames.get(node).stack;
            if (stack[stack.length - 1] instanceof AbstractInsnNode) {
                if (stack[stack.length - 2] instanceof AbstractInsnNode) {
                    instructions.remove(node);
                } else {
                    instructions.set(node, new InsnNode(DUP));
                    stackSize += 1;
                    updateMaxStack(stackSize);
                    removeFrame = false;
                }
            } else {
                if (stack[stack.length - 2] instanceof AbstractInsnNode) {
                    instructions.set(node, new InsnNode(DUP));
                    stackSize += 1;
                } else {
                    stackSize += 2;
                }
                updateMaxStack(stackSize);
                removeFrame = false;
            }
            break;
        case DUP2_X1:
            stack = frames.get(node).stack;
            if (stack[stack.length - 1] instanceof AbstractInsnNode) {
                if (stack[stack.length - 2] instanceof AbstractInsnNode) {
                    instructions.remove(node);
                } else {
                    if (stack[stack.length - 3] instanceof AbstractInsnNode) {
                        instructions.set(node, new InsnNode(DUP));
                    } else {
                        instructions.set(node, new InsnNode(DUP_X1));
                    }
                    stackSize += 1;
                    updateMaxStack(stackSize);
                    removeFrame = false;
                }
            } else {
                if (stack[stack.length - 2] instanceof AbstractInsnNode) {
                    if (stack[stack.length - 3] instanceof AbstractInsnNode) {
                        instructions.set(node, new InsnNode(DUP));
                    } else {
                        instructions.set(node, new InsnNode(DUP_X1));
                    }
                    stackSize += 1;
                } else {
                    if (stack[stack.length - 3] instanceof AbstractInsnNode) {
                        instructions.set(node, new InsnNode(DUP2));
                    }
                    stackSize += 2;
                }
                updateMaxStack(stackSize);
                removeFrame = false;
            }
            break;
        case DUP2_X2:
            stack = frames.get(node).stack;
            if (stack[stack.length - 1] instanceof AbstractInsnNode) {
                if (stack[stack.length - 2] instanceof AbstractInsnNode) {
                    instructions.remove(node);
                } else {
                    if (stack[stack.length - 3] instanceof AbstractInsnNode) {
                        if (stack[stack.length - 4] instanceof AbstractInsnNode) {
                            instructions.set(node, new InsnNode(DUP));
                        } else {
                            instructions.set(node, new InsnNode(DUP_X1));
                        }
                    } else {
                        if (stack[stack.length - 3] instanceof AbstractInsnNode) {
                            instructions.set(node, new InsnNode(DUP_X1));
                        } else {
                            instructions.set(node, new InsnNode(DUP_X2));
                        }
                    }
                    stackSize += 1;
                    updateMaxStack(stackSize);
                    removeFrame = false;
                }
            } else {
                if (stack[stack.length - 2] instanceof AbstractInsnNode) {
                    if (stack[stack.length - 3] instanceof AbstractInsnNode) {
                        if (stack[stack.length - 4] instanceof AbstractInsnNode) {
                            instructions.set(node, new InsnNode(DUP));
                        } else {
                            instructions.set(node, new InsnNode(DUP_X1));
                        }
                    } else {
                        if (stack[stack.length - 4] instanceof AbstractInsnNode) {
                            instructions.set(node, new InsnNode(DUP_X1));
                        } else {
                            instructions.set(node, new InsnNode(DUP_X2));
                        }
                    }
                    stackSize += 1;
                } else {
                    if (stack[stack.length - 3] instanceof AbstractInsnNode) {
                        if (stack[stack.length - 4] instanceof AbstractInsnNode) {
                            instructions.set(node, new InsnNode(DUP2));
                        } else {
                            instructions.set(node, new InsnNode(DUP2_X1));
                        }
                    } else {
                        if (stack[stack.length - 4] instanceof AbstractInsnNode) {
                            instructions.set(node, new InsnNode(DUP2_X1));
                        }
                    }
                    stackSize += 2;
                }
                updateMaxStack(stackSize);
                removeFrame = false;
            }
            break;
        case SWAP:
            stack = frames.get(node).stack;
            if (stack[stack.length - 1] instanceof AbstractInsnNode
                    || stack[stack.length - 2] instanceof AbstractInsnNode) {
                instructions.remove(node);
            } else {
                removeFrame = false;
            }
            break;
        case IF_ACMPEQ:
            stack = frames.get(node).stack;
            if (stack[stack.length - 1] instanceof AbstractInsnNode) {
                if (stack[stack.length - 2] instanceof AbstractInsnNode) {
                    if (stack[stack.length - 1] == stack[stack.length - 2]) {
                        instructions.set(node, new JumpInsnNode(GOTO, ((JumpInsnNode) node).label));
                        removeFrame = false;
                    } else {
                        instructions.remove(node);
                    }
                } else {
                    instructions.set(node, new InsnNode(POP));
                    stackSize -= 1;
                    removeFrame = false;
                }
            } else {
                if (stack[stack.length - 2] instanceof AbstractInsnNode) {
                    instructions.set(node, new InsnNode(POP));
                    stackSize -= 1;
                } else {
                    stackSize -= 2;
                }
                removeFrame = false;
            }
            break;
        case IF_ACMPNE:
            stack = frames.get(node).stack;
            if (stack[stack.length - 1] instanceof AbstractInsnNode) {
                if (stack[stack.length - 2] instanceof AbstractInsnNode) {
                    if (stack[stack.length - 1] == stack[stack.length - 2]) {
                        instructions.remove(node);
                    } else {
                        instructions.set(node, new JumpInsnNode(GOTO, ((JumpInsnNode) node).label));
                        removeFrame = false;
                    }
                } else {
                    instructions.insertBefore(node, new InsnNode(POP));
                    stackSize -= 1;
                    instructions.set(node, new JumpInsnNode(GOTO, ((JumpInsnNode) node).label));
                    removeFrame = false;
                }
            } else {
                if (stack[stack.length - 2] instanceof AbstractInsnNode) {
                    instructions.insertBefore(node, new InsnNode(POP));
                    stackSize -= 1;
                    instructions.set(node, new JumpInsnNode(GOTO, ((JumpInsnNode) node).label));
                } else {
                    stackSize -= 2;
                }
                removeFrame = false;
            }
            break;
        case IRETURN:
        case LRETURN:
        case FRETURN:
        case DRETURN:
        case ARETURN:
        case RETURN:
            stackSize = 0;
            removeFrame = false;
            break;
        case GETSTATIC:
            stackSize += getTypeSize(((FieldInsnNode) node).desc);
            updateMaxStack(stackSize);
            removeFrame = false;
            break;
        case PUTSTATIC:
            stackSize -= getTypeSize(((FieldInsnNode) node).desc);
            removeFrame = false;
            break;
        case GETFIELD:
            stackSize += getTypeSize(((FieldInsnNode) node).desc) - 1;
            updateMaxStack(stackSize);
            removeFrame = false;
            break;
        case PUTFIELD:
            stackSize -= getTypeSize(((FieldInsnNode) node).desc) + 1;
            removeFrame = false;
            break;
        case INVOKEVIRTUAL:
        case INVOKEINTERFACE:
            stackSize += getInvokeDelta(((MethodInsnNode) node).desc);
            updateMaxStack(stackSize);
            removeFrame = false;
            break;
        case INVOKESPECIAL:
            stackSize = handleInvokeSpecial((MethodInsnNode) node, stackSize);
            removeFrame = false;
            break;
        case INVOKESTATIC:
            stackSize += getInvokeDelta(((MethodInsnNode) node).desc) + 1;
            updateMaxStack(stackSize);
            removeFrame = false;
            break;
        case INVOKEDYNAMIC:
            stackSize += getInvokeDelta(((InvokeDynamicInsnNode) node).desc) + 1;
            updateMaxStack(stackSize);
            removeFrame = false;
            break;
        case NEW:
            instructions.remove(node);
            break;
        case ATHROW:
            stackSize += 1 - stackSize;
            updateMaxStack(stackSize);
            removeFrame = false;
            break;
        case MULTIANEWARRAY:
            stackSize += 1 - ((MultiANewArrayInsnNode) node).dims;
            updateMaxStack(stackSize);
            removeFrame = false;
            break;
        case IFNULL:
            stack = frames.get(node).stack;
            if (!(stack[stack.length - 1] instanceof AbstractInsnNode)) {
                stackSize -= 1;
                removeFrame = false;
            }
            break;
        default: // IFNONNULL:
            stack = frames.get(node).stack;
            if (stack[stack.length - 1] instanceof AbstractInsnNode) {
                instructions.set(node, new JumpInsnNode(GOTO, ((JumpInsnNode) node).label));
            } else {
                stackSize -= 1;
            }
            removeFrame = false;
        }
    }

    accept(mv);
}

From source file:org.jooby.internal.apitool.BytecodeRouteParser.java

License:Apache License

private java.lang.reflect.Type parameterType(final ClassLoader loader, final AbstractInsnNode n) {
    if (n instanceof MethodInsnNode) {
        MethodInsnNode node = (MethodInsnNode) n;
        if (mutantValue().test(node)) {
            /** value(); intValue(); booleanValue(); */
            return TypeDescriptorParser.parse(loader, node.desc);
        } else if (mutantToSomething().test(node) || getOrCreateKotlinClass().test(node)) {
            /** to(String.class); toOptional; toList(); */
            String owner = Type.getReturnType(node.desc).getClassName();
            AbstractInsnNode prev = node.getPrevious();
            if (prev instanceof FieldInsnNode && ((MethodInsnNode) n).name.equals("toEnum")) {
                /** toEnum(Letter.A); */
                return loadType(loader, ((FieldInsnNode) prev).owner);
            }/*  ww  w.  j a v  a2 s  .c  om*/
            java.lang.reflect.Type toType = String.class;
            if (prev instanceof LdcInsnNode) {
                /** to(Foo.class); */
                Object cst = ((LdcInsnNode) prev).cst;
                if (cst instanceof Type) {
                    toType = loadType(loader, ((Type) cst).getClassName());
                }
            } else if (prev instanceof FieldInsnNode) {
                toType = loadType(loader, ((FieldInsnNode) prev).owner);
            }
            // JoobyKt.toOptional
            AbstractInsnNode next = node.getNext();
            if (next instanceof MethodInsnNode) {
                String joobyKt = ((MethodInsnNode) next).owner;
                String methodName = ((MethodInsnNode) next).name;
                if ("toOptional".equals(methodName) && "org/jooby/JoobyKt".equals(joobyKt)) {
                    owner = Optional.class.getName();
                }
            }

            Set<String> skipOwners = ImmutableSet.of(Object.class.getName(), Enum.class.getName(),
                    "kotlin.reflect.KClass");
            if (skipOwners.contains(owner)) {
                return toType;
            }

            /** toList(Foo.class); */
            return Types.newParameterizedType(loadType(loader, owner), toType);
        }
    } else if (n instanceof VarInsnNode) {
        return new Insn<>(null, n).prev().filter(is(MethodInsnNode.class)).findFirst()
                .map(MethodInsnNode.class::cast).filter(file()).map(m -> {
                    return m.name.equals("files") ? Types.newParameterizedType(List.class, File.class)
                            : File.class;
                }).orElse(Object.class);
    } else if (n instanceof TypeInsnNode) {
        TypeInsnNode typeInsn = (TypeInsnNode) n;
        if (typeInsn.getOpcode() == Opcodes.CHECKCAST) {
            return loadType(loader, typeInsn.desc);
        }
    } else if (n != null && Opcodes.DUP == n.getOpcode()) {
        // Kotlin 1.2.x
        // mv.visitInsn(DUP);
        // mv.visitLdcInsn("req.param(\"p1\")");
        // mv.visitMethodInsn(INVOKESTATIC, "kotlin/jvm/internal/Intrinsics", "checkExpressionValueIsNotNull", "(Ljava/lang/Object;Ljava/lang/String;)V", false);
        // mv.visitMethodInsn(INVOKESTATIC, "org/jooby/JoobyKt", "getValue", "(Lorg/jooby/Mutant;)Ljava/lang/String;", false);
        AbstractInsnNode next = new Insn<>(null, n).next().filter(MethodInsnNode.class::isInstance).skip(1)
                .findFirst().orElse(null);
        java.lang.reflect.Type result = parameterType(loader, next);
        if (result == Object.class) {
            next = new Insn<>(null, n).next().filter(TypeInsnNode.class::isInstance).findFirst().orElse(null);
            result = parameterType(loader, next);
        }
        return result;
    } else if (n instanceof FieldInsnNode) {
        AbstractInsnNode next = n.getNext();
        if (next instanceof MethodInsnNode) {
            if (((MethodInsnNode) next).name.equals("toOptional")) {
                return Types.newParameterizedType(Optional.class, loadType(loader, ((FieldInsnNode) n).owner));
            } else if (((MethodInsnNode) next).name.equals("getOrCreateKotlinClass")) {
                return loadType(loader, ((FieldInsnNode) n).owner);
            }
        }
    }
    return Object.class;
}

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 w  w .j a  va 2 s.  com
 * 
 * @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.lambdamatic.analyzer.ast.LambdaExpressionReader.java

License:Open Source License

/**
 * Checks if an operation of type OpsCode.CHECKCAST is following this operation, in which case it
 * provides valuable info about the actual returned type of the method
 * //ww w  . ja  v a 2  s  .co  m
 * @param insnCursor the {@link InsnCursor}
 * @param javaMethod the current Java {@link Method}
 * @return the return type of the given method.
 */
private static Class<?> findReturnType(final InsnCursor insnCursor, final Method javaMethod) {
    if (insnCursor.hasNext()) {
        final AbstractInsnNode nextOp = insnCursor.getNext();
        if (nextOp.getOpcode() == Opcodes.CHECKCAST) {
            final TypeInsnNode checkCastInsnNode = (TypeInsnNode) nextOp;
            try {
                return Class.forName(Type.getObjectType(checkCastInsnNode.desc).getClassName());
            } catch (ClassNotFoundException e) {
                throw new AnalyzeException("Failed to retrieve class for " + checkCastInsnNode.desc, e);
            }
        } else {
            // move cursor position backwards
            insnCursor.getPrevious();
        }
    }
    return javaMethod.getReturnType();
}

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

License:Open Source License

/**
 * Reads the current {@link InsnNode} instruction and returns a {@link Statement} or {@code null}
 * if the instruction is not a full statement (in that case, the instruction is stored in the
 * given Expression {@link Stack})./*  w ww. j a v a 2  s .  c  o  m*/
 * 
 * @param insnNode the instruction to read
 * @param expressionStack the expression stack to put on or pop from.
 * @param localVariables the local variables
 * @return a {@link List} of {@link Statement} or empty list if no {@link Statement} was created
 *         after reading the current instruction.
 * @see <a href="https://en.wikipedia.org/wiki/Java_bytecode_instruction_listings">Java bytcode
 *      instruction listings on Wikipedia</a>
 */
private List<Statement> readInstruction(final InsnCursor insnCursor, final Stack<Expression> expressionStack,
        final List<CapturedArgument> capturedArguments, final LocalVariables localVariables) {
    final List<Statement> statements = new ArrayList<>();
    final AbstractInsnNode insnNode = insnCursor.getCurrent();
    switch (insnNode.getOpcode()) {
    // return a reference from a method
    case Opcodes.ARETURN:
        // return an integer from a method
    case Opcodes.IRETURN:
        statements.add(new ReturnStatement(expressionStack.pop()));
        break;
    // return void from method
    case Opcodes.RETURN:
        // wrap all pending expressions into ExpressionStatements
        while (!expressionStack.isEmpty()) {
            final Expression pendingExpression = expressionStack.pop();
            statements.add(new ExpressionStatement(pendingExpression));
        }
        break;
    // push a null reference onto the stack
    case Opcodes.ACONST_NULL:
        expressionStack.add(new NullLiteral());
        break;
    // load the int value 0 onto the stack
    case Opcodes.ICONST_0:
        // applies for byte, short, int and boolean
        expressionStack.add(new NumberLiteral(0));
        break;
    // load the int value 1 onto the stack
    case Opcodes.ICONST_1:
        // applies for byte, short, int and boolean
        expressionStack.add(new NumberLiteral(1));
        break;
    // load the int value 2 onto the stack
    case Opcodes.ICONST_2:
        expressionStack.add(new NumberLiteral(2));
        break;
    // load the int value 3 onto the stack
    case Opcodes.ICONST_3:
        expressionStack.add(new NumberLiteral(3));
        break;
    // load the int value 4 onto the stack
    case Opcodes.ICONST_4:
        expressionStack.add(new NumberLiteral(4));
        break;
    // load the int value 5 onto the stack
    case Opcodes.ICONST_5:
        expressionStack.add(new NumberLiteral(5));
        break;
    // push the long 0 onto the stack
    case Opcodes.LCONST_0:
        expressionStack.add(new NumberLiteral(0L));
        break;
    // push the long 1 onto the stack
    case Opcodes.LCONST_1:
        expressionStack.add(new NumberLiteral(1L));
        break;
    // push the 0.0f onto the stack
    case Opcodes.FCONST_0:
        expressionStack.add(new NumberLiteral(0f));
        break;
    // push the 1.0f onto the stack
    case Opcodes.FCONST_1:
        expressionStack.add(new NumberLiteral(1f));
        break;
    // push the 2.0f onto the stack
    case Opcodes.FCONST_2:
        expressionStack.add(new NumberLiteral(2f));
        break;
    // push the constant 0.0 onto the stack
    case Opcodes.DCONST_0:
        expressionStack.add(new NumberLiteral(0d));
        break;
    // push the constant 1.0 onto the stack
    case Opcodes.DCONST_1:
        expressionStack.add(new NumberLiteral(1d));
        break;
    // compare two longs values
    case Opcodes.LCMP:
        // compare two doubles
    case Opcodes.DCMPL:
        // compare two doubles
    case Opcodes.DCMPG:
        // compare two floats
    case Opcodes.FCMPL:
        // compare two floats
    case Opcodes.FCMPG:
        statements.addAll(
                readJumpInstruction(insnCursor.next(), expressionStack, capturedArguments, localVariables));
        break;
    // add 2 ints
    case Opcodes.IADD:
        expressionStack.add(readOperation(Operator.ADD, expressionStack));
        break;
    // int subtract
    case Opcodes.ISUB:
        expressionStack.add(readOperation(Operator.SUBTRACT, expressionStack));
        break;
    // multiply 2 integers
    case Opcodes.IMUL:
        expressionStack.add(readOperation(Operator.MULTIPLY, expressionStack));
        break;
    // divide 2 integers
    case Opcodes.IDIV:
        expressionStack.add(readOperation(Operator.DIVIDE, expressionStack));
        break;
    // negate int
    case Opcodes.INEG:
        expressionStack.add(inverseInteger(expressionStack));
        break;
    // discard the top value on the stack
    case Opcodes.POP:
        statements.add(new ExpressionStatement(expressionStack.pop()));
        break;
    // duplicate the value on top of the stack
    case Opcodes.DUP:
        expressionStack.push(expressionStack.peek());
        break;
    // insert a copy of the top value into the stack two values from the top.
    case Opcodes.DUP_X1:
        expressionStack.add(expressionStack.size() - 2, expressionStack.peek());
        break;
    // store into a reference in an array
    case Opcodes.AASTORE:
        readArrayStoreInstruction(insnNode, expressionStack);
        break;
    // converts Float to Double -> ignored.
    case Opcodes.F2D:
        break;
    default:
        throw new AnalyzeException(
                "Bytecode instruction with OpCode '" + insnNode.getOpcode() + "' is not supported.");
    }
    return statements;
}

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

License:Open Source License

/**
 * Extracts the comparison {@link CompoundExpressionOperator} from the given {@link JumpInsnNode}.
 * //from ww w .j  av  a 2s.c o m
 * @param currentInstruction the comparison instruction
 * @return the corresponding {@link CompoundExpressionOperator}
 */
private static CompoundExpressionOperator extractComparisonOperator(final AbstractInsnNode currentInstruction) {
    switch (currentInstruction.getOpcode()) {
    case Opcodes.IF_ACMPNE:
    case Opcodes.IF_ICMPNE:
    case Opcodes.IFNE:
        return CompoundExpressionOperator.NOT_EQUALS;
    case Opcodes.IF_ACMPEQ:
    case Opcodes.IF_ICMPEQ:
    case Opcodes.IFEQ:
        return CompoundExpressionOperator.EQUALS;
    case Opcodes.IF_ICMPLE:
    case Opcodes.IFLE:
        return CompoundExpressionOperator.LESS_EQUALS;
    case Opcodes.IF_ICMPLT:
    case Opcodes.IFLT:
        return CompoundExpressionOperator.LESS;
    case Opcodes.IF_ICMPGE:
    case Opcodes.IFGE:
        return CompoundExpressionOperator.GREATER_EQUALS;
    case Opcodes.IF_ICMPGT:
    case Opcodes.IFGT:
        return CompoundExpressionOperator.GREATER;
    default:
        throw new AnalyzeException(
                "Failed to retrieve the operator for the current comparison instruction (opcode: "
                        + currentInstruction.getOpcode() + ")");
    }
}