Example usage for org.objectweb.asm Opcodes POP

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

Introduction

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

Prototype

int POP

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

Click Source Link

Usage

From source file:org.jboss.byteman.rule.expression.DollarExpression.java

License:Open Source License

@Override
public void compileAssign(MethodVisitor mv, CompileContext compileContext) throws CompileException {
    // make sure we are at the right source line
    compileContext.notifySourceLine(line);

    String targetName = binding.getName();

    int currentStack = compileContext.getStackCount();
    int size = ((type.getNBytes() > 4) ? 2 : 1);

    if (index == HELPER_IDX) {
        // not allowed to reassign the helper binding
        throw new CompileException("DollarExpression.compileAssign : invalid assignment to helper binding $$");
    } else {//  w  w  w. j a va 2s  . co m
        // value to be assigned is TOS and will already be coerced to the correct value type
        // copy it so we leave it as a a return value on the stack
        if (size == 2) {
            mv.visitInsn(Opcodes.DUP2);
        } else {
            mv.visitInsn(Opcodes.DUP);
        }
        // stack the current helper then insert it below the value
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        if (size == 2) {
            // use a DUP_X2 to push a copy below the value then pop the redundant value
            mv.visitInsn(Opcodes.DUP_X2);
            mv.visitInsn(Opcodes.POP);
        } else {
            // we can just swap the two values
            mv.visitInsn(Opcodes.SWAP);
        }
        // stack the name for the variable and swap below the value
        mv.visitLdcInsn(targetName);
        if (size == 2) {
            // use a DUP_X2 to push a copy below the value then pop the redundant value
            mv.visitInsn(Opcodes.DUP_X2);
            // this is the high water mark
            // at this point the stack has gone from [ .. val1 val2]  to [.. val1 val2 helper name val1 val2 name]
            compileContext.addStackCount(5);
            mv.visitInsn(Opcodes.POP);
            compileContext.addStackCount(-1);
        } else {
            // this is the high water mark
            // at this point the stack has gone from [ .. val]  to [.. val helper val name]
            compileContext.addStackCount(3);
            // we can just swap the two values
            mv.visitInsn(Opcodes.SWAP);
        }
        // ensure we have an object
        compileObjectConversion(type, Type.OBJECT, mv, compileContext);

        // call the setBinding method
        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.internalName(HelperAdapter.class), "setBinding",
                "(Ljava/lang/String;Ljava/lang/Object;)V");

        // the call will remove 3 from the stack height
        compileContext.addStackCount(-3);

        // ok, the stack height should be as it was
        if (compileContext.getStackCount() != currentStack) {
            throw new CompileException("variable.compileAssignment : invalid stack height "
                    + compileContext.getStackCount() + " expecting " + currentStack);
        }
    }
}

From source file:org.jboss.byteman.rule.expression.FieldExpression.java

License:Open Source License

