Example usage for org.objectweb.asm MethodVisitor visitCode

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

Introduction

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

Prototype

public void visitCode() 

Source Link

Document

Starts the visit of the method's code, if any (i.e.

Usage

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

License:Apache License

@Override
protected void visitConstructorOrMethod(final MethodNode node, final boolean isConstructor) {
    controller.resetLineNumber();/*from w  w  w . j a  v a 2 s.c  o  m*/
    Parameter[] parameters = node.getParameters();
    String methodType = BytecodeHelper.getMethodDescriptor(node.getReturnType(), parameters);
    String signature = BytecodeHelper.getGenericsMethodSignature(node);
    int modifiers = node.getModifiers();
    if (isVargs(node.getParameters()))
        modifiers |= ACC_VARARGS;
    MethodVisitor mv = classVisitor.visitMethod(modifiers, node.getName(), methodType, signature,
            buildExceptions(node.getExceptions()));
    controller.setMethodVisitor(mv);

    visitAnnotations(node, mv);
    for (int i = 0, n = parameters.length; i < n; i += 1) {
        visitParameterAnnotations(parameters[i], i, mv);
    }

    // add parameter names to the MethodVisitor (jdk8+ only)
    if (getCompileUnit().getConfig().getParameters()) {
        for (Parameter parameter : parameters) {
            // TODO: handle ACC_SYNTHETIC for enum method parameters?
            mv.visitParameter(parameter.getName(), 0);
        }
    }

    if (controller.getClassNode().isAnnotationDefinition() && !node.isStaticConstructor()) {
        visitAnnotationDefault(node, mv);
    } else if (!node.isAbstract()) {
        Statement code = node.getCode();
        mv.visitCode();
        // fast path for getter/setters etc.
        if (code instanceof BytecodeSequence && ((BytecodeSequence) code).getInstructions().size() == 1
                && ((BytecodeSequence) code).getInstructions().get(0) instanceof BytecodeInstruction) {
            ((BytecodeInstruction) ((BytecodeSequence) code).getInstructions().get(0)).visit(mv);
        } else {
            visitStdMethod(node, isConstructor, parameters, code);
        }
        try {
            mv.visitMaxs(0, 0);
        } catch (Exception e) {
            Writer writer = null;
            if (mv instanceof TraceMethodVisitor) {
                TraceMethodVisitor tracer = (TraceMethodVisitor) mv;
                writer = new StringBuilderWriter();
                PrintWriter p = new PrintWriter(writer);
                tracer.p.print(p);
                p.flush();
            }
            StringBuilder message = new StringBuilder(64);
            message.append("ASM reporting processing error for ");
            message.append(controller.getClassNode().toString()).append("#").append(node.getName());
            message.append(" with signature ").append(node.getTypeDescriptor());
            message.append(" in ").append(sourceFile).append(":").append(node.getLineNumber());
            if (writer != null) {
                message.append("\nLast known generated bytecode in last generated method or constructor:\n");
                message.append(writer);
            }
            throw new GroovyRuntimeException(message.toString(), e);
        }
    }
    mv.visitEnd();
}

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

License:Apache License

