Search in sources :

Example 1 with Type

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

the class ProxyGeneratorAdapter method visitMethod.

@Override
public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) {
    Object key = Arrays.asList(name, desc);
    if (visitedMethods.contains(key))
        return null;
    if (Modifier.isPrivate(access) || Modifier.isNative(access) || ((access & ACC_SYNTHETIC) != 0)) {
        // do not generate bytecode for private methods
        return null;
    }
    int accessFlags = access;
    visitedMethods.add(key);
    if ((objectDelegateMethods.contains(name + desc) || delegatedClosures.containsKey(name) || (!"<init>".equals(name) && hasWildcard)) && !Modifier.isStatic(access) && !Modifier.isFinal(access)) {
        if (!GROOVYOBJECT_METHOD_NAMESS.contains(name)) {
            if (Modifier.isAbstract(access)) {
                // prevents the proxy from being abstract
                accessFlags -= ACC_ABSTRACT;
            }
            if (delegatedClosures.containsKey(name) || (!"<init>".equals(name) && hasWildcard)) {
                delegatedClosures.put(name, Boolean.TRUE);
                return makeDelegateToClosureCall(name, desc, signature, exceptions, accessFlags);
            }
            if (generateDelegateField && objectDelegateMethods.contains(name + desc)) {
                return makeDelegateCall(name, desc, signature, exceptions, accessFlags);
            }
            delegatedClosures.put(name, Boolean.TRUE);
            return makeDelegateToClosureCall(name, desc, signature, exceptions, accessFlags);
        }
    } else if ("getProxyTarget".equals(name) && "()Ljava/lang/Object;".equals(desc)) {
        return createGetProxyTargetMethod(access, name, desc, signature, exceptions);
    } else if ("<init>".equals(name) && (Modifier.isPublic(access) || Modifier.isProtected(access))) {
        return createConstructor(access, name, desc, signature, exceptions);
    } else if (Modifier.isAbstract(access) && !GROOVYOBJECT_METHOD_NAMESS.contains(name)) {
        if (isImplemented(superClass, name, desc)) {
            return null;
        }
        accessFlags -= ACC_ABSTRACT;
        MethodVisitor mv = super.visitMethod(accessFlags, name, desc, signature, exceptions);
        mv.visitCode();
        Type[] args = Type.getArgumentTypes(desc);
        if (emptyBody) {
            Type returnType = Type.getReturnType(desc);
            if (returnType == Type.VOID_TYPE) {
                mv.visitInsn(RETURN);
            } else {
                int loadIns = getLoadInsn(returnType);
                switch(loadIns) {
                    case ILOAD:
                        mv.visitInsn(ICONST_0);
                        break;
                    case LLOAD:
                        mv.visitInsn(LCONST_0);
                        break;
                    case FLOAD:
                        mv.visitInsn(FCONST_0);
                        break;
                    case DLOAD:
                        mv.visitInsn(DCONST_0);
                        break;
                    default:
                        mv.visitInsn(ACONST_NULL);
                }
                mv.visitInsn(getReturnInsn(returnType));
                mv.visitMaxs(2, registerLen(args) + 1);
            }
        } else {
            // for compatibility with the legacy proxy generator, we should throw an UnsupportedOperationException
            // instead of an AbtractMethodException
            mv.visitTypeInsn(NEW, "java/lang/UnsupportedOperationException");
            mv.visitInsn(DUP);
            mv.visitMethodInsn(INVOKESPECIAL, "java/lang/UnsupportedOperationException", "<init>", "()V", false);
            mv.visitInsn(ATHROW);
            mv.visitMaxs(2, registerLen(args) + 1);
        }
        mv.visitEnd();
    }
    return null;
}
Also used : Type(org.objectweb.asm.Type) GroovyObject(groovy.lang.GroovyObject) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 2 with Type

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

the class ProxyGeneratorAdapter method makeDelegateToClosureCall.

