Example usage for org.objectweb.asm MethodVisitor visitLdcInsn

List of usage examples for org.objectweb.asm MethodVisitor visitLdcInsn

Introduction

In this page you can find the example usage for org.objectweb.asm MethodVisitor visitLdcInsn.

Prototype

public void visitLdcInsn(final Object value) 

Source Link

Document

Visits a LDC instruction.

Usage

From source file:org.codehaus.groovy.classgen.asm.CallSiteWriter.java

License:Apache License

public void prepareCallSite(String message) {
    MethodVisitor mv = controller.getMethodVisitor();
    if (controller.isNotClinit()) {
        mv.visitVarInsn(ALOAD, callSiteArrayVarIndex);
    } else {//from  w  w w. j ava  2 s .  c o  m
        mv.visitMethodInsn(INVOKESTATIC, controller.getClassName(), GET_CALLSITE_METHOD, GET_CALLSITE_DESC,
                false);
    }
    final int index = allocateIndex(message);
    mv.visitLdcInsn(index);
    mv.visitInsn(AALOAD);
}

From source file:org.codehaus.groovy.classgen.asm.CompileStack.java

License:Apache License

private static void pushInitValue(ClassNode type, MethodVisitor mv) {
    if (ClassHelper.isPrimitiveType(type)) {
        if (type == ClassHelper.long_TYPE) {
            mv.visitInsn(LCONST_0);//from   w  ww. ja v a 2 s. c o  m
        } else if (type == ClassHelper.double_TYPE) {
            mv.visitInsn(DCONST_0);
        } else if (type == ClassHelper.float_TYPE) {
            mv.visitInsn(FCONST_0);
        } else {
            mv.visitLdcInsn(0);
        }
    } else {
        mv.visitInsn(ACONST_NULL);
    }
}

From source file:org.codehaus.groovy.classgen.asm.InvocationWriter.java

License:Apache License