protected void createSyntheticStaticFields() {
    if (referencedClasses.isEmpty()) {
        return;/* w  w w  .  j  a v a2 s  .  c  o  m*/
    }
    MethodVisitor mv;
    for (Map.Entry<String, ClassNode> entry : referencedClasses.entrySet()) {
        String staticFieldName = entry.getKey();
        ClassNode cn = entry.getValue();
        // generate a field node
        FieldNode fn = controller.getClassNode().getDeclaredField(staticFieldName);
        if (fn != null) {
            boolean type = fn.getType().equals(ClassHelper.CLASS_Type);
            boolean modifiers = fn.getModifiers() == ACC_STATIC + ACC_SYNTHETIC;
            if (!type || !modifiers) {
                String text = "";
                if (!type)
                    text = " with wrong type: " + fn.getType() + " (java.lang.Class needed)";
                if (!modifiers)
                    text = " with wrong modifiers: " + fn.getModifiers() + " (" + (ACC_STATIC + ACC_SYNTHETIC)
                            + " needed)";
                throwException("tried to set a static synthetic field " + staticFieldName + " in "
                        + controller.getClassNode().getName()
                        + " for class resolving, but found already a node of that name " + text);
            }
        } else {
            classVisitor.visitField(ACC_PRIVATE + ACC_STATIC + ACC_SYNTHETIC, staticFieldName,
                    "Ljava/lang/Class;", null, null);
        }

        mv = classVisitor.visitMethod(ACC_PRIVATE + ACC_STATIC + ACC_SYNTHETIC, "$get$" + staticFieldName,
                "()Ljava/lang/Class;", null, null);
        mv.visitCode();
        mv.visitFieldInsn(GETSTATIC, controller.getInternalClassName(), staticFieldName, "Ljava/lang/Class;");
        mv.visitInsn(DUP);
        Label l0 = new Label();
        mv.visitJumpInsn(IFNONNULL, l0);
        mv.visitInsn(POP);
        mv.visitLdcInsn(BytecodeHelper.getClassLoadingTypeDescription(cn));
        mv.visitMethodInsn(INVOKESTATIC, controller.getInternalClassName(), "class$",
                "(Ljava/lang/String;)Ljava/lang/Class;", false);
        mv.visitInsn(DUP);
        mv.visitFieldInsn(PUTSTATIC, controller.getInternalClassName(), staticFieldName, "Ljava/lang/Class;");
        mv.visitLabel(l0);
        mv.visitInsn(ARETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }

    mv = classVisitor.visitMethod(ACC_STATIC + ACC_SYNTHETIC, "class$", "(Ljava/lang/String;)Ljava/lang/Class;",
            null, null);
    Label l0 = new Label();
    mv.visitLabel(l0);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKESTATIC, "java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;",
            false);
    Label l1 = new Label();
    mv.visitLabel(l1);
    mv.visitInsn(ARETURN);
    Label l2 = new Label();
    mv.visitLabel(l2);
    mv.visitVarInsn(ASTORE, 1);
    mv.visitTypeInsn(NEW, "java/lang/NoClassDefFoundError");
    mv.visitInsn(DUP);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/ClassNotFoundException", "getMessage", "()Ljava/lang/String;",
            false);
    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/NoClassDefFoundError", "<init>", "(Ljava/lang/String;)V",
            false);
    mv.visitInsn(ATHROW);
    mv.visitTryCatchBlock(l0, l2, l2, "java/lang/ClassNotFoundException"); // br using l2 as the 2nd param seems create the right table entry
    mv.visitMaxs(3, 2);
}

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

License:Apache License

