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.mbte.groovypp.compiler.bytecode.BytecodeExpr.java

License:Apache License

public static void dup(ClassNode type, MethodVisitor mv) {
    if (type == double_TYPE || type == long_TYPE)
        mv.visitInsn(Opcodes.DUP2);// w  ww . j  a  v  a 2  s  .co m
    else
        mv.visitInsn(Opcodes.DUP);
}

From source file:org.mbte.groovypp.compiler.ClosureUtil.java

License:Apache License

public static void instantiateClass(ClassNode type, CompilerTransformer compiler, Parameter[] constrParams,
        Expression superArgs, MethodVisitor mv) {
    TraitASTTransformFinal.improveAbstractMethods(type);
    type.getModule().addClass(type);//from w ww  .  j a  va 2 s .c  o  m

    final String classInternalName = BytecodeHelper.getClassInternalName(type);
    mv.visitTypeInsn(Opcodes.NEW, classInternalName);
    mv.visitInsn(Opcodes.DUP);

    final ConstructorNode constructorNode = type.getDeclaredConstructors().get(0);

    for (int i = 0; i != constrParams.length; i++) {
        String name = constrParams[i].getName();

        if ("this$0".equals(name)) {
            mv.visitVarInsn(Opcodes.ALOAD, 0);
        } else {
            final Register var = compiler.compileStack.getRegister(name, false);
            if (var != null) {
                FieldNode field = type.getDeclaredField(name);
                BytecodeExpr.load(field.getType(), var.getIndex(), mv);
                if (!constrParams[i].getType().equals(var.getType())
                        && !ClassHelper.isPrimitiveType(field.getType())) {
                    BytecodeExpr.checkCast(constrParams[i].getType(), mv);
                }
            } else {
                FieldNode field = compiler.methodNode.getDeclaringClass().getDeclaredField(name);
                mv.visitVarInsn(Opcodes.ALOAD, 0);
                if (field == null) // @Field
                    name = compiler.methodNode.getName() + "$" + name;
                mv.visitFieldInsn(Opcodes.GETFIELD,
                        BytecodeHelper.getClassInternalName(compiler.methodNode.getDeclaringClass()), name,
                        BytecodeHelper.getTypeDescription(constrParams[i].getType()));
            }
        }
    }

    if (superArgs != null) {
        final List<Expression> list = ((ArgumentListExpression) superArgs).getExpressions();
        for (int i = 0; i != list.size(); ++i)
            ((BytecodeExpr) list.get(i)).visit(mv);
    }

    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, classInternalName, "<init>",
            BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, constructorNode.getParameters()));
}

From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java

License:Open Source License

/**
 * Encode a method invocation that is wrapped in a synchronized block.
 *   See Sun bug id #4414101 for a discussion of this generated code.
 * //from  ww w.  j  av  a 2s  .  com
 * @param smi - the SynchronizedMethodInvocation object.
 * @param context - the context of the code generation.
 * @return - true if the SynchronizedMethodInvocation is terminating.
 * @throws JavaGenerationException
 */