private void makeMOPBasedConstructorCall(final List<ConstructorNode> constructors,
        final ConstructorCallExpression call, final ClassNode callNode) {
    MethodVisitor mv = controller.getMethodVisitor();
    OperandStack operandStack = controller.getOperandStack();
    call.getArguments().visit(controller.getAcg());
    // keep Object[] on stack
    mv.visitInsn(DUP);/*from   w  w w.ja v a  2  s. co m*/
    // to select the constructor we need also the number of
    // available constructors and the class we want to make
    // the call on
    BytecodeHelper.pushConstant(mv, -1);
    controller.getAcg().visitClassExpression(new ClassExpression(callNode));
    operandStack.remove(1);
    // removes one Object[] leaves the int containing the
    // call flags and the constructor number
    selectConstructorAndTransformArguments.call(mv);
    //load "this"
    if (controller.isConstructor()) {
        mv.visitVarInsn(ALOAD, 0);
    } else {
        mv.visitTypeInsn(NEW, BytecodeHelper.getClassInternalName(callNode));
    }
    mv.visitInsn(SWAP);
    TreeMap<Integer, ConstructorNode> sortedConstructors = new TreeMap<>();
    for (ConstructorNode constructor : constructors) {
        String typeDescriptor = BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE,
                constructor.getParameters());
        int hash = BytecodeHelper.hashCode(typeDescriptor);
        ConstructorNode sameHashNode = sortedConstructors.put(hash, constructor);
        if (sameHashNode != null) {
            controller.getSourceUnit()
                    .addError(new SyntaxException(
                            "Unable to compile class " + controller.getClassNode().getName()
                                    + " due to hash collision in constructors",
                            call.getLineNumber(), call.getColumnNumber()));
        }
    }
    Label[] targets = new Label[constructors.size()];
    int[] indices = new int[constructors.size()];
    Iterator<Integer> hashIt = sortedConstructors.keySet().iterator();
    Iterator<ConstructorNode> constructorIt = sortedConstructors.values().iterator();
    for (int i = 0, n = targets.length; i < n; i += 1) {
        targets[i] = new Label();
        indices[i] = hashIt.next();
    }

    // create switch targets
    Label defaultLabel = new Label();
    Label afterSwitch = new Label();
    mv.visitLookupSwitchInsn(defaultLabel, indices, targets);
    for (Label target : targets) {
        mv.visitLabel(target);
        // to keep the stack height, we need to leave
        // one Object[] on the stack as last element. At the
        // same time, we need the Object[] on top of the stack
        // to extract the parameters.
        if (controller.isConstructor()) {
            // in this case we need one "this", so a SWAP will exchange
            // "this" and Object[], a DUP_X1 will then copy the Object[]
            /// to the last place in the stack:
            //     Object[],this -SWAP-> this,Object[]
            //     this,Object[] -DUP_X1-> Object[],this,Object[]
            mv.visitInsn(SWAP);
            mv.visitInsn(DUP_X1);
        } else {
            // in this case we need two "this" in between and the Object[]
            // at the bottom of the stack as well as on top for our invokeSpecial
            // So we do DUP_X1, DUP2_X1, POP
            //     Object[],this -DUP_X1-> this,Object[],this
            //     this,Object[],this -DUP2_X1-> Object[],this,this,Object[],this
            //     Object[],this,this,Object[],this -POP->  Object[],this,this,Object[]
            mv.visitInsn(DUP_X1);
            mv.visitInsn(DUP2_X1);
            mv.visitInsn(POP);
        }

        ConstructorNode cn = constructorIt.next();
        String descriptor = BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, cn.getParameters());

        // unwrap the Object[] and make transformations if needed
        // that means, to duplicate the Object[], make a cast with possible
        // unboxing and then swap it with the Object[] for each parameter
        // vargs need special attention and transformation though
        Parameter[] parameters = cn.getParameters();
        int lengthWithoutVargs = parameters.length;
        if (parameters.length > 0 && parameters[parameters.length - 1].getType().isArray()) {
            lengthWithoutVargs -= 1;
        }
        for (int p = 0; p < lengthWithoutVargs; p += 1) {
            loadAndCastElement(operandStack, mv, parameters, p);
        }
        if (parameters.length > lengthWithoutVargs) {
            ClassNode type = parameters[lengthWithoutVargs].getType();
            BytecodeHelper.pushConstant(mv, lengthWithoutVargs);
            controller.getAcg().visitClassExpression(new ClassExpression(type));
            operandStack.remove(1);
            castToVargsArray.call(mv);
            BytecodeHelper.doCast(mv, type);
        } else {
            // at the end we remove the Object[]
            // the vargs case simply the last swap so no pop is needed
            mv.visitInsn(POP);
        }
        // make the constructor call
        mv.visitMethodInsn(INVOKESPECIAL, BytecodeHelper.getClassInternalName(callNode), "<init>", descriptor,
                false);
        mv.visitJumpInsn(GOTO, afterSwitch);
    }
    mv.visitLabel(defaultLabel);
    // this part should never be reached!
    mv.visitTypeInsn(NEW, "java/lang/IllegalArgumentException");
    mv.visitInsn(DUP);
    mv.visitLdcInsn(
            "This class has been compiled with a super class which is binary incompatible with the current super class found on classpath. You should recompile this class with the new version.");
    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>", "(Ljava/lang/String;)V",
            false);
    mv.visitInsn(ATHROW);
    mv.visitLabel(afterSwitch);

    // For a special constructor call inside a constructor we don't need
    // any result object on the stack, for outside the constructor we do.
    // to keep the stack height for the able we kept one object as dummy
    // result on the stack, which we can remove now if inside a constructor.
    if (!controller.isConstructor()) {
        // in case we are not in a constructor we have an additional
        // object on the stack, the result of our constructor call
        // which we want to keep, so we swap with the dummy object and
        // do normal removal of it. In the end, the call result will be
        // on the stack then
        mv.visitInsn(SWAP);
        operandStack.push(callNode); // for call result
    }
    mv.visitInsn(POP);
}

From source file:org.codehaus.groovy.classgen.asm.OperandStack.java

License:Apache License

/**
 * load the constant on the operand stack. 
 *//*from   w ww.  j a  va  2  s . co  m*/
