Search in sources :

Example 16 with Type

use of org.objectweb.asm.Type in project buck by facebook.

the class FirstOrderHelper method addDependencies.

private ImmutableSet<String> addDependencies(Iterable<ClassNode> allClasses) {
    for (ClassNode classNode : allClasses) {
        FirstOrderVisitorContext context = new FirstOrderVisitorContext();
        classNode.accept(context.classVisitor);
        FirstOrderTypeInfo info = context.builder.build();
        knownTypes.put(info.type, info);
    }
    for (Type type : scenarioTypes) {
        addFirstOrderTypes(type);
    }
    return resultBuilder.build();
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) Type(org.objectweb.asm.Type)

Example 17 with Type

use of org.objectweb.asm.Type in project android_frameworks_base by ParanoidAndroid.

the class DelegateMethodAdapter2 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 DelegateMethodAdapter2} 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<Type>();
    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) {
            // 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);
    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 18 with Type

use of org.objectweb.asm.Type in project android_frameworks_base by ParanoidAndroid.

the class TransformClassAdapter method visitMethod.

/* Visits a method. */
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
    if (mDeleteReturns != null) {
        Type t = Type.getReturnType(desc);
        if (t.getSort() == Type.OBJECT) {
            String returnType = t.getInternalName();
            if (returnType != null) {
                if (mDeleteReturns.contains(returnType)) {
                    return null;
                }
            }
        }
    }
    String methodSignature = mClassName.replace('/', '.') + "#" + name;
    // change access to public
    if (Main.sOptions.generatePublicAccess) {
        access &= ~(Opcodes.ACC_PROTECTED | Opcodes.ACC_PRIVATE);
        access |= Opcodes.ACC_PUBLIC;
    }
    // remove final
    access = access & ~Opcodes.ACC_FINAL;
    // and don't try to stub interfaces nor abstract non-native methods.
    if (!mIsInterface && ((access & (Opcodes.ACC_ABSTRACT | Opcodes.ACC_NATIVE)) != Opcodes.ACC_ABSTRACT) && (mStubAll || (access & Opcodes.ACC_NATIVE) != 0) || mStubMethods.contains(methodSignature)) {
        boolean isStatic = (access & Opcodes.ACC_STATIC) != 0;
        boolean isNative = (access & Opcodes.ACC_NATIVE) != 0;
        // remove abstract, final and native
        access = access & ~(Opcodes.ACC_ABSTRACT | Opcodes.ACC_FINAL | Opcodes.ACC_NATIVE);
        String invokeSignature = methodSignature + desc;
        mLog.debug("  Stub: %s (%s)", invokeSignature, isNative ? "native" : "");
        MethodVisitor mw = super.visitMethod(access, name, desc, signature, exceptions);
        return new StubMethodAdapter(mw, name, returnType(desc), invokeSignature, isStatic, isNative);
    } else {
        mLog.debug("  Keep: %s %s", name, desc);
        return super.visitMethod(access, name, desc, signature, exceptions);
    }
}
Also used : Type(org.objectweb.asm.Type) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 19 with Type

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

the class EventSubscriptionTransformer method buildEvents.