@Override
public void compileAssign(MethodVisitor mv, CompileContext compileContext) throws CompileException {
    if (indirectStatic != null) {
        // this is just wrapping a static field expression so compile it
        indirectStatic.compileAssign(mv, compileContext);
    } else {/* ww  w.ja  v a2 s .com*/
        // make sure we are at the right source line
        compileContext.notifySourceLine(line);

        int currentStack = compileContext.getStackCount();
        int size = (type.getNBytes() > 4 ? 2 : 1);

        // copy the value so we leave it as a result
        if (size == 1) {
            // this means at the maximum we add 1 to the current stack
            // [.. val] ==> [.. val val]
            mv.visitInsn(Opcodes.DUP);
        } else {
            // [.. val1 val2] ==> [.. val1 val2 val1 val2]
            mv.visitInsn(Opcodes.DUP2);
        }
        compileContext.addStackCount(size);
        // compile the owner expression and swap with the value
        owner.compile(mv, compileContext);
        if (size == 1) {
            // [.. val val owner] ==> [.. val owner val]
            mv.visitInsn(Opcodes.SWAP);
        } else {
            // we have to use a DUP_X2 and a POP to insert the owner below the two word value
            // i.e. [.. val1 val2 val1 val2] ==> [.. val1 val2 val1 val2 owner] ==>
            //              [.. val1 val2 owner val1 val2 owner] ==> [.. val1 val2 owner val1 val2]
            mv.visitInsn(Opcodes.DUP_X2);
            compileContext.addStackCount(1);
            mv.visitInsn(Opcodes.POP);
            compileContext.addStackCount(-1);
        }
        if (isPublicField) {
            // now compile a field update
            String ownerType = Type.internalName(field.getDeclaringClass());
            String fieldName = field.getName();
            String fieldType = Type.internalName(field.getType(), true);
            mv.visitFieldInsn(Opcodes.PUTFIELD, ownerType, fieldName, fieldType);
            // we removed the owner and the value
            compileContext.addStackCount(-(1 + size));
        } else {
            // since this is a private field we need to do the update using reflection
            // box the value to an object if necessary
            if (type.isPrimitive()) {
                compileBox(Type.boxType(type), mv, compileContext);
            }
            // stack the helper and then dupx2 it so it goes under the owner and value
            // [.. val(s) owner  valObj ==> val(s) owner valObj helper ]
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            // [.. val(s) owner  valObj helper ==> val(s) helper owner valObj helper ]
            mv.visitInsn(Opcodes.DUP_X2);
            // stack now has 2 more words so count them
            compileContext.addStackCount(2);
            // now pop the redundant top word and stack the field index instead
            // [.. val(s) helper owner valObj helper ==> val(s) helper owner valObj index ]
            mv.visitInsn(Opcodes.POP);
            mv.visitLdcInsn(fieldIndex);
            // use the HelperAdapter method setAccessibleField to set the field value
            mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.internalName(HelperAdapter.class),
                    "setAccessibleField", "(Ljava/lang/Object;Ljava/lang/Object;I)V");
            // we popped four args
            compileContext.addStackCount(-4);
        }

        // check the stack height is ok
        if (compileContext.getStackCount() != currentStack) {
            throw new CompileException("FieldExpression.compileAssign : invalid stack height "
                    + compileContext.getStackCount() + " expecting " + (currentStack));
        }
    }
}

From source file:org.jboss.byteman.rule.expression.MethodExpression.java

License:Open Source License