public void pushConstant(ConstantExpression expression) {
    MethodVisitor mv = controller.getMethodVisitor();
    Object value = expression.getValue();
    ClassNode origType = expression.getType().redirect();
    ClassNode type = ClassHelper.getUnwrapper(origType);
    boolean boxing = origType != type;
    boolean asPrimitive = boxing || ClassHelper.isPrimitiveType(type);

    if (value == null) {
        mv.visitInsn(ACONST_NULL);
    } else if (boxing && value instanceof Boolean) {
        // special path for boxed boolean
        Boolean bool = (Boolean) value;
        String text = bool ? "TRUE" : "FALSE";
        mv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", text, "Ljava/lang/Boolean;");
        boxing = false;
        type = origType;
    } else if (asPrimitive) {
        pushPrimitiveConstant(mv, value, type);
    } else if (value instanceof BigDecimal) {
        newInstance(mv, value);
    } else if (value instanceof BigInteger) {
        newInstance(mv, value);
    } else if (value instanceof String) {
        mv.visitLdcInsn(value);
    } else {
        throw new ClassGeneratorException(
                "Cannot generate bytecode for constant: " + value + " of type: " + type.getName());
    }

    push(type);
    if (boxing)
        box();
}

From source file:org.codehaus.groovy.classgen.asm.OperandStack.java

License:Apache License

private static void newInstance(MethodVisitor mv, Object value) {
    String className = BytecodeHelper.getClassInternalName(value.getClass().getName());
    mv.visitTypeInsn(NEW, className);/* www .  j  a v  a 2  s . c o m*/
    mv.visitInsn(DUP);
    mv.visitLdcInsn(value.toString());
    mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", "(Ljava/lang/String;)V", false);
}

From source file:org.codehaus.groovy.classgen.asm.OperandStack.java

License:Apache License

private static void pushPrimitiveConstant(final MethodVisitor mv, final Object value, final ClassNode type) {
    boolean isInt = ClassHelper.int_TYPE.equals(type);
    boolean isShort = ClassHelper.short_TYPE.equals(type);
    boolean isByte = ClassHelper.byte_TYPE.equals(type);
    boolean isChar = ClassHelper.char_TYPE.equals(type);
    if (isInt || isShort || isByte || isChar) {
        int val = isInt ? (Integer) value : isShort ? (Short) value : isChar ? (Character) value : (Byte) value;
        BytecodeHelper.pushConstant(mv, val);
    } else if (ClassHelper.long_TYPE.equals(type)) {
        if ((Long) value == 0L) {
            mv.visitInsn(LCONST_0);//from  ww w  . j a  v a  2 s .  co m
        } else if ((Long) value == 1L) {
            mv.visitInsn(LCONST_1);
        } else {
            mv.visitLdcInsn(value);
        }
    } else if (ClassHelper.float_TYPE.equals(type)) {
        if ((Float) value == 0f) {
            mv.visitInsn(FCONST_0);
        } else if ((Float) value == 1f) {
            mv.visitInsn(FCONST_1);
        } else if ((Float) value == 2f) {
            mv.visitInsn(FCONST_2);
        } else {
            mv.visitLdcInsn(value);
        }
    } else if (ClassHelper.double_TYPE.equals(type)) {
        if ((Double) value == 0d) {
            mv.visitInsn(DCONST_0);
        } else if ((Double) value == 1d) {
            mv.visitInsn(DCONST_1);
        } else {
            mv.visitLdcInsn(value);
        }
    } else if (ClassHelper.boolean_TYPE.equals(type)) {
        boolean b = (Boolean) value;
        if (b) {
            mv.visitInsn(ICONST_1);
        } else {
            mv.visitInsn(ICONST_0);
        }
    } else {
        mv.visitLdcInsn(value);
    }
}

From source file:org.codehaus.groovy.classgen.asm.OperandStack.java

License:Apache License

public void pushBool(boolean inclusive) {
    MethodVisitor mv = controller.getMethodVisitor();
    mv.visitLdcInsn(inclusive);
    push(ClassHelper.boolean_TYPE);
}

From source file:org.codehaus.groovy.classgen.asm.sc.StaticTypesCallSiteWriter.java

License:Apache License

private void writeMapDotProperty(final Expression receiver, final String propertyName, final MethodVisitor mv,
        final boolean safe) {
    receiver.visit(controller.getAcg()); // load receiver

    Label exit = new Label();
    if (safe) {/*from  ww  w . java  2s  .co  m*/
        Label doGet = new Label();
        mv.visitJumpInsn(IFNONNULL, doGet);
        controller.getOperandStack().remove(1);
        mv.visitInsn(ACONST_NULL);
        mv.visitJumpInsn(GOTO, exit);
        mv.visitLabel(doGet);
        receiver.visit(controller.getAcg());
    }

    mv.visitLdcInsn(propertyName); // load property name
    mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;", true);
    if (safe) {
        mv.visitLabel(exit);
    }
    controller.getOperandStack().replace(OBJECT_TYPE);
}