@Override
public void visitListExpression(final ListExpression expression) {
    onLineNumber(expression, "ListExpression");

    int size = expression.getExpressions().size();
    boolean containsSpreadExpression = containsSpreadExpression(expression);
    boolean containsOnlyConstants = !containsSpreadExpression && containsOnlyConstants(expression);
    OperandStack operandStack = controller.getOperandStack();
    if (!containsSpreadExpression) {
        MethodVisitor mv = controller.getMethodVisitor();
        BytecodeHelper.pushConstant(mv, size);
        mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
        int maxInit = 1000;
        if (size < maxInit || !containsOnlyConstants) {
            for (int i = 0; i < size; i += 1) {
                mv.visitInsn(DUP);//www . j av  a 2 s .c o m
                BytecodeHelper.pushConstant(mv, i);
                expression.getExpression(i).visit(this);
                operandStack.box();
                mv.visitInsn(AASTORE);
            }
            controller.getOperandStack().remove(size);
        } else {
            List<Expression> expressions = expression.getExpressions();
            List<String> methods = new ArrayList<>();
            MethodVisitor oldMv = mv;
            int index = 0;
            while (index < size) {
                String methodName = "$createListEntry_" + controller.getNextHelperMethodIndex();
                methods.add(methodName);
                mv = controller.getClassVisitor().visitMethod(ACC_PRIVATE + ACC_STATIC + ACC_SYNTHETIC,
                        methodName, "([Ljava/lang/Object;)V", null, null);
                controller.setMethodVisitor(mv);
                mv.visitCode();
                int methodBlockSize = Math.min(size - index, maxInit);
                int methodBlockEnd = index + methodBlockSize;
                for (; index < methodBlockEnd; index += 1) {
                    mv.visitVarInsn(ALOAD, 0);
                    mv.visitLdcInsn(index);
                    expressions.get(index).visit(this);
                    operandStack.box();
                    mv.visitInsn(AASTORE);
                }
                operandStack.remove(methodBlockSize);
                mv.visitInsn(RETURN);
                mv.visitMaxs(0, 0);
                mv.visitEnd();
            }
            mv = oldMv;
            controller.setMethodVisitor(mv);
            for (String methodName : methods) {
                mv.visitInsn(DUP);
                mv.visitMethodInsn(INVOKESTATIC, controller.getInternalClassName(), methodName,
                        "([Ljava/lang/Object;)V", false);
            }
        }
    } else {
        despreadList(expression.getExpressions(), false);
    }
    createListMethod.call(controller.getMethodVisitor());
    operandStack.push(ClassHelper.LIST_TYPE);
}

From source file:org.codehaus.groovy.reflection.MethodHandleFactory.java

License:Apache License

private static void genConstructor(ClassWriter cw, final String superClass) {
    MethodVisitor mv;
    mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
    mv.visitCode();
    mv.visitVarInsn(Opcodes.ALOAD, 0);/*  w w w.j av  a2 s .c  om*/
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, superClass, "<init>", "()V");
    mv.visitInsn(Opcodes.RETURN);
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}

From source file:org.codehaus.groovy.reflection.MethodHandleFactory.java

License:Apache License

@Deprecated
public static void genInvokeXxxWithArray(ClassWriter cw, Method method) {
    MethodVisitor mv;
    mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "invoke",
            "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;", null, EXCEPTIONS);
    mv.visitCode();

    Class callClass = method.getDeclaringClass();
    boolean useInterface = callClass.isInterface();

    String type = BytecodeHelper.getClassInternalName(callClass.getName());
    String descriptor = BytecodeHelper.getMethodDescriptor(method.getReturnType(), method.getParameterTypes());

    // make call//from   w w  w.  ja  v a 2 s .c  om
    if (Modifier.isStatic(method.getModifiers())) {
        genLoadParameters(2, mv, method);
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, type, method.getName(), descriptor);
    } else {
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        BytecodeHelper.doCast(mv, callClass);
        genLoadParameters(2, mv, method);
        mv.visitMethodInsn((useInterface) ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL, type,
                method.getName(), descriptor);
    }

    BytecodeHelper.box(mv, method.getReturnType());
    if (method.getReturnType() == void.class) {
        mv.visitInsn(Opcodes.ACONST_NULL);
    }

    mv.visitInsn(Opcodes.ARETURN);
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}

From source file:org.codehaus.groovy.reflection.MethodHandleFactory.java

License:Apache License