private static boolean encodeSynchronizedMethodInvocation(JavaStatement.SynchronizedMethodInvocation smi,
        GenerationContext context) throws JavaGenerationException {

    MethodVisitor mv = context.getMethodVisitor();

    // Get the JavaExpression for the object to synchronize on and generate the bytecode. 
    JavaExpression objectToSynchOn = smi.getSynchronizingObject();
    encodeExpr(objectToSynchOn, context);

    // The object to synchronize on is now on the stack.  Duplicate it, 
    // move one to storage as a local variable, and to MONITORENTER on the other. 
    mv.visitInsn(Opcodes.DUP);

    int mutexIndex = context.addLocalVar("$mutex", JavaTypeName.OBJECT);
    mv.visitVarInsn(Opcodes.ASTORE, mutexIndex);

    mv.visitInsn(Opcodes.MONITORENTER);

    // We need to wrap the method invocation in a try/catch block so 
    // the monitor can be exited properly if the method invocation throws
    // an exception.
    Label tryCatchStart = new Label();
    mv.visitLabel(tryCatchStart);

    // Note: if this is generalized to handle any synchronized statement (for example, a synchronized block), 
    //   then the scope of entries in the exception table here will have to be modified to exclude return instructions.
    //   See encodeTryCatchStatement() for how to do this.
    //   Here, the only statement in the try block is a single expressionStatement, which has no return instructions, 
    //     so we don't have to worry about handling this case.

    // Get the method invocation and generate the corresponding bytecode.
    MethodInvocation methodInvocation = smi.getMethodInvocation();
    encodeExpr(methodInvocation, context);

    // Load the mutex object back onto the stack and do MonitorExit.
    mv.visitVarInsn(Opcodes.ALOAD, mutexIndex);
    mv.visitInsn(Opcodes.MONITOREXIT);

    // Label the end of the try block around the method invocation.
    Label tryEnd = new Label();
    mv.visitLabel(tryEnd);

    // At this point we want to code an instruction to jump past the exception handling
    // code.
    Label tryCatchEnd = new Label();
    mv.visitJumpInsn(Opcodes.GOTO, tryCatchEnd);

    // Label the start of the exception handling code.
    Label catchStart = new Label();
    mv.visitLabel(catchStart);

    // The exception is on the stack.  Store it as a local.
    int exceptionIndex = context.addLocalVar("exception", JavaTypeName.OBJECT);
    mv.visitVarInsn(Opcodes.ASTORE, exceptionIndex);

    // Retrieve the mutex object and do MONITOREXIT.
    mv.visitVarInsn(Opcodes.ALOAD, mutexIndex);
    mv.visitInsn(Opcodes.MONITOREXIT);

    // Label the end of the exception handling code that deals with the monitor.
    Label exceptionMonitorExitEnd = new Label();
    mv.visitLabel(exceptionMonitorExitEnd);

    // Retrieve the exception and throw it.
    mv.visitVarInsn(Opcodes.ALOAD, exceptionIndex);
    mv.visitInsn(Opcodes.ATHROW);

    // Vist the label to mark the end of the try/catch.
    mv.visitLabel(tryCatchEnd);

    // Set up the try/catch block to catch exceptions thrown by the method invocation
    // and handle exiting the monitor.
    mv.visitTryCatchBlock(tryCatchStart, tryEnd, catchStart, null);

    // Set up a try catch block so that if an exception is thrown by trying to exit 
    // the monitor in the case of an exception from the method invocation we will keep trying to 
    // exit the monitor.
    mv.visitTryCatchBlock(catchStart, exceptionMonitorExitEnd, catchStart, null);

    return false;
}

From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java

License:Open Source License

/**    
 * @param type/*from w ww  . j a va2s . co m*/
 * @return the DUP or DUP2 instruction, depending on type.
 */
private static int getDupOpCode(JavaTypeName type) {

    switch (type.getTag()) {
    case JavaTypeName.BOOLEAN_TAG:
    case JavaTypeName.BYTE_TAG:
    case JavaTypeName.SHORT_TAG:
    case JavaTypeName.CHAR_TAG:
    case JavaTypeName.INT_TAG:
    case JavaTypeName.FLOAT_TAG:
    case JavaTypeName.ARRAY_TAG:
    case JavaTypeName.OBJECT_TAG:
        return Opcodes.DUP;

    case JavaTypeName.LONG_TAG:
    case JavaTypeName.DOUBLE_TAG:
        return Opcodes.DUP2;

    case JavaTypeName.VOID_TAG:
    default: {
        throw new IllegalArgumentException("invalid type: " + type);
    }
    }
}

From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java

License:Open Source License

/**
 * Encodes the Java code for a given Java operator expression.
 *   //from ww  w.  j av a 2  s .  co m
 * @param operatorExpr the java operator expression  
 * @param context
 * @return JavaTypeName
 * @throws JavaGenerationException
 */
