Search in sources :

Example 1 with FieldNode

use of org.objectweb.asm.tree.FieldNode 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 2 with FieldNode

use of org.objectweb.asm.tree.FieldNode in project MinecraftForge by MinecraftForge.

the class SideTransformer method transform.

@Override
public byte[] transform(String name, String transformedName, byte[] bytes) {
    if (bytes == null) {
        return null;
    }
    ClassNode classNode = new ClassNode();
    ClassReader classReader = new ClassReader(bytes);
    classReader.accept(classNode, 0);
    if (remove(classNode.visibleAnnotations, SIDE)) {
        if (DEBUG) {
            System.out.println(String.format("Attempted to load class %s for invalid side %s", classNode.name, SIDE));
        }
        throw new RuntimeException(String.format("Attempted to load class %s for invalid side %s", classNode.name, SIDE));
    }
    Iterator<FieldNode> fields = classNode.fields.iterator();
    while (fields.hasNext()) {
        FieldNode field = fields.next();
        if (remove(field.visibleAnnotations, SIDE)) {
            if (DEBUG) {
                System.out.println(String.format("Removing Field: %s.%s", classNode.name, field.name));
            }
            fields.remove();
        }
    }
    LambdaGatherer lambdaGatherer = new LambdaGatherer();
    Iterator<MethodNode> methods = classNode.methods.iterator();
    while (methods.hasNext()) {
        MethodNode method = methods.next();
        if (remove(method.visibleAnnotations, SIDE)) {
            if (DEBUG) {
                System.out.println(String.format("Removing Method: %s.%s%s", classNode.name, method.name, method.desc));
            }
            methods.remove();
            lambdaGatherer.accept(method);
        }
    }
    // remove dynamic lambda methods that are inside of removed methods
    List<Handle> dynamicLambdaHandles = lambdaGatherer.getDynamicLambdaHandles();
    if (!dynamicLambdaHandles.isEmpty()) {
        methods = classNode.methods.iterator();
        while (methods.hasNext()) {
            MethodNode method = methods.next();
            for (Handle dynamicLambdaHandle : dynamicLambdaHandles) {
                if (method.name.equals(dynamicLambdaHandle.getName()) && method.desc.equals(dynamicLambdaHandle.getDesc())) {
                    if (DEBUG) {
                        System.out.println(String.format("Removing Method: %s.%s%s", classNode.name, method.name, method.desc));
                    }
                    methods.remove();
                }
            }
        }
    }
    ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    classNode.accept(writer);
    return writer.toByteArray();
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) FieldNode(org.objectweb.asm.tree.FieldNode) MethodNode(org.objectweb.asm.tree.MethodNode) ClassReader(org.objectweb.asm.ClassReader) ClassWriter(org.objectweb.asm.ClassWriter) Handle(org.objectweb.asm.Handle)

Example 3 with FieldNode

use of org.objectweb.asm.tree.FieldNode in project pinpoint by naver.

the class ASMClassNodeAdapter method getField.

public ASMFieldNodeAdapter getField(final String fieldName, final String fieldDesc) {
    if (fieldName == null || this.classNode.fields == null) {
        return null;
    }
    final List<FieldNode> fields = this.classNode.fields;
    for (FieldNode fieldNode : fields) {
        if ((fieldNode.name != null && fieldNode.name.equals(fieldName)) && (fieldDesc == null || (fieldNode.desc != null && fieldNode.desc.equals(fieldDesc)))) {
            return new ASMFieldNodeAdapter(fieldNode);
        }
    }
    // find interface.
    final List<String> interfaces = this.classNode.interfaces;
    if (interfaces != null && interfaces.size() > 0) {
        for (String interfaceClassName : interfaces) {
            if (interfaceClassName == null) {
                continue;
            }
            final ASMClassNodeAdapter classNodeAdapter = ASMClassNodeAdapter.get(this.pluginContext, this.classLoader, interfaceClassName, true);
            if (classNodeAdapter != null) {
                final ASMFieldNodeAdapter fieldNode = classNodeAdapter.getField(fieldName, fieldDesc);
                if (fieldNode != null) {
                    return fieldNode;
                }
            }
        }
    }
    // find super class.
    if (this.classNode.superName != null) {
        final ASMClassNodeAdapter classNodeAdapter = ASMClassNodeAdapter.get(this.pluginContext, this.classLoader, this.classNode.superName, true);
        if (classNodeAdapter != null) {
            final ASMFieldNodeAdapter fieldNode = classNodeAdapter.getField(fieldName, fieldDesc);
            if (fieldNode != null) {
                return fieldNode;
            }
        }
    }
    return null;
}
Also used : FieldNode(org.objectweb.asm.tree.FieldNode)