protected MethodVisitor makeDelegateToClosureCall(final String name, final String desc, final String signature, final String[] exceptions, final int accessFlags) {
    MethodVisitor mv = super.visitMethod(accessFlags, name, desc, signature, exceptions);
    //        TraceMethodVisitor tmv = new TraceMethodVisitor(mv);
    //        mv = tmv;
    mv.visitCode();
    int stackSize = 0;
    // method body should be:
    //  this.$delegate$closure$methodName.call(new Object[] { method arguments })
    Type[] args = Type.getArgumentTypes(desc);
    int arrayStore = args.length + 1;
    BytecodeHelper.pushConstant(mv, args.length);
    // stack size = 1
    mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
    stackSize = 1;
    int idx = 1;
    for (int i = 0; i < args.length; i++) {
        Type arg = args[i];
        // stack size = 2
        mv.visitInsn(DUP);
        // array index, stack size = 3
        BytecodeHelper.pushConstant(mv, i);
        stackSize = 3;
        // primitive types must be boxed
        if (isPrimitive(arg)) {
            mv.visitIntInsn(getLoadInsn(arg), idx);
            String wrappedType = getWrappedClassDescriptor(arg);
            mv.visitMethodInsn(INVOKESTATIC, wrappedType, "valueOf", "(" + arg.getDescriptor() + ")L" + wrappedType + ";", false);
        } else {
            // load argument i
            mv.visitVarInsn(ALOAD, idx);
        }
        idx += registerLen(arg);
        stackSize = Math.max(4, 3 + registerLen(arg));
        // store value into array
        mv.visitInsn(AASTORE);
    }
    // store array
    mv.visitVarInsn(ASTORE, arrayStore);
    int arrayIndex = arrayStore;
    // load this
    mv.visitVarInsn(ALOAD, 0);
    // load closure map
    mv.visitFieldInsn(GETFIELD, proxyName, CLOSURES_MAP_FIELD, "Ljava/util/Map;");
    // load method name
    mv.visitLdcInsn(name);
    mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;", true);
    arrayStore++;
    mv.visitVarInsn(ASTORE, arrayStore);
    // if null, test if wildcard exists
    Label notNull = new Label();
    mv.visitIntInsn(ALOAD, arrayStore);
    mv.visitJumpInsn(IFNONNULL, notNull);
    // load this
    mv.visitVarInsn(ALOAD, 0);
    // load closure map
    mv.visitFieldInsn(GETFIELD, proxyName, CLOSURES_MAP_FIELD, "Ljava/util/Map;");
    // load wildcard
    mv.visitLdcInsn("*");
    mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;", true);
    mv.visitVarInsn(ASTORE, arrayStore);
    mv.visitLabel(notNull);
    mv.visitVarInsn(ALOAD, arrayStore);
    mv.visitMethodInsn(INVOKESTATIC, BytecodeHelper.getClassInternalName(this.getClass()), "ensureClosure", "(Ljava/lang/Object;)Lgroovy/lang/Closure;", false);
    // load argument array
    mv.visitVarInsn(ALOAD, arrayIndex);
    stackSize++;
    // call closure
    mv.visitMethodInsn(INVOKEVIRTUAL, "groovy/lang/Closure", "call", "([Ljava/lang/Object;)Ljava/lang/Object;", false);
    unwrapResult(mv, desc);
    mv.visitMaxs(stackSize, arrayStore + 1);
    mv.visitEnd();
    //        System.out.println("tmv.getText() = " + tmv.getText());
    return null;
}
Also used : Type(org.objectweb.asm.Type) Label(org.objectweb.asm.Label) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 3 with Type

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

the class ProxyGeneratorAdapter method makeDelegateCall.

/**
     * Generate a call to the delegate object.
     */
protected MethodVisitor makeDelegateCall(final String name, final String desc, final String signature, final String[] exceptions, final int accessFlags) {
    MethodVisitor mv = super.visitMethod(accessFlags, name, desc, signature, exceptions);
    // load this
    mv.visitVarInsn(ALOAD, 0);
    // load delegate
    mv.visitFieldInsn(GETFIELD, proxyName, DELEGATE_OBJECT_FIELD, BytecodeHelper.getTypeDescription(delegateClass));
    // using InvokerHelper to allow potential intercepted calls
    int size;
    // method name
    mv.visitLdcInsn(name);
    Type[] args = Type.getArgumentTypes(desc);
    BytecodeHelper.pushConstant(mv, args.length);
    mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
    size = 6;
    int idx = 1;
    for (int i = 0; i < args.length; i++) {
        Type arg = args[i];
        mv.visitInsn(DUP);
        BytecodeHelper.pushConstant(mv, i);
        // primitive types must be boxed
        if (isPrimitive(arg)) {
            mv.visitIntInsn(getLoadInsn(arg), idx);
            String wrappedType = getWrappedClassDescriptor(arg);
            mv.visitMethodInsn(INVOKESTATIC, wrappedType, "valueOf", "(" + arg.getDescriptor() + ")L" + wrappedType + ";", false);
        } else {
            // load argument i
            mv.visitVarInsn(ALOAD, idx);
        }
        size = Math.max(size, 5 + registerLen(arg));
        idx += registerLen(arg);
        // store value into array
        mv.visitInsn(AASTORE);
    }
    mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/InvokerHelper", "invokeMethod", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;", false);
    unwrapResult(mv, desc);
    mv.visitMaxs(size, registerLen(args) + 1);
    return mv;
}
Also used : Type(org.objectweb.asm.Type) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 4 with Type