private static JavaTypeName encodeOperatorExpr(JavaExpression.OperatorExpression operatorExpr,
        GenerationContext context) throws JavaGenerationException {

    MethodVisitor mv = context.getMethodVisitor();

    JavaOperator operator = operatorExpr.getJavaOperator();
    String symbol = operator.getSymbol();
    JavaTypeName valueType = operator.getValueType();

    // Now carry out the operation according to its type.
    if (operator.isArithmeticOp()) {

        // Add the instructions to evaluate the first argument.
        JavaTypeName arg1Type = encodeExpr(operatorExpr.getArgument(0), context);

        if (operatorExpr instanceof OperatorExpression.Unary) {

            if (symbol.equals("-")) { // number negation

                mv.visitInsn(getNegateOpCode(arg1Type));
                return arg1Type;
            }

            throw new JavaGenerationException("Unknown unary arithmetic operator " + symbol + ".");
        }

        // Add an instruction to widen the argument if necessary.
        int wideningOpCode = getWideningOpCode(arg1Type, valueType);
        if (wideningOpCode != Opcodes.NOP) {
            mv.visitInsn(wideningOpCode);
        }

        // Add the instructions to evaluate the second argument.
        JavaTypeName arg2Type = encodeExpr(operatorExpr.getArgument(1), context);

        // Add an instruction to widen the argument if necessary.
        wideningOpCode = getWideningOpCode(arg2Type, valueType);
        if (wideningOpCode != Opcodes.NOP) {
            mv.visitInsn(wideningOpCode);
        }

        // Evaluate.
        mv.visitInsn(getArithmeticBinaryOpCode(symbol, valueType));

        return valueType;
    }

    if (operator.isBitOp()) {
        // Add the instructions to evaluate the first argument.
        JavaTypeName arg1Type = encodeExpr(operatorExpr.getArgument(0), context);

        // Add an instruction to widen the argument if necessary.
        int wideningOpCode = getWideningOpCode(arg1Type, valueType);
        if (wideningOpCode != Opcodes.NOP) {
            mv.visitInsn(wideningOpCode);
        }

        if (operatorExpr instanceof OperatorExpression.Unary) {
            if (symbol.equals("~")) { // number negation
                if (valueType == JavaTypeName.INT) {
                    mv.visitInsn(Opcodes.ICONST_M1);
                    mv.visitInsn(Opcodes.IXOR);
                    return valueType;
                } else if (valueType == JavaTypeName.LONG) {
                    encodePushLongValue(new Long(-1), context);
                    mv.visitInsn(Opcodes.LXOR);
                    return valueType;
                }
            }

            throw new JavaGenerationException("Unknown unary arithmetic operator " + symbol + ".");
        }

        // Add the instructions to evaluate the second argument.
        JavaTypeName arg2Type = encodeExpr(operatorExpr.getArgument(1), context);

        // If this is >>, >>>, or << we may need to narrow the second argument to an int
        if (symbol.equals(">>") || symbol.equals(">>>") || symbol.equals("<<")) {
            if (arg2Type == JavaTypeName.LONG) {
                mv.visitInsn(Opcodes.L2I);
            }
        } else {
            // Add an instruction to widen the argument if necessary.
            wideningOpCode = getWideningOpCode(arg2Type, valueType);
            if (wideningOpCode != Opcodes.NOP) {
                mv.visitInsn(wideningOpCode);
            }
        }

        // Evaluate.
        mv.visitInsn(getArithmeticBinaryOpCode(symbol, valueType));

        return valueType;

    }

    if (operator.isLogicalOp() || operator.isRelationalOp()) {

        // Logical op:    {"!", "&&", "||"}
        // Relational op: {">", ">=", "<", "<=", "==", "!="}

        Label trueContinuation = new Label();
        Label falseContinuation = new Label();

        encodeBooleanValuedOperatorHelper(operatorExpr, context, trueContinuation, falseContinuation);
        return encodeThenTrueElseFalse(trueContinuation, falseContinuation, context);
    }

    if (operator == JavaOperator.STRING_CONCATENATION) {

        // Create an uninitialized StringBuilder, duplicate the reference (so we can invoke the initializer).
        mv.visitTypeInsn(Opcodes.NEW, "java/lang/StringBuilder");
        mv.visitInsn(Opcodes.DUP);

        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V");

        // append the first arg.
        JavaTypeName firstArgType = encodeExpr(operatorExpr.getArgument(0), context);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
                getAppendJVMDescriptor(firstArgType));

        // Append the results of evaluation of the second arg.
        // Note that, conveniently, StringBuilder has an append() method for all the different types.
        JavaTypeName secondArgType = encodeExpr(operatorExpr.getArgument(1), context);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
                getAppendJVMDescriptor(secondArgType));

        // Call toString() on the result.           
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString",
                "()Ljava/lang/String;");

        return JavaTypeName.STRING;
    }

    return encodeTernaryOperatorExpr((OperatorExpression.Ternary) operatorExpr, context);
}

From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java

License:Open Source License

/**
 * Creates and initializes a 1-dimensional array (as specified by arrayCreationExpr) and then pushes a reference
 * to the array onto the stack./*from  w w  w  .j  a  va 2 s .  co m*/
 * 
 * @param arrayCreationExpr
 * @param context
 * @return JavaTypeName the type of the result on the operand stack. 
 * @throws JavaGenerationException
 */