private boolean buildEvents(ClassNode classNode) throws Exception {
    // Yes, this recursively loads classes until we get this base class. THIS IS NOT A ISSUE. Coremods should handle re-entry just fine.
    // If they do not this a COREMOD issue NOT a Forge/LaunchWrapper issue.
    Class<?> parent = this.getClass().getClassLoader().loadClass(classNode.superName.replace('/', '.'));
    if (!Event.class.isAssignableFrom(parent)) {
        return false;
    }
    //Class<?> listenerListClazz = Class.forName("net.minecraftforge.fml.common.eventhandler.ListenerList", false, getClass().getClassLoader());
    Type tList = Type.getType("Lnet/minecraftforge/fml/common/eventhandler/ListenerList;");
    boolean edited = false;
    boolean hasSetup = false;
    boolean hasGetListenerList = false;
    boolean hasDefaultCtr = false;
    boolean hasCancelable = false;
    boolean hasResult = false;
    String voidDesc = Type.getMethodDescriptor(VOID_TYPE);
    String boolDesc = Type.getMethodDescriptor(BOOLEAN_TYPE);
    String listDesc = tList.getDescriptor();
    String listDescM = Type.getMethodDescriptor(tList);
    for (MethodNode method : classNode.methods) {
        if (method.name.equals("setup") && method.desc.equals(voidDesc) && (method.access & ACC_PROTECTED) == ACC_PROTECTED)
            hasSetup = true;
        if ((method.access & ACC_PUBLIC) == ACC_PUBLIC) {
            if (method.name.equals("getListenerList") && method.desc.equals(listDescM))
                hasGetListenerList = true;
            if (method.name.equals("isCancelable") && method.desc.equals(boolDesc))
                hasCancelable = true;
            if (method.name.equals("hasResult") && method.desc.equals(boolDesc))
                hasResult = true;
        }
        if (method.name.equals("<init>") && method.desc.equals(voidDesc))
            hasDefaultCtr = true;
    }
    if (classNode.visibleAnnotations != null) {
        for (AnnotationNode node : classNode.visibleAnnotations) {
            if (!hasResult && node.desc.equals("Lnet/minecraftforge/fml/common/eventhandler/Event$HasResult;")) {
                /* Add:
                     *      public boolean hasResult()
                     *      {
                     *            return true;
                     *      }
                     */
                MethodNode method = new MethodNode(ACC_PUBLIC, "hasResult", boolDesc, null, null);
                method.instructions.add(new InsnNode(ICONST_1));
                method.instructions.add(new InsnNode(IRETURN));
                classNode.methods.add(method);
                edited = true;
            } else if (!hasCancelable && node.desc.equals("Lnet/minecraftforge/fml/common/eventhandler/Cancelable;")) {
                /* Add:
                     *      public boolean isCancelable()
                     *      {
                     *            return true;
                     *      }
                     */
                MethodNode method = new MethodNode(ACC_PUBLIC, "isCancelable", boolDesc, null, null);
                method.instructions.add(new InsnNode(ICONST_1));
                method.instructions.add(new InsnNode(IRETURN));
                classNode.methods.add(method);
                edited = true;
            }
        }
    }
    if (hasSetup) {
        if (!hasGetListenerList)
            throw new RuntimeException("Event class defines setup() but does not define getListenerList! " + classNode.name);
        else
            return edited;
    }
    Type tSuper = Type.getType(classNode.superName);
    //Add private static ListenerList LISTENER_LIST
    classNode.fields.add(new FieldNode(ACC_PRIVATE | ACC_STATIC, "LISTENER_LIST", listDesc, null, null));
    /*Add:
         *      public <init>()
         *      {
         *              super();
         *      }
         */
    if (!hasDefaultCtr) {
        MethodNode method = new MethodNode(ACC_PUBLIC, "<init>", voidDesc, null, null);
        method.instructions.add(new VarInsnNode(ALOAD, 0));
        method.instructions.add(new MethodInsnNode(INVOKESPECIAL, tSuper.getInternalName(), "<init>", voidDesc, false));
        method.instructions.add(new InsnNode(RETURN));
        classNode.methods.add(method);
    }
    /*Add:
         *      protected void setup()
         *      {
         *              super.setup();
         *              if (LISTENER_LIST != NULL)
         *              {
         *                      return;
         *              }
         *              LISTENER_LIST = new ListenerList(super.getListenerList());
         *      }
         */
    MethodNode method = new MethodNode(ACC_PROTECTED, "setup", voidDesc, null, null);
    method.instructions.add(new VarInsnNode(ALOAD, 0));
    method.instructions.add(new MethodInsnNode(INVOKESPECIAL, tSuper.getInternalName(), "setup", voidDesc, false));
    method.instructions.add(new FieldInsnNode(GETSTATIC, classNode.name, "LISTENER_LIST", listDesc));
    LabelNode initListener = new LabelNode();
    method.instructions.add(new JumpInsnNode(IFNULL, initListener));
    method.instructions.add(new InsnNode(RETURN));
    method.instructions.add(initListener);
    method.instructions.add(new FrameNode(F_SAME, 0, null, 0, null));
    method.instructions.add(new TypeInsnNode(NEW, tList.getInternalName()));
    method.instructions.add(new InsnNode(DUP));
    method.instructions.add(new VarInsnNode(ALOAD, 0));
    method.instructions.add(new MethodInsnNode(INVOKESPECIAL, tSuper.getInternalName(), "getListenerList", listDescM, false));
    method.instructions.add(new MethodInsnNode(INVOKESPECIAL, tList.getInternalName(), "<init>", getMethodDescriptor(VOID_TYPE, tList), false));
    method.instructions.add(new FieldInsnNode(PUTSTATIC, classNode.name, "LISTENER_LIST", listDesc));
    method.instructions.add(new InsnNode(RETURN));
    classNode.methods.add(method);
    /*Add:
         *      public ListenerList getListenerList()
         *      {
         *              return this.LISTENER_LIST;
         *      }
         */
    method = new MethodNode(ACC_PUBLIC, "getListenerList", listDescM, null, null);
    method.instructions.add(new FieldInsnNode(GETSTATIC, classNode.name, "LISTENER_LIST", listDesc));
    method.instructions.add(new InsnNode(ARETURN));
    classNode.methods.add(method);
    return true;
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) FrameNode(org.objectweb.asm.tree.FrameNode) FieldNode(org.objectweb.asm.tree.FieldNode) FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) InsnNode(org.objectweb.asm.tree.InsnNode) Type(org.objectweb.asm.Type) MethodNode(org.objectweb.asm.tree.MethodNode) AnnotationNode(org.objectweb.asm.tree.AnnotationNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) Event(net.minecraftforge.fml.common.eventhandler.Event) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode)

