use of org.objectweb.asm.tree.MethodNode in project DynamicSurroundings by OreCruncher.
the class PatchSoundManagerPlayTime method transmorgrify.
@Override
public boolean transmorgrify(final ClassNode cn) {
final String[] names = { "playSound", "func_148611_c" };
final String sig = "(Lnet/minecraft/client/audio/ISound;)V";
final MethodNode m = findMethod(cn, sig, names);
if (m != null) {
logMethod(Transformer.log(), m, "Found!");
for (int i = 0; i < m.instructions.size(); i++) {
final AbstractInsnNode node = m.instructions.get(i);
if (node instanceof IntInsnNode) {
final IntInsnNode intNode = (IntInsnNode) node;
if (intNode.operand == 20) {
m.instructions.set(node, new IntInsnNode(Opcodes.BIPUSH, 0));
return true;
}
}
}
} else {
Transformer.log().error("Unable to locate method {}{}", names[0], sig);
}
Transformer.log().info("Unable to patch [{}]!", getClassName());
return false;
}
use of org.objectweb.asm.tree.MethodNode in project DynamicSurroundings by OreCruncher.
the class PatchSoundManagerSync method transmorgrify.
@Override
public boolean transmorgrify(final ClassNode cn) {
// Loop through the method nodes setting the synchronized bit
for (final MethodNode m : cn.methods) {
if (!m.name.startsWith("<") && (m.access & Opcodes.ACC_PUBLIC) != 0 && (m.access & Opcodes.ACC_SYNCHRONIZED) == 0) {
logMethod(Transformer.log(), m, "Synchronized!");
m.access |= Opcodes.ACC_SYNCHRONIZED;
}
}
return true;
}
use of org.objectweb.asm.tree.MethodNode in project DynamicSurroundings by OreCruncher.
the class SoundCrashFixLibrary method transmorgrify.
@Override
public boolean transmorgrify(final ClassNode cn) {
final String name = "removeSource";
final String sig = "(Ljava/lang/String;)V";
final MethodNode m = findMethod(cn, sig, name);
if (m != null) {
for (final Iterator<?> iterator = m.instructions.iterator(); iterator.hasNext(); ) {
final AbstractInsnNode insn = (AbstractInsnNode) iterator.next();
if (insn instanceof MethodInsnNode && ((MethodInsnNode) insn).owner.equals("paulscode/sound/Source") && ((MethodInsnNode) insn).name.equals("cleanup")) {
m.instructions.insertBefore(insn, new MethodInsnNode(Opcodes.INVOKESTATIC, "org/blockartistry/DynSurround/client/sound/fix/SoundFixMethods", "cleanupSource", "(Lpaulscode/sound/Source;)V", false));
m.instructions.remove(insn);
return true;
}
}
} else {
Transformer.log().error("Unable to locate method {}{}", name, sig);
}
Transformer.log().info("Unable to patch [{}]!", getClassName());
return false;
}
use of org.objectweb.asm.tree.MethodNode in project BuildCraft by BuildCraft.
the class EventBusProviderASM method generateGenerator.
private byte[] generateGenerator(Class<? extends IEventHandler<?>> handlerClass, Class<?> parClass, String clsName) {
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
ClassNode node = new ClassNode();
node.name = clsName.replace('.', '/');
node.version = Opcodes.V1_6;
node.access = Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL;
node.interfaces = Lists.newArrayList(IEventHandlerProvider.class.getName().replace('.', '/'));
node.superName = "java/lang/Object";
// Method:
// public ClassName() {
// super();
// }
{
MethodNode consturctorMethod = new MethodNode();
consturctorMethod.access = Opcodes.ACC_PUBLIC;
consturctorMethod.desc = "()V";
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 InsnNode(Opcodes.RETURN));
node.methods.add(consturctorMethod);
}
// Method:
// public IEventHandler createNewHandler(Object obj) {
// return new ClassHandler(obj);
// }
{
MethodNode generationMethod = new MethodNode();
// public final void handle(Object)
generationMethod.access = Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL;
generationMethod.desc = "(Ljava/lang/Object;)Lbuildcraft/core/lib/event/IEventHandler;";
generationMethod.name = "createNewHandler";
generationMethod.exceptions = Lists.newArrayList();
{
generationMethod.instructions.add(new TypeInsnNode(Opcodes.NEW, Type.getInternalName(handlerClass)));
generationMethod.instructions.add(new InsnNode(Opcodes.DUP));
generationMethod.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1));
generationMethod.instructions.add(new TypeInsnNode(Opcodes.CHECKCAST, Type.getInternalName(parClass)));
generationMethod.instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, Type.getInternalName(handlerClass), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(parClass)), false));
generationMethod.instructions.add(new InsnNode(Opcodes.ARETURN));
}
node.methods.add(generationMethod);
}
node.accept(writer);
return writer.toByteArray();
}
use of org.objectweb.asm.tree.MethodNode 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;
}
Aggregations