Search in sources :

Example 46 with AnnotationVisitor

use of org.objectweb.asm.AnnotationVisitor in project presto by prestodb.

the class AnnotationDefinition method visitFieldAnnotation.

public void visitFieldAnnotation(FieldVisitor visitor) {
    AnnotationVisitor annotationVisitor = visitor.visitAnnotation(type.getType(), true);
    visit(annotationVisitor);
    annotationVisitor.visitEnd();
}
Also used : AnnotationVisitor(org.objectweb.asm.AnnotationVisitor)

Example 47 with AnnotationVisitor

use of org.objectweb.asm.AnnotationVisitor in project android_frameworks_base by DirtyUnicorns.

the class DelegateMethodAdapter method generateDelegateCode.

/**
     * Generates the new code for the method.
     * <p/>
     * For native methods, this must be invoked directly by {@link DelegateClassAdapter}
     * (since they have no code to visit).
     * <p/>
     * Otherwise for non-native methods the {@link DelegateClassAdapter} simply needs to
     * return this instance of {@link DelegateMethodAdapter} and let the normal visitor pattern
     * invoke it as part of the {@link ClassReader#accept(ClassVisitor, int)} workflow and then
     * this method will be invoked from {@link MethodVisitor#visitEnd()}.
     */
public void generateDelegateCode() {
    /*
         * The goal is to generate a call to a static delegate method.
         * If this method is non-static, the first parameter will be 'this'.
         * All the parameters must be passed and then the eventual return type returned.
         *
         * Example, let's say we have a method such as
         *   public void myMethod(int a, Object b, ArrayList<String> c) { ... }
         *
         * We'll want to create a body that calls a delegate method like this:
         *   TheClass_Delegate.myMethod(this, a, b, c);
         *
         * If the method is non-static and the class name is an inner class (e.g. has $ in its
         * last segment), we want to push the 'this' of the outer class first:
         *   OuterClass_InnerClass_Delegate.myMethod(
         *     OuterClass.this,
         *     OuterClass$InnerClass.this,
         *     a, b, c);
         *
         * Only one level of inner class is supported right now, for simplicity and because
         * we don't need more.
         *
         * The generated class name is the current class name with "_Delegate" appended to it.
         * One thing to realize is that we don't care about generics -- since generic types
         * are erased at build time, they have no influence on the method name being called.
         */
    // Add our annotation
    AnnotationVisitor aw = mDelWriter.visitAnnotation(Type.getObjectType(Type.getInternalName(LayoutlibDelegate.class)).toString(), // visible at runtime
    true);
    if (aw != null) {
        aw.visitEnd();
    }
    mDelWriter.visitCode();
    if (mDelegateLineNumber != null) {
        Object[] p = mDelegateLineNumber;
        mDelWriter.visitLineNumber((Integer) p[0], (Label) p[1]);
    }
    ArrayList<Type> paramTypes = new ArrayList<>();
    String delegateClassName = mClassName + DELEGATE_SUFFIX;
    boolean pushedArg0 = false;
    int maxStack = 0;
    // Check if the last segment of the class name has inner an class.
    // Right now we only support one level of inner classes.
    Type outerType = null;
    int slash = mClassName.lastIndexOf('/');
    int dol = mClassName.lastIndexOf('$');
    if (dol != -1 && dol > slash && dol == mClassName.indexOf('$')) {
        String outerClass = mClassName.substring(0, dol);
        outerType = Type.getObjectType(outerClass);
        // Change a delegate class name to "com/foo/Outer_Inner_Delegate"
        delegateClassName = delegateClassName.replace('$', '_');
    }
    // by the 'this' of any outer class, if any.
    if (!mIsStatic) {
        if (outerType != null && !mIsStaticInnerClass) {
            // The first-level inner class has a package-protected member called 'this$0'
            // that points to the outer class.
            // Push this.getField("this$0") on the call stack.
            // var 0 = this
            mDelWriter.visitVarInsn(Opcodes.ALOAD, 0);
            mDelWriter.visitFieldInsn(Opcodes.GETFIELD, // class where the field is defined
            mClassName, // field name
            "this$0", // type of the field
            outerType.getDescriptor());
            maxStack++;
            paramTypes.add(outerType);
        }
        // Push "this" for the instance method, which is always ALOAD 0
        mDelWriter.visitVarInsn(Opcodes.ALOAD, 0);
        maxStack++;
        pushedArg0 = true;
        paramTypes.add(Type.getObjectType(mClassName));
    }
    // Push all other arguments. Start at arg 1 if we already pushed 'this' above.
    Type[] argTypes = Type.getArgumentTypes(mDesc);
    int maxLocals = pushedArg0 ? 1 : 0;
    for (Type t : argTypes) {
        int size = t.getSize();
        mDelWriter.visitVarInsn(t.getOpcode(Opcodes.ILOAD), maxLocals);
        maxLocals += size;
        maxStack += size;
        paramTypes.add(t);
    }
    // Construct the descriptor of the delegate based on the parameters
    // we pushed on the call stack. The return type remains unchanged.
    String desc = Type.getMethodDescriptor(Type.getReturnType(mDesc), paramTypes.toArray(new Type[paramTypes.size()]));
    // Invoke the static delegate
    mDelWriter.visitMethodInsn(Opcodes.INVOKESTATIC, delegateClassName, mMethodName, desc, false);
    Type returnType = Type.getReturnType(mDesc);
    mDelWriter.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
    mDelWriter.visitMaxs(maxStack, maxLocals);
    mDelWriter.visitEnd();
    // For debugging now. Maybe we should collect these and store them in
    // a text file for helping create the delegates. We could also compare
    // the text file to a golden and break the build on unsupported changes
    // or regressions. Even better we could fancy-print something that looks
    // like the expected Java method declaration.
    mLog.debug("Delegate: %1$s # %2$s %3$s", delegateClassName, mMethodName, desc);
}
Also used : LayoutlibDelegate(com.android.tools.layoutlib.annotations.LayoutlibDelegate) Type(org.objectweb.asm.Type) AnnotationVisitor(org.objectweb.asm.AnnotationVisitor) ArrayList(java.util.ArrayList)