private static void genInvokeWithFixedParams(ClassWriter cw, Method method) {
    MethodVisitor mv;
    final int pc = method.getParameterTypes().length;
    if (pc <= 4) {
        StringBuilder pdescb = new StringBuilder();
        for (int i = 0; i != pc; ++i)
            pdescb.append("Ljava/lang/Object;");

        String pdesc = pdescb.toString();

        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "invoke", "(Ljava/lang/Object;" + pdesc + ")Ljava/lang/Object;",
                null, EXCEPTIONS);/*from w  ww .j a  va2 s. c  om*/
        mv.visitCode();

        Class callClass = method.getDeclaringClass();
        boolean useInterface = callClass.isInterface();

        String type = BytecodeHelper.getClassInternalName(callClass.getName());
        String descriptor = BytecodeHelper.getMethodDescriptor(method.getReturnType(),
                method.getParameterTypes());

        // make call
        if (Modifier.isStatic(method.getModifiers())) {
            MethodHandleFactory.genLoadParametersDirect(2, mv, method);
            mv.visitMethodInsn(Opcodes.INVOKESTATIC, type, method.getName(), descriptor);
        } else {
            mv.visitVarInsn(Opcodes.ALOAD, 1);
            BytecodeHelper.doCast(mv, callClass);
            MethodHandleFactory.genLoadParametersDirect(2, mv, method);
            mv.visitMethodInsn((useInterface) ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL, type,
                    method.getName(), descriptor);
        }

        BytecodeHelper.box(mv, method.getReturnType());
        if (method.getReturnType() == void.class) {
            mv.visitInsn(Opcodes.ACONST_NULL);
        }

        mv.visitInsn(Opcodes.ARETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }
}

From source file:org.codehaus.groovy.reflection.MethodHandleFactory.java

License:Apache License

private static void genInvokeWithFixedPrimitiveParams(ClassWriter cw, Method method) {
    MethodVisitor mv;
    final Class<?>[] pt = method.getParameterTypes();
    final int pc = pt.length;
    if (pc > 0 && pc <= 3) {
        StringBuilder pdescb = new StringBuilder();
        boolean hasPrimitive = false;
        for (int i = 0; i != pc; ++i)
            if (pt[i].isPrimitive()) {
                hasPrimitive = true;/*www  .j  a v a  2s.  co  m*/
                pdescb.append(BytecodeHelper.getTypeDescription(pt[i]));
            } else
                pdescb.append("Ljava/lang/Object;");

        if (!hasPrimitive)
            return;

        String pdesc = pdescb.toString();

        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "invoke", "(Ljava/lang/Object;" + pdesc + ")Ljava/lang/Object;",
                null, EXCEPTIONS);
        mv.visitCode();

        Class callClass = method.getDeclaringClass();
        boolean useInterface = callClass.isInterface();

        String type = BytecodeHelper.getClassInternalName(callClass.getName());
        String descriptor = BytecodeHelper.getMethodDescriptor(method.getReturnType(),
                method.getParameterTypes());

        // make call
        if (Modifier.isStatic(method.getModifiers())) {
            MethodHandleFactory.genLoadParametersPrimitiveDirect(2, mv, method);
            mv.visitMethodInsn(Opcodes.INVOKESTATIC, type, method.getName(), descriptor);
        } else {
            mv.visitVarInsn(Opcodes.ALOAD, 1);
            BytecodeHelper.doCast(mv, callClass);
            MethodHandleFactory.genLoadParametersPrimitiveDirect(2, mv, method);
            mv.visitMethodInsn((useInterface) ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL, type,
                    method.getName(), descriptor);
        }

        BytecodeHelper.box(mv, method.getReturnType());
        if (method.getReturnType() == void.class) {
            mv.visitInsn(Opcodes.ACONST_NULL);
        }

        mv.visitInsn(Opcodes.ARETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }
}

From source file:org.codehaus.groovy.reflection.SunClassLoader.java

License:Apache License

private void loadMagic() {
    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    cw.visit(Opcodes.V1_4, Opcodes.ACC_PUBLIC, "sun/reflect/GroovyMagic", null, "sun/reflect/MagicAccessorImpl",
            null);/*from   w w  w.ja  v  a  2s.  c o m*/
    MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
    mv.visitCode();
    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKESPECIAL, "sun/reflect/MagicAccessorImpl", "<init>", "()V", false);
    mv.visitInsn(RETURN);
    mv.visitMaxs(0, 0);
    mv.visitEnd();
    cw.visitEnd();

    define(cw.toByteArray(), "sun.reflect.GroovyMagic");
}

From source file:org.codehaus.groovy.runtime.callsite.CallSiteGenerator.java

License:Apache License