From source file:org.codehaus.groovy.classgen.asm.sc.StaticTypesUnaryExpressionHelper.java

License:Apache License

@Override
public void writeBitwiseNegate(final BitwiseNegationExpression expression) {
    expression.getExpression().visit(controller.getAcg());
    if (isPrimitiveOnTop()) {
        final ClassNode top = getTopOperand();
        if (top == int_TYPE || top == short_TYPE || top == byte_TYPE || top == char_TYPE || top == long_TYPE) {
            BytecodeExpression bytecodeExpression = new BytecodeExpression() {
                @Override//from  ww  w .j ava 2  s.co m
                public void visit(final MethodVisitor mv) {
                    if (long_TYPE == top) {
                        mv.visitLdcInsn(-1);
                        mv.visitInsn(LXOR);
                    } else {
                        mv.visitInsn(ICONST_M1);
                        mv.visitInsn(IXOR);
                        if (byte_TYPE == top) {
                            mv.visitInsn(I2B);
                        } else if (char_TYPE == top) {
                            mv.visitInsn(I2C);
                        } else if (short_TYPE == top) {
                            mv.visitInsn(I2S);
                        }
                    }
                }
            };
            bytecodeExpression.visit(controller.getAcg());
            controller.getOperandStack().remove(1);
            return;
        }
    }
    super.writeBitwiseNegate(EMPTY_BITWISE_NEGATE);
}

From source file:org.codehaus.groovy.classgen.AsmClassGenerator.java

License:Apache License

private void visitStdMethod(final MethodNode node, final boolean isConstructor, final Parameter[] parameters,
        final Statement code) {
    controller.getCompileStack().init(node.getVariableScope(), parameters);
    controller.getCallSiteWriter().makeSiteEntry();

    MethodVisitor mv = controller.getMethodVisitor();
    final ClassNode superClass = controller.getClassNode().getSuperClass();
    if (isConstructor && (code == null || !((ConstructorNode) node).firstStatementIsSpecialConstructorCall())) {
        boolean hasCallToSuper = false;
        if (code != null && controller.getClassNode() instanceof InnerClassNode) {
            // if the class not is an inner class node, there are chances that the call to super is already added
            // so we must ensure not to add it twice (see GROOVY-4471)
            if (code instanceof BlockStatement) {
                for (Statement statement : ((BlockStatement) code).getStatements()) {
                    if (statement instanceof ExpressionStatement) {
                        final Expression expression = ((ExpressionStatement) statement).getExpression();
                        if (expression instanceof ConstructorCallExpression) {
                            ConstructorCallExpression call = (ConstructorCallExpression) expression;
                            if (call.isSuperCall()) {
                                hasCallToSuper = true;
                                break;
                            }/*  www  .  j  a  v a 2 s  .c om*/
                        }
                    }
                }
            }
        }
        if (!hasCallToSuper) {
            // invokes the super class constructor
            mv.visitVarInsn(ALOAD, 0);
            mv.visitMethodInsn(INVOKESPECIAL, BytecodeHelper.getClassInternalName(superClass), "<init>", "()V",
                    false);
        }
    }

    // handle body
    super.visitConstructorOrMethod(node, isConstructor);

    controller.getCompileStack().clear();
    if (node.isVoidMethod()) {
        mv.visitInsn(RETURN);
    } else {
        // we make a dummy return for label ranges that reach here
        ClassNode type = node.getReturnType().redirect();
        if (ClassHelper.isPrimitiveType(type)) {
            mv.visitLdcInsn(0);
            controller.getOperandStack().push(ClassHelper.int_TYPE);
            controller.getOperandStack().doGroovyCast(type);
            BytecodeHelper.doReturn(mv, type);
            controller.getOperandStack().remove(1);
        } else {
            mv.visitInsn(ACONST_NULL);
            BytecodeHelper.doReturn(mv, type);
        }
    }
}