private static JavaTypeName encodeArrayCreationExpr(JavaExpression.ArrayCreationExpression arrayCreationExpr,
        GenerationContext context) throws JavaGenerationException {

    MethodVisitor mv = context.getMethodVisitor();
    final int nArrayElements = arrayCreationExpr.getNElementValues();

    //push the n of elements of the array onto the stack.       
    encodePushIntValue(nArrayElements, context);

    JavaTypeName arrayElementType = arrayCreationExpr.getArrayElementTypeName();
    switch (arrayElementType.getTag()) {

    case JavaTypeName.VOID_TAG:
        throw new JavaGenerationException("Cannot have an array of with void element types.");

    case JavaTypeName.BOOLEAN_TAG:
    case JavaTypeName.BYTE_TAG:
    case JavaTypeName.SHORT_TAG:
    case JavaTypeName.CHAR_TAG:
    case JavaTypeName.INT_TAG:
    case JavaTypeName.LONG_TAG:
    case JavaTypeName.DOUBLE_TAG:
    case JavaTypeName.FLOAT_TAG: {
        //push the instruction to create a 1-dimensonal array of primitive values
        mv.visitIntInsn(Opcodes.NEWARRAY, getNewArrayArgCode(arrayElementType));
        break;
    }

    case JavaTypeName.ARRAY_TAG: {
        throw new JavaGenerationException(
                "JavaExpression.ArrayCreationExpression supports only 1 dimensional arrays.");
    }

    case JavaTypeName.OBJECT_TAG: {
        //push the instruction to create a 1-dimensonal array of reference values
        mv.visitTypeInsn(Opcodes.ANEWARRAY, arrayElementType.getJVMInternalName());
        break;
    }

    default: {
        throw new IllegalArgumentException();
    }
    }

    final int arrayElemStoreCode = getArrayStoreOpCode(arrayElementType);

    //now initialize the elements of the array
    for (int i = 0; i < nArrayElements; ++i) {
        //duplicate the array reference on the stack
        mv.visitInsn(Opcodes.DUP);

        //push i
        encodePushIntValue(i, context);

        //push the code to evalaute the ith element expression
        encodeExpr(arrayCreationExpr.getElementValue(i), context);

        //array[i] = elementExpr           
        mv.visitInsn(arrayElemStoreCode);
    }

    return arrayElementType.makeArrayType();
}

From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java

License:Open Source License

/**
 * Create the Java code for a given class instance creation expression. The new object reference will be pushed onto
 * the operand stack. /*from w  w w  .j  a va2  s.  co m*/
 * 
 * @param cice the class instance creation expression
 * @param context 
 * @return JavaTypeName    
 * @throws JavaGenerationException
 */
private static JavaTypeName encodeClassInstanceCreationExpr(
        final JavaExpression.ClassInstanceCreationExpression cice, final GenerationContext context)
        throws JavaGenerationException {

    final MethodVisitor mv = context.getMethodVisitor();
    final JavaTypeName classType = cice.getClassName();
    if (classType instanceof JavaTypeName.Reference.Array) {

        final JavaTypeName.Reference.Array arrayType = (JavaTypeName.Reference.Array) classType;
        final int nSizedDims = cice.getNArgs();
        if (nSizedDims == 1) {

            //for example, new String[10][][] will hit this case since it has 1 sized dimension (even though a multi-dimensional array is 
            //being created

            //push the size of the dimension
            encodeExpr(cice.getArg(0), context);

            final JavaTypeName arrayElementType = arrayType.getIncrementalElementType();
            switch (arrayElementType.getTag()) {

            case JavaTypeName.VOID_TAG:
                throw new JavaGenerationException("Cannot have an array of with void element types.");

            case JavaTypeName.BOOLEAN_TAG:
            case JavaTypeName.BYTE_TAG:
            case JavaTypeName.SHORT_TAG:
            case JavaTypeName.CHAR_TAG:
            case JavaTypeName.INT_TAG:
            case JavaTypeName.LONG_TAG:
            case JavaTypeName.DOUBLE_TAG:
            case JavaTypeName.FLOAT_TAG: {
                //push the instruction to create a 1-dimensonal array of primitive values
                mv.visitIntInsn(Opcodes.NEWARRAY, getNewArrayArgCode(arrayElementType));
                break;
            }

            case JavaTypeName.ARRAY_TAG:
            case JavaTypeName.OBJECT_TAG: {
                //push the instruction to create a 1-dimensonal array of reference values
                mv.visitTypeInsn(Opcodes.ANEWARRAY, arrayElementType.getJVMInternalName());
                break;
            }

            default: {
                throw new IllegalArgumentException();
            }
            }

            return arrayType;

        } else {
            //the case of multi-dimensional arrays where more than 1 sizing dimension is supplied.

            // push args onto the stack
            for (int i = 0; i < nSizedDims; i++) {
                encodeExpr(cice.getArg(i), context);
            }

            mv.visitMultiANewArrayInsn(arrayType.getJVMInternalName(), nSizedDims);

            return arrayType;
        }

    } else if (classType instanceof JavaTypeName.Reference.Object) {

        String internalClassName = classType.getJVMInternalName();

        // create uninitialized object, duplicate the ref.
        mv.visitTypeInsn(Opcodes.NEW, internalClassName);
        mv.visitInsn(Opcodes.DUP);

        // push args onto the stack
        for (int i = 0, nArgs = cice.getNArgs(); i < nArgs; i++) {
            encodeExpr(cice.getArg(i), context);
        }

        //descriptor for the constructor
        StringBuilder descriptor = new StringBuilder("(");
        for (int i = 0, nArgs = cice.getNArgs(); i < nArgs; ++i) {
            descriptor.append(cice.getParamType(i).getJVMDescriptor());
        }
        descriptor.append(")V");

        // initialize - consumes the args and the duplicate reference.
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, internalClassName, "<init>", descriptor.toString());

        return classType;

    } else {
        throw new JavaGenerationException("cannot create a new instance of a primitive type.");
    }
}