public void compile(MethodVisitor mv, CompileContext compileContext) throws CompileException {
    // make sure we are at the right source line
    compileContext.notifySourceLine(line);

    int currentStack = compileContext.getStackCount();
    int extraParams = 0; // space used by stacked args after conversion
    int expected = 0;

    // no need for type conversion as return type was derived from method
    if (type.getNBytes() > 4) {
        expected = 2;/*from  w  w  w .j  av  a  2 s .c  o m*/
    } else if (type != Type.VOID) {
        expected = 1;
    } else {
        expected = 0;
    }

    int argCount = arguments.size();

    if (isPublicMethod) {
        // we can just do this as a direct call
        // stack the recipient if necessary then stack the args and then invoke the method
        if (recipient != null) {
            // compile code for recipient
            recipient.compile(mv, compileContext);

            extraParams += 1;
        }

        for (int i = 0; i < argCount; i++) {
            Expression argument = arguments.get(i);
            Type argType = argumentTypes.get(i);
            Type paramType = paramTypes.get(i);
            // compile code to stack argument and type convert if necessary
            argument.compile(mv, compileContext);
            compileTypeConversion(argType, paramType, mv, compileContext);
            // allow for stacked paramType value
            extraParams += (paramType.getNBytes() > 4 ? 2 : 1);
        }

        // enable triggering before we call the method
        // this adds an extra value to the stack so modify the compile context to ensure
        // we increase the maximum height if necessary
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/jboss/byteman/rule/Rule", "enableTriggersInternal",
                "()Z");
        compileContext.addStackCount(1);
        mv.visitInsn(Opcodes.POP);
        compileContext.addStackCount(-1);

        // ok, now just call the method -- removes extraParams words

        String ownerName = Type.internalName(method.getDeclaringClass());

        if (recipient == null) {
            mv.visitMethodInsn(Opcodes.INVOKESTATIC, ownerName, method.getName(), getDescriptor());
        } else if (method.getDeclaringClass().isInterface()) {
            mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, ownerName, method.getName(), getDescriptor());
        } else {
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, ownerName, method.getName(), getDescriptor());
        }
        // decrement the stack height to account for stacked param values (removed) and return value (added)
        compileContext.addStackCount(expected - extraParams);

        // now disable triggering again
        // this temporarily adds an extra value to the stack -- n.b. we *must* increment and
        // then decrement the stack height even though we bumped the max before the call. in
        // some cases the stack may be larger after the method call than before e.g. calling
        // a static which returns a value or calling a non-static which returns a long/double

        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/jboss/byteman/rule/Rule", "disableTriggersInternal",
                "()Z");
        compileContext.addStackCount(1);
        mv.visitInsn(Opcodes.POP);
        compileContext.addStackCount(-1);
    } else {
        // if we are calling a method by reflection then we need to stack the current helper then
        // the recipient or null if there is none and then build an object array on the stack
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        compileContext.addStackCount(1);
        if (recipient != null) {
            // compile code for recipient
            recipient.compile(mv, compileContext);
        } else {
            mv.visitInsn(Opcodes.ACONST_NULL);
            compileContext.addStackCount(1);
        }

        // stack arg count then create a new array
        mv.visitLdcInsn(argCount);
        compileContext.addStackCount(1);
        // this just swaps one word for another
        mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");

        // duplicate the array, stack the index, compile code to generate the arg and the do an array put
        for (int i = 0; i < argCount; i++) {
            mv.visitInsn(Opcodes.DUP);
            mv.visitLdcInsn(i);
            // that was two extra words
            compileContext.addStackCount(2);
            Expression argument = arguments.get(i);
            Type argType = argumentTypes.get(i);
            Type paramType = paramTypes.get(i);
            // compile code to stack argument and type convert/box if necessary
            argument.compile(mv, compileContext);
            compileTypeConversion(argType, paramType, mv, compileContext);
            compileBox(paramType, mv, compileContext);
            // that's 3 extra words which now get removed
            mv.visitInsn(Opcodes.AASTORE);
            compileContext.addStackCount(-3);
        }
        // now stack the method object index
        mv.visitLdcInsn(methodIndex);
        compileContext.addStackCount(1);

        // enable triggering before we call the method
        // this adds an extra value to the stack so modify the compile context to ensure
        // we increase the maximum height if necessary
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/jboss/byteman/rule/Rule", "enableTriggersInternal",
                "()Z");
        compileContext.addStackCount(1);
        mv.visitInsn(Opcodes.POP);
        compileContext.addStackCount(-1);

        // ok, we  now have the recipient, args array and method index on the stack
        // so we can call the HelperAdapter method  to do the actual reflective invocation
        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.internalName(HelperAdapter.class),
                "invokeAccessibleMethod", "(Ljava/lang/Object;[Ljava/lang/Object;I)Ljava/lang/Object;");
        // we popped 4 words and left one in its place
        compileContext.addStackCount(-3);
        if (type == Type.VOID) {
            mv.visitInsn(Opcodes.POP);
            compileContext.addStackCount(-1);
        } else {
            // do any necessary casting and/or unboxing
            compileTypeConversion(Type.OBJECT, type, mv, compileContext);
        }

        // now disable triggering again
        // this temporarily adds an extra value to the stack -- n.b. no need to increment and
        // then decrement the stack height here because the previous enable call will already have
        // bumped the max when we had 4 slots on the stack and any return value on the stack will
        // occupy at most 2 slots

        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/jboss/byteman/rule/Rule", "disableTriggersInternal",
                "()Z");
        compileContext.addStackCount(1);
        mv.visitInsn(Opcodes.POP);
        compileContext.addStackCount(-1);
    }

    // ensure we have only increased the stack by the return value size
    if (compileContext.getStackCount() != currentStack + expected) {
        throw new CompileException("MethodExpression.compile : invalid stack height "
                + compileContext.getStackCount() + " expecting " + (currentStack + expected));
    }

    // no need to update max stack since compiling the  recipient or arguments will
    // have done so (and there will be no change if there was no such compile call)
}

From source file:org.jboss.byteman.rule.expression.StringPlusExpression.java

License:Open Source License

public void compile(MethodVisitor mv, CompileContext compileContext) throws CompileException {
    // make sure we are at the right source line
    compileContext.notifySourceLine(line);

    Expression oper0 = getOperand(0);
    Expression oper1 = getOperand(1);

    int currentStack = compileContext.getStackCount();
    int expected = 1;

    // compile and type convert each operand n.b. the type conversion will ensure that
    // null operands are replaced with "null"

    oper0.compile(mv, compileContext);//  ww  w.  ja  v  a2  s  .c o m
    compileTypeConversion(oper0.getType(), type, mv, compileContext);
    oper1.compile(mv, compileContext);
    compileTypeConversion(oper1.getType(), type, mv, compileContext);

    // ok, we could optimize this for the case where the left or right operand is a String plus expression
    // by employing a StringBuffer but for now we will just evaluate the left and right operand and
    // then call concat to join them
    // add two strings leaving one string

    // if second operand is null replace it with "null"
    Label skiptarget = new Label();
    // this adds a word then removes it -- do so to ensure the max height gets updated if need be
    mv.visitInsn(Opcodes.DUP);
    compileContext.addStackCount(1);
    // if it is not null we skip to the concat operation
    mv.visitJumpInsn(Opcodes.IFNONNULL, skiptarget);
    compileContext.addStackCount(-1);
    // it's null so we have to swap it fdr "null"
    mv.visitInsn(Opcodes.POP);
    mv.visitLdcInsn("null");
    mv.visitLabel(skiptarget);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "concat",
            "(Ljava/lang/String;)Ljava/lang/String;");

    compileContext.addStackCount(-1);

    if (compileContext.getStackCount() != currentStack + expected) {
        throw new CompileException("StringPlusExpression.compile : invalid stack height "
                + compileContext.getStackCount() + " expecting " + currentStack + expected);
    }
}

