Example usage for org.objectweb.asm Opcodes DUP

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

Introduction

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

Prototype

int DUP

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

Click Source Link

Usage

From source file:org.jboss.byteman.rule.expression.ReturnExpression.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);

    Type valueType = (returnValue == null ? Type.VOID : returnValue.getType());
    int currentStack = compileContext.getStackCount();
    int expected = 1;

    // ok, we need to create the EarlyReturnException instance and then
    // initialise it using the appropriate return value or null if no
    // return value is needed. strictly we should maybe delay the
    // new until after computing the return expression so we avoid a new
    // if the expression throws an error. but that means we end up doing
    // stack manipulations so lets do it the easy way.

    // create am EarlyReturnException -- adds 1 to stack
    String exceptionClassName = Type.internalName(EarlyReturnException.class);
    mv.visitTypeInsn(Opcodes.NEW, exceptionClassName);
    compileContext.addStackCount(1);/*from  ww  w  .  jav a2 s.  c  om*/
    // copy the exception so we can initialise it -- adds 1 to stack
    mv.visitInsn(Opcodes.DUP);
    compileContext.addStackCount(1);
    // stack a string constant to initialise the exception with -- adds 1 to stack
    mv.visitLdcInsn("return from " + rule.getName());
    compileContext.addStackCount(1);
    // stack any required return value or null -- adds 1 to stack but may use 2 slots
    if (returnValue != null) {
        returnValue.compile(mv, compileContext);
        // we may need to convert from the value type to the return type
        if (valueType != type) {
            compileTypeConversion(valueType, type, mv, compileContext);
        }
        if (type.isPrimitive()) {
            // we need an object not a primitive
            compileBox(Type.boxType(type), mv, compileContext);
        }
    } else {
        // just push null
        mv.visitInsn(Opcodes.ACONST_NULL);
        compileContext.addStackCount(1);
    }
    // construct the exception -- pops 3
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, exceptionClassName, "<init>",
            "(Ljava/lang/String;Ljava/lang/Object;)V");
    compileContext.addStackCount(-3);

    // check current stack and increment max stack if necessary
    if (compileContext.getStackCount() != currentStack + expected) {
        throw new CompileException("ReturnExpression.compile : invalid stack height "
                + compileContext.getStackCount() + " expecting " + (currentStack + expected));
    }

    // now insert the throw instruction and decrement the stack height accordingly

    mv.visitInsn(Opcodes.ATHROW);
    compileContext.addStackCount(-1);
}

From source file:org.jboss.byteman.rule.expression.StaticExpression.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);

    // copy the value so we leave a result
    // increases stack height by size words
    if (size == 1) {
        mv.visitInsn(Opcodes.DUP);
    } else {//from ww w. j  ava2s .c o m
        mv.visitInsn(Opcodes.DUP2);
    }
    compileContext.addStackCount(size);
    // compile a static field update

    if (isPublicField) {
        String ownerType = Type.internalName(field.getDeclaringClass());
        String fieldName = field.getName();
        String fieldType = Type.internalName(field.getType(), true);
        compileContext.addStackCount(-size);
        mv.visitFieldInsn(Opcodes.PUTSTATIC, ownerType, fieldName, fieldType);
    } else {
        // since this is a private field we need to do the update using reflection
        // box the value to an object if necessary
        // [.. val(s) val(s) ==> val(s) valObj]
        if (type.isPrimitive()) {
            compileBox(Type.boxType(type), mv, compileContext);
        }
        // stack the helper and then swap it so it goes under the value
        // [.. val(s) valObj ==> val(s) valObj helper ==> val(s) helper valObj]
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitInsn(Opcodes.SWAP);
        // stack a null owner then swap it so it goes under the value
        // [val(s) helper valObj ==> val(s) helper valObj null ==> val(s) helper null valObj]
        mv.visitInsn(Opcodes.ACONST_NULL);
        mv.visitInsn(Opcodes.SWAP);
        // now stack the field index
        // [.. val(s) helper null valObj ==> val(s) helper null valObj index ]
        mv.visitLdcInsn(fieldIndex);
        // we added three more words
        compileContext.addStackCount(3);
        // 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);
    }

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

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);/*from  www.j a  v a2  s .co  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.ThrowExpression.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 expected = 1;
    int extraParams = 0;

    // ok, we need to create the thrown exception instance and then
    // initialise it.

    // create the thrown exception instance -- adds 1 to stack
    String exceptionClassName = type.getInternalName();
    mv.visitTypeInsn(Opcodes.NEW, exceptionClassName);
    compileContext.addStackCount(1);/*from  ww w  .ja  va2s.c  o m*/
    // copy the exception so we can init it
    mv.visitInsn(Opcodes.DUP);
    compileContext.addStackCount(1);

    int argCount = arguments.size();

    // stack each of the arguments to the constructor
    for (int i = 0; i < argCount; i++) {
        Type argType = argumentTypes.get(i);
        Type paramType = paramTypes.get(i);
        int paramCount = (paramType.getNBytes() > 4 ? 2 : 1);

        // track extra storage used after type conversion
        extraParams += (paramCount);
        arguments.get(i).compile(mv, compileContext);
        compileTypeConversion(argType, paramType, mv, compileContext);
    }

    // construct the exception
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, exceptionClassName, "<init>", getDescriptor());

    // modify the stack height to account for the removed exception and params
    compileContext.addStackCount(-(extraParams + 1));

    if (compileContext.getStackCount() != currentStack + expected) {
        throw new CompileException("ThrowExpression.compile : invalid stack height "
                + compileContext.getStackCount() + " expecting " + (currentStack + expected));
    }
    // now create a ThrowException to wrap the user exception
    // create the thrown exception instance -- adds 1 to stack [UE] --> [UE, THE]
    exceptionClassName = "org/jboss/byteman/rule/exception/ThrowException";
    mv.visitTypeInsn(Opcodes.NEW, exceptionClassName);
    compileContext.addStackCount(1);
    // copy the ThrowException so we can init it [UE, THE] --> [THE, UE, THE]
    mv.visitInsn(Opcodes.DUP_X1);
    compileContext.addStackCount(1);
    // reverse the order of the top two words  [THE, UE, THE] --> [THE, THE, UE]
    mv.visitInsn(Opcodes.SWAP);
    // construct the exception [THE, THE, UE] --> [UE]
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, exceptionClassName, "<init>", "(Ljava/lang/Throwable;)V");
    // we should now have just the ThrowException on the stack
    compileContext.addStackCount(-2);
    if (compileContext.getStackCount() != currentStack + expected) {
        throw new CompileException("ThrowExpression.compile : invalid stack height "
                + compileContext.getStackCount() + " expecting " + (currentStack + expected));
    }

    // now throw the exception and decrement the stack height

    mv.visitInsn(Opcodes.ATHROW);
    compileContext.addStackCount(-1);
}

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;//from  w  w  w  . j a v a  2s.  c om

    // 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);
        // 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);/*from  ww  w . j a va 2s . co m*/
        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.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);
            }/*from w  w w.  j  av  a  2s. c o m*/
            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 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  .j av a  2s. 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.mbte.groovypp.compiler.bytecode.BytecodeExpr.java