Example 4 with FieldNode

use of org.objectweb.asm.tree.FieldNode in project pinpoint by naver.

the class ASMFieldNodeAdapterTest method getName.

@Test
public void getName() throws Exception {
    ClassNode classNode = ASMClassNodeLoader.get("com.navercorp.pinpoint.profiler.instrument.mock.FieldClass");
    List<FieldNode> fieldNodes = classNode.fields;
    for (FieldNode fieldNode : fieldNodes) {
        ASMFieldNodeAdapter adapter = new ASMFieldNodeAdapter(fieldNode);
        assertNotNull(adapter.getName());
        assertNotNull(adapter.getClassName());
        assertNotNull(adapter.getDesc());
    }
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) FieldNode(org.objectweb.asm.tree.FieldNode) Test(org.junit.Test)

Example 5 with FieldNode

use of org.objectweb.asm.tree.FieldNode in project spring-loaded by spring-projects.

the class Utils method fieldNodeFormat.

//    * The name value pairs of this annotation. Each name value pair is stored
//    * as two consecutive elements in the list. The name is a {@link String},
//    * and the value may be a {@link Byte}, {@link Boolean}, {@link Character},
//    * {@link Short}, {@link Integer}, {@link Long}, {@link Float},
//    * {@link Double}, {@link String} or {@link org.objectweb.asm.Type}, or an
//    * two elements String array (for enumeration values), a
//    * {@link AnnotationNode}, or a {@link List} of values of one of the
//    * preceding types. The list may be <tt>null</tt> if there is no name
//    * value pair.
public static String fieldNodeFormat(Collection<FieldNode> fieldNodes) {
    StringBuilder s = new StringBuilder();
    int n = 0;
    for (FieldNode fieldNode : fieldNodes) {
        if (n > 0) {
            s.append(" ");
        }
        s.append("'").append(fieldNodeFormat(fieldNode)).append("'");
        n++;
    }
    return s.toString();
}
Also used : FieldNode(org.objectweb.asm.tree.FieldNode)

Aggregations

FieldNode (org.objectweb.asm.tree.FieldNode)19 ClassNode (org.objectweb.asm.tree.ClassNode)11 MethodNode (org.objectweb.asm.tree.MethodNode)8 ClassReader (org.objectweb.asm.ClassReader)6 ArrayList (java.util.ArrayList)3 ClassWriter (org.objectweb.asm.ClassWriter)3 AnnotationNode (org.objectweb.asm.tree.AnnotationNode)3 List (java.util.List)2 Type (org.objectweb.asm.Type)2 FieldInsnNode (org.objectweb.asm.tree.FieldInsnNode)2 InnerClassNode (org.objectweb.asm.tree.InnerClassNode)2 MethodInsnNode (org.objectweb.asm.tree.MethodInsnNode)2 ModContainer (cpw.mods.fml.common.ModContainer)1 ArtifactVersion (cpw.mods.fml.common.versioning.ArtifactVersion)1 DefaultArtifactVersion (cpw.mods.fml.common.versioning.DefaultArtifactVersion)1 VersionRange (cpw.mods.fml.common.versioning.VersionRange)1 IOException (java.io.IOException)1 Nullable (javax.annotation.Nullable)1 Event (net.minecraftforge.fml.common.eventhandler.Event)1 ClassSet (org.apache.drill.exec.compile.ClassTransformer.ClassSet)1