private static MethodVisitor writeMethod(ClassWriter cw, String name, int argumentCount,
        final String superClass, CachedMethod cachedMethod, String receiverType, String parameterDescription,
        boolean useArray) {
    MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "call" + name,
            "(L" + receiverType + ";" + parameterDescription + ")Ljava/lang/Object;", null, null);
    mv.visitCode();

    final Label tryStart = new Label();
    mv.visitLabel(tryStart);/*from ww  w  .  j  a v a2  s .c  om*/

    // call for checking if method is still valid
    for (int i = 0; i < argumentCount; ++i)
        mv.visitVarInsn(Opcodes.ALOAD, i);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, superClass, "checkCall",
            "(Ljava/lang/Object;" + parameterDescription + ")Z", false);
    Label l0 = new Label();
    mv.visitJumpInsn(Opcodes.IFEQ, l0);

    // valid method branch

    Class callClass = cachedMethod.getDeclaringClass().getTheClass();
    boolean useInterface = callClass.isInterface();

    String type = BytecodeHelper.getClassInternalName(callClass.getName());
    String descriptor = BytecodeHelper.getMethodDescriptor(cachedMethod.getReturnType(),
            cachedMethod.getNativeParameterTypes());

    // prepare call
    int invokeMethodCode = Opcodes.INVOKEVIRTUAL;
    if (cachedMethod.isStatic()) {
        invokeMethodCode = Opcodes.INVOKESTATIC;
    } else {
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        BytecodeHelper.doCast(mv, callClass);
        if (useInterface)
            invokeMethodCode = Opcodes.INVOKEINTERFACE;
    }

    Class<?>[] parameters = cachedMethod.getPT();
    int size = parameters.length;
    for (int i = 0; i < size; i++) {
        if (useArray) {
            // unpack argument from Object[]
            mv.visitVarInsn(Opcodes.ALOAD, 2);
            BytecodeHelper.pushConstant(mv, i);
            mv.visitInsn(Opcodes.AALOAD);
        } else {
            mv.visitVarInsn(Opcodes.ALOAD, i + 2);
        }

        // cast argument to parameter class, inclusive unboxing
        // for methods with primitive types
        BytecodeHelper.doCast(mv, parameters[i]);
    }

    // make call
    mv.visitMethodInsn(invokeMethodCode, type, cachedMethod.getName(), descriptor, useInterface);

    // produce result
    BytecodeHelper.box(mv, cachedMethod.getReturnType());
    if (cachedMethod.getReturnType() == void.class) {
        mv.visitInsn(Opcodes.ACONST_NULL);
    }

    // return
    mv.visitInsn(Opcodes.ARETURN);

    // fall back after method change
    mv.visitLabel(l0);
    for (int i = 0; i < argumentCount; ++i)
        mv.visitVarInsn(Opcodes.ALOAD, i);
    if (!useArray) {
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/codehaus/groovy/runtime/ArrayUtil", "createArray",
                "(" + parameterDescription + ")[Ljava/lang/Object;", false);
    }
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/codehaus/groovy/runtime/callsite/CallSiteArray",
            "defaultCall" + name, "(Lorg/codehaus/groovy/runtime/callsite/CallSite;L" + receiverType
                    + ";[Ljava/lang/Object;)Ljava/lang/Object;",
            false);
    mv.visitInsn(Opcodes.ARETURN);

    // exception unwrapping for stackless exceptions
    final Label tryEnd = new Label();
    mv.visitLabel(tryEnd);
    final Label catchStart = new Label();
    mv.visitLabel(catchStart);
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/codehaus/groovy/runtime/ScriptBytecodeAdapter", "unwrap",
            "(Lgroovy/lang/GroovyRuntimeException;)Ljava/lang/Throwable;", false);
    mv.visitInsn(Opcodes.ATHROW);
    mv.visitTryCatchBlock(tryStart, tryEnd, catchStart, "groovy/lang/GroovyRuntimeException");

    mv.visitMaxs(0, 0);
    mv.visitEnd();
    return mv;
}