use of org.objectweb.asm.Type in project cglib by cglib.

the class EmitUtils method process_arrays.

/**
     * Process two arrays on the stack in parallel. Assumes the top two items on the stack
     * are arrays of the specified class. The arrays must be the same length. For each pair
     * of elements in the arrays, puts the pair on the stack and triggers the callback.
     * @param type the type of the arrays (type.isArray() must be true)
     * @param callback the callback triggered for each pair of elements
     */
public static void process_arrays(CodeEmitter e, Type type, ProcessArrayCallback callback) {
    Type componentType = TypeUtils.getComponentType(type);
    Local array1 = e.make_local();
    Local array2 = e.make_local();
    Local loopvar = e.make_local(Type.INT_TYPE);
    Label loopbody = e.make_label();
    Label checkloop = e.make_label();
    e.store_local(array1);
    e.store_local(array2);
    e.push(0);
    e.store_local(loopvar);
    e.goTo(checkloop);
    e.mark(loopbody);
    e.load_local(array1);
    e.load_local(loopvar);
    e.array_load(componentType);
    e.load_local(array2);
    e.load_local(loopvar);
    e.array_load(componentType);
    callback.processElement(componentType);
    e.iinc(loopvar, 1);
    e.mark(checkloop);
    e.load_local(loopvar);
    e.load_local(array1);
    e.arraylength();
    e.if_icmp(e.LT, loopbody);
}
Also used : Type(org.objectweb.asm.Type) Label(org.objectweb.asm.Label)

Example 5 with Type

use of org.objectweb.asm.Type in project cglib by cglib.

the class ReflectUtils method getClassInfo.

public static ClassInfo getClassInfo(final Class clazz) {
    final Type type = Type.getType(clazz);
    final Type sc = (clazz.getSuperclass() == null) ? null : Type.getType(clazz.getSuperclass());
    return new ClassInfo() {

        public Type getType() {
            return type;
        }

        public Type getSuperType() {
            return sc;
        }

        public Type[] getInterfaces() {
            return TypeUtils.getTypes(clazz.getInterfaces());
        }

        public int getModifiers() {
            return clazz.getModifiers();
        }
    };
}
Also used : Type(org.objectweb.asm.Type)

Aggregations

Type (org.objectweb.asm.Type)151 MethodVisitor (org.objectweb.asm.MethodVisitor)33 Label (org.objectweb.asm.Label)21 Method (org.objectweb.asm.commons.Method)16 GeneratorAdapter (org.objectweb.asm.commons.GeneratorAdapter)14 ClassWriter (org.objectweb.asm.ClassWriter)13 ArrayList (java.util.ArrayList)11 ClassReader (org.objectweb.asm.ClassReader)10 Method (java.lang.reflect.Method)9 AnnotationVisitor (org.objectweb.asm.AnnotationVisitor)9 ClassVisitor (org.objectweb.asm.ClassVisitor)9 PropertyAccessorType (org.gradle.internal.reflect.PropertyAccessorType)7 ModelType (org.gradle.model.internal.type.ModelType)7 LayoutlibDelegate (com.android.tools.layoutlib.annotations.LayoutlibDelegate)6 MethodType (java.lang.invoke.MethodType)6 List (java.util.List)6 VarInsnNode (org.objectweb.asm.tree.VarInsnNode)5 InterceptorType (com.navercorp.pinpoint.profiler.instrument.interceptor.InterceptorType)4 IOException (java.io.IOException)4 InputStream (java.io.InputStream)4