Example 48 with AnnotationVisitor

use of org.objectweb.asm.AnnotationVisitor in project bytecode-viewer by Konloch.

the class SAXAnnotationAdapter method visit.

@Override
public void visit(final String name, final Object value) {
    Class<?> c = value.getClass();
    if (c.isArray()) {
        AnnotationVisitor av = visitArray(name);
        if (value instanceof byte[]) {
            byte[] b = (byte[]) value;
            for (int i = 0; i < b.length; i++) {
                av.visit(null, b[i]);
            }
        } else if (value instanceof char[]) {
            char[] b = (char[]) value;
            for (int i = 0; i < b.length; i++) {
                av.visit(null, b[i]);
            }
        } else if (value instanceof short[]) {
            short[] b = (short[]) value;
            for (int i = 0; i < b.length; i++) {
                av.visit(null, b[i]);
            }
        } else if (value instanceof boolean[]) {
            boolean[] b = (boolean[]) value;
            for (int i = 0; i < b.length; i++) {
                av.visit(null, Boolean.valueOf(b[i]));
            }
        } else if (value instanceof int[]) {
            int[] b = (int[]) value;
            for (int i = 0; i < b.length; i++) {
                av.visit(null, b[i]);
            }
        } else if (value instanceof long[]) {
            long[] b = (long[]) value;
            for (int i = 0; i < b.length; i++) {
                av.visit(null, b[i]);
            }
        } else if (value instanceof float[]) {
            float[] b = (float[]) value;
            for (int i = 0; i < b.length; i++) {
                av.visit(null, b[i]);
            }
        } else if (value instanceof double[]) {
            double[] b = (double[]) value;
            for (int i = 0; i < b.length; i++) {
                av.visit(null, b[i]);
            }
        }
        av.visitEnd();
    } else {
        addValueElement("annotationValue", name, Type.getDescriptor(c), value.toString());
    }
}
Also used : AnnotationVisitor(org.objectweb.asm.AnnotationVisitor)

Example 49 with AnnotationVisitor

use of org.objectweb.asm.AnnotationVisitor in project android_frameworks_base by AOSPA.

the class DelegateMethodAdapter method generateDelegateCode.

/**
     * Generates the new code for the method.
     * <p/>
     * For native methods, this must be invoked directly by {@link DelegateClassAdapter}
     * (since they have no code to visit).
     * <p/>
     * Otherwise for non-native methods the {@link DelegateClassAdapter} simply needs to
     * return this instance of {@link DelegateMethodAdapter} and let the normal visitor pattern
     * invoke it as part of the {@link ClassReader#accept(ClassVisitor, int)} workflow and then
     * this method will be invoked from {@link MethodVisitor#visitEnd()}.
     */