From source file:org.jboss.byteman.rule.expression.Variable.java

License:Open Source License

@Override
public void compileAssign(MethodVisitor mv, CompileContext compileContext) throws CompileException {
    // make sure we are at the right source line
    compileContext.notifySourceLine(line);

    int currentStack = compileContext.getStackCount();
    int size = ((type.getNBytes() > 4) ? 2 : 1);
    int max;// ww  w. j a v  a  2 s. c o  m

    // value to be assigned is TOS and will already be coerced to the correct value type
    // copy it so we leave it as a a return value on the stack
    if (size == 2) {
        // [... val1 val2 ==> ... val1 val2 val1 val2]
        mv.visitInsn(Opcodes.DUP2);
    } else {
        // [... val ==> ... val val]
        mv.visitInsn(Opcodes.DUP);
    }
    // stack the current helper then insert it below the value
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    if (size == 2) {
        // use a DUP_X2 to push a copy below the value then pop the redundant value
        // [... val1 val2 val1 val2 helper ==> ... val1 val2 helper val1 val2 helper]
        mv.visitInsn(Opcodes.DUP_X2);
        // [... val1 val2 helper val1 val2 helper ==> ... val1 val2 helper val1 val2]
        mv.visitInsn(Opcodes.POP);
    } else {
        // we can just swap the two values
        // [... val val helper ==> ... val helper val]
        mv.visitInsn(Opcodes.SWAP);
    }
    // stack the name for the variable and swap below the value
    mv.visitLdcInsn(name);
    if (size == 2) {
        // use a DUP_X2 to push a copy below the value then pop the redundant value
        // [... val1 val2 helper val1 val2 name ==> [... val1 val2 helper name val1 val2 name]
        mv.visitInsn(Opcodes.DUP_X2);
        // this is the high water mark
        compileContext.addStackCount(5);
        // [... val1 val2 helper name val1 val2 name ==> [... val1 val2 helper name val1 val2]
        mv.visitInsn(Opcodes.POP);
        compileContext.addStackCount(-1);
        // and now we have the desired arrangement for the call[.. val1 val2 helper name val1 val2]
    } else {
        // this is the high water mark
        // at this point the stack has gone from [ .. val]  to [.. val helper val name]
        compileContext.addStackCount(3);
        // we can just swap the two values
        // [... val helper val name ==> ... val helper name val]
        mv.visitInsn(Opcodes.SWAP);
        // and now we have the desired arrangement for the call[.. val helper name val]
    }

    // ensure we have an object
    compileObjectConversion(type, Type.OBJECT, mv, compileContext);

    // call the setBinding method
    mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.internalName(HelperAdapter.class), "setBinding",
            "(Ljava/lang/String;Ljava/lang/Object;)V");

    // the call will remove 3 from the stack height
    compileContext.addStackCount(-3);

    // ok, the stack height should be as it was
    if (compileContext.getStackCount() != currentStack) {
        throw new CompileException("variable.compileAssignment : invalid stack height "
                + compileContext.getStackCount() + " expecting " + currentStack);
    }
}

From source file:org.jboss.byteman.rule.RuleElement.java

License:Open Source License