Example 20 with Type

use of org.objectweb.asm.Type in project hudson-2.x by hudson.

the class SubClassGenerator method generate.

public <T> Class<? extends T> generate(Class<T> base, String name) {
    //?
    ClassWriter cw = new ClassWriter(false, false);
    cw.visit(49, ACC_PUBLIC, name.replace('.', '/'), null, Type.getInternalName(base), null);
    for (Constructor c : base.getDeclaredConstructors()) {
        Class[] et = c.getExceptionTypes();
        String[] exceptions = new String[et.length];
        for (int i = 0; i < et.length; i++) exceptions[i] = Type.getInternalName(et[i]);
        String methodDescriptor = getMethodDescriptor(c);
        MethodVisitor m = cw.visitMethod(c.getModifiers(), "<init>", methodDescriptor, null, exceptions);
        m.visitCode();
        int index = 1;
        m.visitVarInsn(ALOAD, 0);
        for (Class param : c.getParameterTypes()) {
            Type t = Type.getType(param);
            m.visitVarInsn(t.getOpcode(ILOAD), index);
            index += t.getSize();
        }
        m.visitMethodInsn(INVOKESPECIAL, Type.getInternalName(base), "<init>", methodDescriptor);
        m.visitInsn(RETURN);
        m.visitMaxs(index, index);
        m.visitEnd();
    }
    cw.visitEnd();
    byte[] image = cw.toByteArray();
    Class<? extends T> c = defineClass(name, image, 0, image.length).asSubclass(base);
    Hudson h = Hudson.getInstance();
    if (// null only during tests.
    h != null)
        // can't change the field type as it breaks binary compatibility
        ((UberClassLoader) h.pluginManager.uberClassLoader).addNamedClass(name, c);
    return c;
}
Also used : Type(org.objectweb.asm.Type) Constructor(java.lang.reflect.Constructor) Hudson(hudson.model.Hudson) ClassWriter(org.objectweb.asm.ClassWriter) MethodVisitor(org.objectweb.asm.MethodVisitor)

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