public void generateDelegateCode() {
    /*
         * The goal is to generate a call to a static delegate method.
         * If this method is non-static, the first parameter will be 'this'.
         * All the parameters must be passed and then the eventual return type returned.
         *
         * Example, let's say we have a method such as
         *   public void myMethod(int a, Object b, ArrayList<String> c) { ... }
         *
         * We'll want to create a body that calls a delegate method like this:
         *   TheClass_Delegate.myMethod(this, a, b, c);
         *
         * If the method is non-static and the class name is an inner class (e.g. has $ in its
         * last segment), we want to push the 'this' of the outer class first:
         *   OuterClass_InnerClass_Delegate.myMethod(
         *     OuterClass.this,
         *     OuterClass$InnerClass.this,
         *     a, b, c);
         *
         * Only one level of inner class is supported right now, for simplicity and because
         * we don't need more.
         *
         * The generated class name is the current class name with "_Delegate" appended to it.
         * One thing to realize is that we don't care about generics -- since generic types
         * are erased at build time, they have no influence on the method name being called.
         */
    // Add our annotation
    AnnotationVisitor aw = mDelWriter.visitAnnotation(Type.getObjectType(Type.getInternalName(LayoutlibDelegate.class)).toString(), // visible at runtime
    true);
    if (aw != null) {
        aw.visitEnd();
    }
    mDelWriter.visitCode();
    if (mDelegateLineNumber != null) {
        Object[] p = mDelegateLineNumber;
        mDelWriter.visitLineNumber((Integer) p[0], (Label) p[1]);
    }
    ArrayList<Type> paramTypes = new ArrayList<>();
    String delegateClassName = mClassName + DELEGATE_SUFFIX;
    boolean pushedArg0 = false;
    int maxStack = 0;
    // Check if the last segment of the class name has inner an class.
    // Right now we only support one level of inner classes.
    Type outerType = null;
    int slash = mClassName.lastIndexOf('/');
    int dol = mClassName.lastIndexOf('$');
    if (dol != -1 && dol > slash && dol == mClassName.indexOf('$')) {
        String outerClass = mClassName.substring(0, dol);
        outerType = Type.getObjectType(outerClass);
        // Change a delegate class name to "com/foo/Outer_Inner_Delegate"
        delegateClassName = delegateClassName.replace('$', '_');
    }
    // by the 'this' of any outer class, if any.
    if (!mIsStatic) {
        if (outerType != null && !mIsStaticInnerClass) {
            // The first-level inner class has a package-protected member called 'this$0'
            // that points to the outer class.
            // Push this.getField("this$0") on the call stack.
            // var 0 = this
            mDelWriter.visitVarInsn(Opcodes.ALOAD, 0);
            mDelWriter.visitFieldInsn(Opcodes.GETFIELD, // class where the field is defined
            mClassName, // field name
            "this$0", // type of the field
            outerType.getDescriptor());
            maxStack++;
            paramTypes.add(outerType);
        }
        // Push "this" for the instance method, which is always ALOAD 0
        mDelWriter.visitVarInsn(Opcodes.ALOAD, 0);
        maxStack++;
        pushedArg0 = true;
        paramTypes.add(Type.getObjectType(mClassName));
    }
    // Push all other arguments. Start at arg 1 if we already pushed 'this' above.
    Type[] argTypes = Type.getArgumentTypes(mDesc);
    int maxLocals = pushedArg0 ? 1 : 0;
    for (Type t : argTypes) {
        int size = t.getSize();
        mDelWriter.visitVarInsn(t.getOpcode(Opcodes.ILOAD), maxLocals);
        maxLocals += size;
        maxStack += size;
        paramTypes.add(t);
    }
    // Construct the descriptor of the delegate based on the parameters
    // we pushed on the call stack. The return type remains unchanged.
    String desc = Type.getMethodDescriptor(Type.getReturnType(mDesc), paramTypes.toArray(new Type[paramTypes.size()]));
    // Invoke the static delegate
    mDelWriter.visitMethodInsn(Opcodes.INVOKESTATIC, delegateClassName, mMethodName, desc, false);
    Type returnType = Type.getReturnType(mDesc);
    mDelWriter.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
    mDelWriter.visitMaxs(maxStack, maxLocals);
    mDelWriter.visitEnd();
    // For debugging now. Maybe we should collect these and store them in
    // a text file for helping create the delegates. We could also compare
    // the text file to a golden and break the build on unsupported changes
    // or regressions. Even better we could fancy-print something that looks
    // like the expected Java method declaration.
    mLog.debug("Delegate: %1$s # %2$s %3$s", delegateClassName, mMethodName, desc);
}
Also used : LayoutlibDelegate(com.android.tools.layoutlib.annotations.LayoutlibDelegate) Type(org.objectweb.asm.Type) AnnotationVisitor(org.objectweb.asm.AnnotationVisitor) ArrayList(java.util.ArrayList)

