Search in sources :

Example 81 with ClassNode

use of org.objectweb.asm.tree.ClassNode in project BuildCraft by BuildCraft.

the class EventBusProviderASM method generateDirectHandler.

private byte[] generateDirectHandler(Method meth, Class<?> parClass, String clsName) {
    ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
    ClassNode node = new ClassNode();
    node.name = clsName.replace('.', '/');
    node.access = Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL;
    node.interfaces = Lists.newArrayList(IEventHandler.class.getName().replace('.', '/'));
    node.version = Opcodes.V1_6;
    node.superName = "java/lang/Object";
    String fd = Type.getDescriptor(meth.getDeclaringClass());
    node.fields.add(new FieldNode(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, "listener", fd, null, null));
    // This method does:
    // public ClassName(ListenerObject obj) {
    // super();
    // this.listener = obj;
    // }
    {
        MethodNode consturctorMethod = new MethodNode();
        consturctorMethod.access = Opcodes.ACC_PUBLIC;
        consturctorMethod.desc = Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(meth.getDeclaringClass()));
        consturctorMethod.name = "<init>";
        consturctorMethod.exceptions = Lists.newArrayList();
        consturctorMethod.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
        consturctorMethod.instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false));
        consturctorMethod.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
        consturctorMethod.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1));
        consturctorMethod.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, node.name, "listener", fd));
        consturctorMethod.instructions.add(new InsnNode(Opcodes.RETURN));
        node.methods.add(consturctorMethod);
    }
    // This method does:
    // public final void handle(Object event) {
    // if (!(event instanceof EventClass)) return;
    // listener.<method_name>((EventClass) event);
    // }
    {
        MethodNode generationMethod = new MethodNode();
        // public final void handle(Object)
        generationMethod.access = Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL;
        generationMethod.desc = Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(Object.class));
        generationMethod.name = "handle";
        generationMethod.exceptions = Lists.newArrayList();
        // This block does:
        // if (!(event instanceof EventClass)) return;
        {
            // ADD the first object (given as [this, event])
            // -> event
            generationMethod.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1));
            // event -> event instanceof PAR_CLASS -> boolean
            generationMethod.instructions.add(new TypeInsnNode(Opcodes.INSTANCEOF, Type.getInternalName(parClass)));
            LabelNode instanceLabel = new LabelNode();
            // boolean -> if (boolean) GOTO instanceLabel ->
            generationMethod.instructions.add(new JumpInsnNode(Opcodes.IFNE, instanceLabel));
            // return;
            generationMethod.instructions.add(new InsnNode(Opcodes.RETURN));
            generationMethod.instructions.add(instanceLabel);
        }
        // This block does:
        // listener.<method_name>(event);
        {
            generationMethod.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
            // -> ListenerObject
            String desc = Type.getDescriptor(meth.getDeclaringClass());
            generationMethod.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, node.name, "listener", desc));
            // -> Object
            generationMethod.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1));
            // CheckCast
            generationMethod.instructions.add(new TypeInsnNode(Opcodes.CHECKCAST, Type.getInternalName(parClass)));
            // ListenerObject, EventObject -> <method_name> ->
            generationMethod.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, Type.getInternalName(meth.getDeclaringClass()), meth.getName(), Type.getMethodDescriptor(meth), false));
        }
        // return;
        generationMethod.instructions.add(new InsnNode(Opcodes.RETURN));
        node.methods.add(generationMethod);
    }
    node.accept(writer);
    byte[] bytecode = writer.toByteArray();
    return bytecode;
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) ClassNode(org.objectweb.asm.tree.ClassNode) FieldNode(org.objectweb.asm.tree.FieldNode) FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) ClassWriter(org.objectweb.asm.ClassWriter) FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) InsnNode(org.objectweb.asm.tree.InsnNode) MethodNode(org.objectweb.asm.tree.MethodNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode)

Example 82 with ClassNode

use of org.objectweb.asm.tree.ClassNode in project SpecialSource by md-5.

the class Jar method getNode.

/**
 * Get the {@link ClassNode} object corresponding to this class. Takes the
 * internal name of a class (/)
 *
 * @param clazz
 * @return
 */
public ClassNode getNode(String clazz) {
    // No luck, so lets try read it
    try (InputStream is = getClass(clazz)) {
        if (is != null) {
            ClassReader cr = new ClassReader(is);
            // Process it
            ClassNode node = new ClassNode();
            cr.accept(node, 0);
            return node;
        }
    } catch (IOException ex) {
        // Wrap this in a runtime exception so it can conform easily to interfaces
        throw new RuntimeException(clazz, ex);
    }
    // We get here if the class isn't in the jar
    return null;
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) InputStream(java.io.InputStream) ClassReader(org.objectweb.asm.ClassReader) IOException(java.io.IOException)

Example 83 with ClassNode

use of org.objectweb.asm.tree.ClassNode in project SpecialSource by md-5.

the class ClassLoaderProvider method getParents.