From source file:org.parboiled.compiler.notNullVerification.MyMethodAdapter.java

License:Apache License

@Override
public void visitInsn(int opcode) {
    if (opcode == Opcodes.ARETURN && myIsNotNull) {
        mv.visitInsn(Opcodes.DUP);
        if (myThrowLabel == null) {
            Label skipLabel = new Label();
            mv.visitJumpInsn(Opcodes.IFNONNULL, skipLabel);
            myThrowLabel = new Label();
            mv.visitLabel(myThrowLabel);
            generateThrow("java/lang/IllegalStateException",
                    "@NotNull method " + getFullMethodName() + " must not return null", skipLabel);
        } else {/*from   w  ww .j a v a 2s . co  m*/
            mv.visitJumpInsn(Opcodes.IFNULL, myThrowLabel);
        }
    }

    mv.visitInsn(opcode);
}

From source file:org.parboiled.compiler.notNullVerification.MyMethodAdapter.java

License:Apache License

private void generateThrow(String exceptionClass, String descr, Label end) {
    String exceptionParamClass = "(Ljava/lang/String;)V";
    mv.visitTypeInsn(Opcodes.NEW, exceptionClass);
    mv.visitInsn(Opcodes.DUP);
    mv.visitLdcInsn(descr);// w w  w  .  j ava2s.  co m
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, exceptionClass, NotNullVerifyingInstrumenter.CONSTRUCTOR_NAME,
            exceptionParamClass);
    mv.visitInsn(Opcodes.ATHROW);
    mv.visitLabel(end);

    instrumenter.myIsModification = true;
}

From source file:org.pitest.mutationtest.engine.gregor.mutators.experimental.extended.UOIMutator1.java

License:Apache License

@Override
public void visitVarInsn(int opcode, int var) {
    mv.visitVarInsn(opcode, var);

    switch (opcode) {
    case Opcodes.ILOAD:
        if (this.shouldMutate("Incremented (a++) integer local variable number " + var)) {
            mv.visitIincInsn(var, 1);
        }//from   w w  w . j  av a  2s .c  o m
        break;
    case Opcodes.FLOAD:
        if (this.shouldMutate("Incremented (a++) float local variable number " + var)) {
            mv.visitInsn(Opcodes.DUP);
            mv.visitInsn(Opcodes.FCONST_1);
            mv.visitInsn(Opcodes.FADD);
            mv.visitVarInsn(Opcodes.FSTORE, var);
        }
        break;
    case Opcodes.LLOAD:
        if (this.shouldMutate("Incremented (a++) long local variable number " + var)) {
            mv.visitInsn(Opcodes.DUP2);
            mv.visitInsn(Opcodes.LCONST_1);
            mv.visitInsn(Opcodes.LADD);
            mv.visitVarInsn(Opcodes.LSTORE, var);
        }
        break;
    case Opcodes.DLOAD:
        if (this.shouldMutate("Incremented (a++) double local variable number " + var)) {
            mv.visitInsn(Opcodes.DUP2);
            mv.visitInsn(Opcodes.DCONST_1);
            mv.visitInsn(Opcodes.DADD);
            mv.visitVarInsn(Opcodes.DSTORE, var);
        }
        break;

    default:
        break;
    }
}