Example 50 with AnnotationVisitor

use of org.objectweb.asm.AnnotationVisitor in project robovm by robovm.

the class ObjCProtocolProxyPlugin method generateProxyMethods.

private void generateProxyMethods(Config config, List<String> interfazes, ClassWriter cw) throws IOException {
    Clazzes clazzes = config.getClazzes();
    final Set<String> addedMethods = new HashSet<>();
    for (String interfaze : interfazes) {
        Clazz clazz = clazzes.load(interfaze);
        if (clazz == null) {
            continue;
        }
        // Copy all abstract method (we skip default methods) to the proxy 
        // and make them native instead of abstract.
        ClassReader classReader = new ClassReader(clazz.getBytes());
        classReader.accept(new ClassVisitor(ASM4, cw) {

            @Override
            public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
                String key = name + desc;
                if ((access & ACC_ABSTRACT) > 0 && !addedMethods.contains(key)) {
                    access &= ~ACC_ABSTRACT;
                    access |= ACC_NATIVE;
                    addedMethods.add(key);
                    return super.visitMethod(access, name, desc, signature, exceptions);
                }
                return null;
            }

            @Override
            public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
            // Ignored
            }

            @Override
            public void visitEnd() {
            // Ignored
            }

            @Override
            public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
                // Ignored
                return null;
            }

            @Override
            public void visitAttribute(Attribute attr) {
            // Ignored
            }

            @Override
            public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
                // Ignored
                return null;
            }

            @Override
            public void visitInnerClass(String name, String outerName, String innerName, int access) {
            // Ignored
            }

            @Override
            public void visitOuterClass(String owner, String name, String desc) {
            // Ignored
            }

            @Override
            public void visitSource(String source, String debug) {
            // Ignored
            }
        }, 0);
    }
}
Also used : Attribute(org.objectweb.asm.Attribute) ClassVisitor(org.objectweb.asm.ClassVisitor) FieldVisitor(org.objectweb.asm.FieldVisitor) MethodVisitor(org.objectweb.asm.MethodVisitor) AnnotationVisitor(org.objectweb.asm.AnnotationVisitor) ClassReader(org.objectweb.asm.ClassReader) Clazz(org.robovm.compiler.clazz.Clazz) Clazzes(org.robovm.compiler.clazz.Clazzes) HashSet(java.util.HashSet)

Aggregations

AnnotationVisitor (org.objectweb.asm.AnnotationVisitor)64 AnnotationNode (org.codehaus.groovy.ast.AnnotationNode)12 ArrayList (java.util.ArrayList)9 Type (org.objectweb.asm.Type)9 MethodVisitor (org.objectweb.asm.MethodVisitor)7 LayoutlibDelegate (com.android.tools.layoutlib.annotations.LayoutlibDelegate)6 ClassNode (org.codehaus.groovy.ast.ClassNode)6 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)6 InterfaceHelperClassNode (org.codehaus.groovy.ast.InterfaceHelperClassNode)6 ClassVisitor (org.objectweb.asm.ClassVisitor)6 ClassReader (org.objectweb.asm.ClassReader)5 HashMap (java.util.HashMap)4 Map (java.util.Map)4 FieldVisitor (org.objectweb.asm.FieldVisitor)3 Label (org.objectweb.asm.Label)3 GroovyRuntimeException (groovy.lang.GroovyRuntimeException)2 InputStream (java.io.InputStream)2 List (java.util.List)2 GroovyBugError (org.codehaus.groovy.GroovyBugError)2 GenericsType (org.codehaus.groovy.ast.GenericsType)2