List of usage examples for org.objectweb.asm.tree AbstractInsnNode getOpcode
public int getOpcode()
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() + ")"); } }