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;
}
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;
}
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;
}
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;
}
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();
}
Aggregations