License:Apache License

/**
 * box the primitive value on the stack//from  ww  w.  j  a va2  s .  co m
 *
 * @param type
 * @param mv
 */
public void quickBoxIfNecessary(ClassNode type, MethodVisitor mv) {
    String descr = getTypeDescription(type);
    if (type == boolean_TYPE) {
        boxBoolean(mv);
    } else if (isPrimitiveType(type) && type != VOID_TYPE) {
        ClassNode wrapper = TypeUtil.wrapSafely(type);
        String internName = getClassInternalName(wrapper);
        mv.visitTypeInsn(Opcodes.NEW, internName);
        mv.visitInsn(Opcodes.DUP);
        if (type == double_TYPE || type == long_TYPE) {
            mv.visitInsn(Opcodes.DUP2_X2);
            mv.visitInsn(Opcodes.POP2);
        } else {
            mv.visitInsn(Opcodes.DUP2_X1);
            mv.visitInsn(Opcodes.POP2);
        }
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, internName, "<init>", "(" + descr + ")V");
    }
}

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

License:Apache License

/**
 * load the constant on the operand stack. primitives auto-boxed.
 *///ww  w.ja va  2 s  .c  o  m
void loadConstant(Object value, MethodVisitor mv) {
    if (value == null) {
        mv.visitInsn(Opcodes.ACONST_NULL);
    } else if (value instanceof String) {
        mv.visitLdcInsn(value);
    } else if (value instanceof Character) {
        String className = "java/lang/Character";
        mv.visitTypeInsn(Opcodes.NEW, className);
        mv.visitInsn(Opcodes.DUP);
        mv.visitLdcInsn(value);
        String methodType = "(C)V";
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, className, "<init>", methodType);
    } else if (value instanceof Number) {
        /** todo it would be more efficient to generate class constants */
        Number n = (Number) value;
        String className = BytecodeHelper.getClassInternalName(value.getClass().getName());
        mv.visitTypeInsn(Opcodes.NEW, className);
        mv.visitInsn(Opcodes.DUP);
        String methodType;
        if (n instanceof Integer) {
            //pushConstant(n.intValue());
            mv.visitLdcInsn(n);
            methodType = "(I)V";
        } else if (n instanceof Double) {
            mv.visitLdcInsn(n);
            methodType = "(D)V";
        } else if (n instanceof Float) {
            mv.visitLdcInsn(n);
            methodType = "(F)V";
        } else if (n instanceof Long) {
            mv.visitLdcInsn(n);
            methodType = "(J)V";
        } else if (n instanceof BigDecimal) {
            mv.visitLdcInsn(n.toString());
            methodType = "(Ljava/lang/String;)V";
        } else if (n instanceof BigInteger) {
            mv.visitLdcInsn(n.toString());
            methodType = "(Ljava/lang/String;)V";
        } else if (n instanceof Short) {
            mv.visitLdcInsn(n);
            methodType = "(S)V";
        } else if (n instanceof Byte) {
            mv.visitLdcInsn(n);
            methodType = "(B)V";
        } else {
            throw new ClassGeneratorException("Cannot generate bytecode for constant: " + value + " of type: "
                    + value.getClass().getName() + ".  Numeric constant type not supported.");
        }
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, className, "<init>", methodType);
    } else if (value instanceof Boolean) {
        Boolean bool = (Boolean) value;
        String text = (bool.booleanValue()) ? "TRUE" : "FALSE";
        mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Boolean", text, "Ljava/lang/Boolean;");
    } else if (value instanceof Class) {
        Class vc = (Class) value;
        if (vc.getName().equals("java.lang.Void")) {
            // load nothing here for void
        } else {
            throw new ClassGeneratorException("Cannot generate bytecode for constant: " + value + " of type: "
                    + value.getClass().getName());
        }
    } else {
        throw new ClassGeneratorException(
                "Cannot generate bytecode for constant: " + value + " of type: " + value.getClass().getName());
    }
}