Search in sources :

Example 71 with MethodVisitor

use of org.objectweb.asm.MethodVisitor in project groovy by apache.

the class MopWriter method generateMopCalls.

/**
     * generates a Meta Object Protocol method, that is used to call a non public
     * method, or to make a call to super.
     *
     * @param mopCalls list of methods a mop call method should be generated for
     * @param useThis  true if "this" should be used for the naming
     */
protected void generateMopCalls(LinkedList<MethodNode> mopCalls, boolean useThis) {
    for (MethodNode method : mopCalls) {
        String name = getMopMethodName(method, useThis);
        Parameter[] parameters = method.getParameters();
        String methodDescriptor = BytecodeHelper.getMethodDescriptor(method.getReturnType(), method.getParameters());
        MethodVisitor mv = controller.getClassVisitor().visitMethod(ACC_PUBLIC | ACC_SYNTHETIC, name, methodDescriptor, null, null);
        controller.setMethodVisitor(mv);
        mv.visitVarInsn(ALOAD, 0);
        int newRegister = 1;
        OperandStack operandStack = controller.getOperandStack();
        for (Parameter parameter : parameters) {
            ClassNode type = parameter.getType();
            operandStack.load(parameter.getType(), newRegister);
            // increment to next register, double/long are using two places
            newRegister++;
            if (type == ClassHelper.double_TYPE || type == ClassHelper.long_TYPE)
                newRegister++;
        }
        operandStack.remove(parameters.length);
        ClassNode declaringClass = method.getDeclaringClass();
        // JDK 8 support for default methods in interfaces
        // this should probably be strenghtened when we support the A.super.foo() syntax
        int opcode = declaringClass.isInterface() ? INVOKEINTERFACE : INVOKESPECIAL;
        mv.visitMethodInsn(opcode, BytecodeHelper.getClassInternalName(declaringClass), method.getName(), methodDescriptor, opcode == INVOKEINTERFACE);
        BytecodeHelper.doReturn(mv, method.getReturnType());
        mv.visitMaxs(0, 0);
        mv.visitEnd();
        controller.getClassNode().addMethod(name, ACC_PUBLIC | ACC_SYNTHETIC, method.getReturnType(), parameters, null, null);
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) MethodNode(org.codehaus.groovy.ast.MethodNode) Parameter(org.codehaus.groovy.ast.Parameter) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 72 with MethodVisitor

use of org.objectweb.asm.MethodVisitor in project groovy by apache.

the class OperandStack method popDownTo.

public void popDownTo(int elements) {
    int last = stack.size();
    MethodVisitor mv = controller.getMethodVisitor();
    while (last > elements) {
        last--;
        ClassNode element = popWithMessage(last);
        if (isTwoSlotType(element)) {
            mv.visitInsn(POP2);
        } else {
            mv.visitInsn(POP);
        }
    }
}
Also used : MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 73 with MethodVisitor

use of org.objectweb.asm.MethodVisitor in project groovy by apache.

the class OperandStack method storeVar.

public void storeVar(BytecodeVariable variable) {
    MethodVisitor mv = controller.getMethodVisitor();
    int idx = variable.getIndex();
    ClassNode type = variable.getType();
    // value is on stack
    if (variable.isHolder()) {
        doGroovyCast(type);
        box();
        mv.visitVarInsn(ALOAD, idx);
        mv.visitTypeInsn(CHECKCAST, "groovy/lang/Reference");
        mv.visitInsn(SWAP);
        mv.visitMethodInsn(INVOKEVIRTUAL, "groovy/lang/Reference", "set", "(Ljava/lang/Object;)V", false);
    } else {
        doGroovyCast(type);
        if (type == ClassHelper.double_TYPE) {
            mv.visitVarInsn(DSTORE, idx);
        } else if (type == ClassHelper.float_TYPE) {
            mv.visitVarInsn(FSTORE, idx);
        } else if (type == ClassHelper.long_TYPE) {
            mv.visitVarInsn(LSTORE, idx);
        } else if (type == ClassHelper.boolean_TYPE || type == ClassHelper.char_TYPE || type == ClassHelper.byte_TYPE || type == ClassHelper.int_TYPE || type == ClassHelper.short_TYPE) {
            mv.visitVarInsn(ISTORE, idx);
        } else {
            mv.visitVarInsn(ASTORE, idx);
        }
    }
    // remove RHS value from operand stack
    remove(1);
}
Also used : MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 74 with MethodVisitor

use of org.objectweb.asm.MethodVisitor in project groovy by apache.

the class OperandStack method box.

public ClassNode box() {
    MethodVisitor mv = controller.getMethodVisitor();
    int size = stack.size();
    ClassNode type = stack.get(size - 1);
    if (ClassHelper.isPrimitiveType(type) && ClassHelper.VOID_TYPE != type) {
        ClassNode wrapper = ClassHelper.getWrapper(type);
        BytecodeHelper.doCastToWrappedType(mv, type, wrapper);
        type = wrapper;
    }
    // else nothing to box
    stack.set(size - 1, type);
    return type;
}
Also used : MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 75 with MethodVisitor

use of org.objectweb.asm.MethodVisitor in project groovy by apache.

the class OperandStack method pushConstant.

/**
     * load the constant on the operand stack. 
     */
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) {
        String className = BytecodeHelper.getClassInternalName(value.getClass().getName());
        mv.visitTypeInsn(NEW, className);
        mv.visitInsn(DUP);
        mv.visitLdcInsn(value.toString());
        mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", "(Ljava/lang/String;)V", false);
    } else if (value instanceof BigInteger) {
        String className = BytecodeHelper.getClassInternalName(value.getClass().getName());
        mv.visitTypeInsn(NEW, className);
        mv.visitInsn(DUP);
        mv.visitLdcInsn(value.toString());
        mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", "(Ljava/lang/String;)V", false);
    } 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();
}
Also used : BigInteger(java.math.BigInteger) ClassGeneratorException(org.codehaus.groovy.classgen.ClassGeneratorException) BigDecimal(java.math.BigDecimal) MethodVisitor(org.objectweb.asm.MethodVisitor)

Aggregations

MethodVisitor (org.objectweb.asm.MethodVisitor)630 Label (org.objectweb.asm.Label)186 ClassWriter (org.objectweb.asm.ClassWriter)116 Type (org.objectweb.asm.Type)59 ClassNode (org.codehaus.groovy.ast.ClassNode)57 FieldVisitor (org.objectweb.asm.FieldVisitor)56 ClassVisitor (org.objectweb.asm.ClassVisitor)47 ClassReader (org.objectweb.asm.ClassReader)43 ArrayList (java.util.ArrayList)32 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)30 Test (org.junit.Test)29 AnnotationVisitor (org.objectweb.asm.AnnotationVisitor)29 List (java.util.List)23 LinkedList (java.util.LinkedList)22 Parameter (org.codehaus.groovy.ast.Parameter)22 InterfaceHelperClassNode (org.codehaus.groovy.ast.InterfaceHelperClassNode)18 AsmClassGenerator (org.codehaus.groovy.classgen.AsmClassGenerator)18 BytecodeExpression (org.codehaus.groovy.classgen.BytecodeExpression)18 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)17 Method (java.lang.reflect.Method)16