protected void compileStringConversion(Type fromType, Type toType, MethodVisitor mv,
        CompileContext compileContext) throws CompileException {
    assert toType == Type.STRING;
    if (fromType.isObject() || fromType.isArray() || (fromType.isNumeric() && !fromType.isPrimitive())) {
        // use the toString method if the object is non null otherwise just replace it with null
        Label elseLabel = new Label();
        Label endLabel = new Label();
        // if (object == null)
        mv.visitInsn(Opcodes.DUP);/*from  w ww .j  a v  a 2s  .c om*/
        // the above dup bumps the stack height
        compileContext.addStackCount(1);
        mv.visitJumpInsn(Opcodes.IFNONNULL, elseLabel);
        compileContext.addStackCount(-1);
        // then string = "null"
        mv.visitInsn(Opcodes.POP);
        mv.visitInsn(Opcodes.ACONST_NULL);
        mv.visitJumpInsn(Opcodes.GOTO, endLabel);
        // else string = object.toString()
        mv.visitLabel(elseLabel);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;");
        mv.visitLabel(endLabel);
    } else if (fromType == Type.Z) {
        // use the toString method
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "toString", "(Z)Ljava/lang/String;");
    } else if (fromType == Type.B) {
        // use the toString method
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "toString", "(B)Ljava/lang/String;");
    } else if (fromType == Type.S) {
        // use the toString method
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "toString", "(S)Ljava/lang/String;");
    } else if (fromType == Type.C) {
        // use the toString method
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Character", "toString", "(C)Ljava/lang/String;");
    } else if (fromType == Type.I) {
        // use the toString method
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "toString", "(I)Ljava/lang/String;");
    } else if (fromType == Type.J) {
        // use the toString method
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "toString", "(J)Ljava/lang/String;");
        compileContext.addStackCount(-1);
    } else if (fromType == Type.F) {
        // use the toString method
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Float", "toString", "(F)Ljava/lang/String;");
    } else if (fromType == Type.D) {
        // use the toString method
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Double", "toString", "(D)Ljava/lang/String;");
        compileContext.addStackCount(-1);
    }
}

From source file:org.kantega.notsoserial.CreateBytesIT.java

License:Apache License

private byte[] createTransletBytes() {

    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "com/example/InvokingTranslet", null,
            Type.getType(AbstractTranslet.class).getInternalName(),
            new String[] { Type.getType(Serializable.class).getInternalName() });

    MethodVisitor init = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
    init.visitCode();// w w  w .j  a  v a2s.com
    init.visitVarInsn(Opcodes.ALOAD, 0);
    init.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getType(AbstractTranslet.class).getInternalName(),
            "<init>", "()V");
    init.visitVarInsn(Opcodes.ALOAD, 0);
    init.visitIntInsn(Opcodes.BIPUSH, 101);
    init.visitFieldInsn(Opcodes.PUTFIELD, Type.getType(AbstractTranslet.class).getInternalName(),
            "transletVersion", "I");
    init.visitInsn(Opcodes.RETURN);
    init.visitMaxs(2, 2);
    init.visitEnd();

    MethodVisitor transformMethod = cw.visitMethod(Opcodes.ACC_PUBLIC, "transform",
            Type.getMethodDescriptor(Type.VOID_TYPE,
                    new Type[] { Type.getType(DOM.class), Type.getType(DTMAxisIterator.class) }),
            null, new String[] { Type.getType(TransletException.class).getInternalName() });

    transformMethod.visitCode();
    transformMethod.visitInsn(Opcodes.RETURN);
    transformMethod.visitEnd();

    MethodVisitor mv = cw.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null);
    mv.visitCode();
    mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
    mv.visitLdcInsn("HMM..");
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
    mv.visitLdcInsn("pwned");
    mv.visitLdcInsn("true");
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/System", "setProperty",
            "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
    mv.visitInsn(Opcodes.POP);
    mv.visitInsn(Opcodes.RETURN);
    mv.visitMaxs(2, 0);
    mv.visitEnd();
    cw.visitEnd();

    return cw.toByteArray();
}

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}).//from   w  w w .  jav  a2s. c om
 * 
 * @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.mbte.groovypp.compiler.bytecode.BytecodeExpr.java

License:Apache License

public void swapObjectWith(ClassNode type, MethodVisitor mv) {
    if (type == long_TYPE || type == double_TYPE) {
        mv.visitInsn(Opcodes.DUP_X2);//  w ww  .  j a  v  a  2 s .  com
        mv.visitInsn(Opcodes.POP);
    } else {
        mv.visitInsn(Opcodes.SWAP);
    }
}

From source file:org.mbte.groovypp.compiler.bytecode.BytecodeExpr.java

License:Apache License

/**
 * load a message on the stack and remove it right away. Good for put a mark in the generated bytecode for debugging purpose.
 *
 * @param msg// w  ww.  j ava2  s.c  o m
 * @param mv
 */
public void mark(String msg, MethodVisitor mv) {
    mv.visitLdcInsn(msg);
    mv.visitInsn(Opcodes.POP);
}