@Override
@SuppressWarnings("unchecked")
public Collection<String> getParents(String owner) {
    // TODO: ToInternalName
    String ownerInternalName = owner.replace('.', '/').concat(".class");
    try (InputStream input = classLoader.getResourceAsStream(ownerInternalName)) {
        if (input == null) {
            return null;
        }
        ClassReader cr = new ClassReader(input);
        ClassNode node = new ClassNode();
        cr.accept(node, 0);
        Collection<String> parents = new HashSet<String>();
        for (String iface : node.interfaces) {
            parents.add(iface);
        }
        if (node.superName != null) {
            parents.add(node.superName);
        }
        return parents;
    } catch (Exception ex) {
    // Just ignore this, means that we couldn't get any lookup for the specified class
    }
    return null;
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) InputStream(java.io.InputStream) ClassReader(org.objectweb.asm.ClassReader) IOException(java.io.IOException) HashSet(java.util.HashSet)

Example 84 with ClassNode

use of org.objectweb.asm.tree.ClassNode in project SpecialSource by md-5.

the class JarComparer method getDeclarer.

public String getDeclarer(String currentParent, Ownable node) {
    String newParent = null;
    ClassNode n = jarRepo.findClass(currentParent);
    if (n == null) {
        return newParent;
    }
    switch(node.type) {
        case FIELD:
            for (FieldNode field : n.fields) {
                if (field.name.equals(node.name) && field.desc.equals(node.descriptor)) {
                    newParent = currentParent;
                    fields.remove(new Ownable(NodeType.FIELD, currentParent, node.name, node.descriptor, node.access));
                    break;
                }
            }
            break;
        case METHOD:
            for (MethodNode method : n.methods) {
                if (method.name.equals(node.name) && method.desc.equals(node.descriptor) && (method.access == -1 || (!Modifier.isPrivate(method.access) && !Modifier.isStatic(method.access)))) {
                    newParent = currentParent;
                    methods.remove(new Ownable(NodeType.METHOD, currentParent, node.name, node.descriptor, node.access));
                    methods.remove(node);
                    break;
                }
            }
            break;
    }
    if ((node.owner.equals(newParent) || newParent == null) && (node.access == -1 || (!Modifier.isPrivate(node.access) && !Modifier.isStatic(node.access)))) {
        Collection<String> parents = inheritance.getParents(currentParent);
        if (parents != null) {
            // climb the inheritance tree
            for (String parent : parents) {
                newParent = getDeclarer(parent, node);
                if (newParent != null) {
                    return newParent;
                }
            }
        }
    }
    return newParent;
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) FieldNode(org.objectweb.asm.tree.FieldNode) MethodNode(org.objectweb.asm.tree.MethodNode)

Example 85 with ClassNode

use of org.objectweb.asm.tree.ClassNode in project SpecialSource by md-5.

the class JarRemapper method remapClassFile.

@SuppressWarnings("unchecked")
private byte[] remapClassFile(ClassReader reader, final ClassRepo repo) {
    if (preProcessor != null) {
        byte[] pre = preProcessor.process(reader);
        if (pre != null) {
            reader = new ClassReader(pre);
        }
    }
    ClassNode node = new ClassNode();
    RemappingClassAdapter mapper = new RemappingClassAdapter(node, this, repo);
    reader.accept(mapper, readerFlags);
    ClassWriter wr = new ClassWriter(writerFlags);
    node.accept(wr);
    if (SpecialSource.identifier != null) {
        wr.newUTF8(SpecialSource.identifier);
    }
    return (postProcessor != null) ? postProcessor.process(wr.toByteArray()) : wr.toByteArray();
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) ClassReader(org.objectweb.asm.ClassReader) ClassWriter(org.objectweb.asm.ClassWriter)

Aggregations

ClassNode (org.objectweb.asm.tree.ClassNode)323 ClassReader (org.objectweb.asm.ClassReader)148 MethodNode (org.objectweb.asm.tree.MethodNode)120 ClassWriter (org.objectweb.asm.ClassWriter)70 IOException (java.io.IOException)44 AbstractInsnNode (org.objectweb.asm.tree.AbstractInsnNode)37 MethodInsnNode (org.objectweb.asm.tree.MethodInsnNode)34 InsnList (org.objectweb.asm.tree.InsnList)29 FieldNode (org.objectweb.asm.tree.FieldNode)28 ArrayList (java.util.ArrayList)27 Test (org.junit.Test)26 VarInsnNode (org.objectweb.asm.tree.VarInsnNode)26 Label (org.objectweb.asm.Label)21 InputStream (java.io.InputStream)20 FieldInsnNode (org.objectweb.asm.tree.FieldInsnNode)18 JumpInsnNode (org.objectweb.asm.tree.JumpInsnNode)18 InnerClassNode (org.objectweb.asm.tree.InnerClassNode)17 InsnNode (org.objectweb.asm.tree.InsnNode)17 Method (java.lang.reflect.Method)16 List (java.util.List)16