List of usage examples for org.objectweb.asm Opcodes INVOKESPECIAL
int INVOKESPECIAL
To view the source code for org.objectweb.asm Opcodes INVOKESPECIAL.
Click Source Link
From source file:org.spongepowered.asm.mixin.transformer.MixinTargetContext.java
License:MIT License
/** * Handle "imaginary super" invokations, these are invokations in * non-derived mixins for accessing methods known to exist in a supermixin * which is not directly inherited by this mixix. The method can only call * its <b>own</b> super-implmentation and the methd must also be tagged with * {@link SoftOverride} to indicate that the method must exist in a super * class./*from w ww . j a va 2s . c o m*/ * * @param method Method being processed * @param fieldInsn the GETFIELD insn which access the pseudo-field which is * used as a handle to the superclass */ private void processImaginarySuper(MethodNode method, FieldInsnNode fieldInsn) { if (fieldInsn.getOpcode() != Opcodes.GETFIELD) { if (MixinTargetContext.INIT.equals(method.name)) { throw new InvalidMixinException(this, "Illegal imaginary super declaration: field " + fieldInsn.name + " must not specify an initialiser"); } throw new InvalidMixinException(this, "Illegal imaginary super access: found " + ASMHelper.getOpcodeName(fieldInsn.getOpcode()) + " opcode in " + method.name + method.desc); } if ((method.access & Opcodes.ACC_PRIVATE) != 0 || (method.access & Opcodes.ACC_STATIC) != 0) { throw new InvalidMixinException(this, "Illegal imaginary super access: method " + method.name + method.desc + " is private or static"); } if (ASMHelper.getInvisibleAnnotation(method, SoftOverride.class) == null) { throw new InvalidMixinException(this, "Illegal imaginary super access: method " + method.name + method.desc + " is not decorated with @SoftOverride"); } for (Iterator<AbstractInsnNode> methodIter = method.instructions .iterator(method.instructions.indexOf(fieldInsn)); methodIter.hasNext();) { AbstractInsnNode insn = methodIter.next(); if (insn instanceof MethodInsnNode) { MethodInsnNode methodNode = (MethodInsnNode) insn; if (methodNode.owner.equals(this.getClassRef()) && methodNode.name.equals(method.name) && methodNode.desc.equals(method.desc)) { methodNode.setOpcode(Opcodes.INVOKESPECIAL); this.updateStaticBinding(method, methodNode); return; } } } throw new InvalidMixinException(this, "Illegal imaginary super access: could not find INVOKE for " + method.name + method.desc); }
From source file:org.spongepowered.asm.mixin.transformer.MixinTransformer.java
License:MIT License
/** * Identifies line numbers in the supplied ctor which correspond to the * start and end of the method body./*w ww . j a va 2 s . c o m*/ * * @param ctor * @return range indicating the line numbers of the specified constructor * and the position of the superclass ctor invocation */ private Range getConstructorRange(MethodNode ctor) { int line = 0, start = 0, end = 0, superIndex = -1; for (Iterator<AbstractInsnNode> iter = ctor.instructions.iterator(); iter.hasNext();) { AbstractInsnNode insn = iter.next(); if (insn instanceof LineNumberNode) { line = ((LineNumberNode) insn).line; } else if (insn instanceof MethodInsnNode) { if (insn.getOpcode() == Opcodes.INVOKESPECIAL && MixinTransformer.INIT.equals(((MethodInsnNode) insn).name) && superIndex == -1) { superIndex = ctor.instructions.indexOf(insn); start = line; } } else if (insn.getOpcode() == Opcodes.RETURN) { end = line; } } return new Range(start, end, superIndex); }
From source file:org.spongepowered.asm.mixin.transformer.MixinTransformer.java
License:MIT License
/** * Inject initialiser code into the target constructor * /*w w w . j a va 2 s . c o m*/ * @param ctor * @param initialiser */ private void injectInitialiser(MethodNode ctor, InsnList initialiser) { for (Iterator<AbstractInsnNode> iter = ctor.instructions.iterator(0); iter.hasNext();) { AbstractInsnNode insn = iter.next(); if (insn.getOpcode() == Opcodes.INVOKESPECIAL && MixinTransformer.INIT.equals(((MethodInsnNode) insn).name)) { ctor.instructions.insert(insn, initialiser); } } }
From source file:org.spongepowered.despector.emitter.bytecode.instruction.BytecodeInstanceMethodInvokeEmitter.java
License:Open Source License
public int getOpcode(InstanceMethodInvoke.Type type) { switch (type) { case INTERFACE: return Opcodes.INVOKEINTERFACE; case SPECIAL: return Opcodes.INVOKESPECIAL; case VIRTUAL: default:/*from w w w.j a v a 2 s. c o m*/ return Opcodes.INVOKEVIRTUAL; } }
From source file:org.spongepowered.mod.asm.transformers.BaseEventTransformer.java
License:MIT License
@Override public byte[] transform(String name, String transformedName, byte[] bytes) { if (bytes == null || name == null) { return bytes; }/* ww w . j av a2 s.c o m*/ try { ClassReader cr = new ClassReader(bytes); ClassNode classNode = new ClassNode(); cr.accept(classNode, 0); String parentName = classNode.superName.replace('/', '.'); Class<?> parent = this.getClass().getClassLoader().loadClass(parentName); // Skip classes that do not implement SpongeAPI Event, or extend other classes // This implies that there will be issues with custom event classes that extend a superclass that does not fit these conditions itself // However, this is a fairly fundamental JVM limitation if ((!Object.class.equals(parent.getSuperclass())) || (!Event.class.isAssignableFrom(parent))) { return bytes; } // Add forwarding methods ASMHelper.addAndReplaceMethod(classNode, EventTransformer.createGetGameMethod()); ASMHelper.addAndReplaceMethod(classNode, EventTransformer.createGetSimpleNameMethod()); ASMHelper.addAndReplaceMethod(classNode, EventTransformer.createIsCancellableMethod()); ASMHelper.addAndReplaceMethod(classNode, EventTransformer.createIsCancelledMethod()); ASMHelper.addAndReplaceMethod(classNode, EventTransformer.createSetCancelledMethod()); // Change super-class classNode.superName = "net/minecraftforge/fml/common/eventhandler/Event"; // Replace super() call in constructor so that it points to the new super-class MethodNode method = ASMHelper.findMethod(classNode, "<init>", "()V"); ListIterator<AbstractInsnNode> instructions = method.instructions.iterator(); while (instructions.hasNext()) { AbstractInsnNode insn = instructions.next(); if (insn.getOpcode() == Opcodes.INVOKESPECIAL) { MethodInsnNode methodInsn = new MethodInsnNode(Opcodes.INVOKESPECIAL, classNode.superName, "<init>", "()V", false); instructions.remove(); instructions.add(methodInsn); break; } } ClassWriter cw = new ClassWriter(cr, COMPUTE_MAXS | COMPUTE_FRAMES); classNode.accept(cw); return cw.toByteArray(); } catch (Throwable t) { t.printStackTrace(); return bytes; } }
From source file:org.spongepowered.mod.asm.transformers.EventTransformer.java
License:MIT License
protected static MethodNode createGetSimpleNameMethod() { MethodNode methodNode = new MethodNode(Opcodes.ASM4, Opcodes.ACC_PUBLIC, "getSimpleName", "()Ljava/lang/String;", null, null); methodNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); methodNode.instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false)); methodNode.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Class", "getSimpleName", "()Ljava/lang/String;", false)); methodNode.instructions.add(new InsnNode(Opcodes.ARETURN)); methodNode.maxLocals = 1;//from w w w .java 2s. co m methodNode.maxStack = 1; return methodNode; }
From source file:org.spongepowered.mod.asm.transformers.EventTransformer.java
License:MIT License
protected static MethodNode createIsCancellableMethod() { MethodNode methodNode = new MethodNode(Opcodes.ASM4, Opcodes.ACC_PUBLIC, "isCancellable", "()Z", null, null);// w w w . jav a2 s.c o m methodNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); methodNode.instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "net/minecraftforge/fml/common/eventhandler/Event", "isCancelable", "()Z", false)); methodNode.instructions.add(new InsnNode(Opcodes.IRETURN)); methodNode.maxLocals = 1; methodNode.maxStack = 1; return methodNode; }
From source file:org.spongepowered.mod.asm.transformers.EventTransformer.java
License:MIT License
protected static MethodNode createIsCancelledMethod() { MethodNode methodNode = new MethodNode(Opcodes.ASM4, Opcodes.ACC_PUBLIC, "isCancelled", "()Z", null, null); methodNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); methodNode.instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "net/minecraftforge/fml/common/eventhandler/Event", "isCanceled", "()Z", false)); methodNode.instructions.add(new InsnNode(Opcodes.IRETURN)); methodNode.maxLocals = 1;// w w w .ja va 2 s. c o m methodNode.maxStack = 1; return methodNode; }
From source file:org.spongepowered.mod.asm.transformers.EventTransformer.java
License:MIT License
protected static MethodNode createSetCancelledMethod() { MethodNode methodNode = new MethodNode(Opcodes.ASM4, Opcodes.ACC_PUBLIC, "setCancelled", "(Z)V", null, null);//from w w w .jav a 2 s . c o m methodNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); methodNode.instructions.add(new VarInsnNode(Opcodes.ILOAD, 1)); methodNode.instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "net/minecraftforge/fml/common/eventhandler/Event", "setCanceled", "(Z)V", false)); methodNode.instructions.add(new InsnNode(Opcodes.RETURN)); methodNode.maxLocals = 1; methodNode.maxStack = 1; return methodNode; }
From source file:org.spongepowered.mod.asm.util.ASMEventListenerFactory.java
License:MIT License
@SuppressWarnings("unchecked") private static <T> Class<T> createClass(Class<T> interf, Method input, Method output) { String className = getClassName(interf, input, output); ClassWriter cwBase = new ClassWriter(0); CheckClassAdapter cw = new CheckClassAdapter(cwBase); MethodVisitor mv;/*from w w w . j a va 2 s .c om*/ String classNameDesc = className.replace('.', '/'); String interfaceInternalName = Type.getInternalName(interf); String inputName = input.getName(); String inputMethodDescriptor = Type.getMethodDescriptor(input); String outputParameterTypeIntName = Type.getInternalName(output.getParameterTypes()[0]); String outputTargetTypeIntName = Type.getInternalName(output.getDeclaringClass()); String outputMethodDescriptor = Type.getMethodDescriptor(output); String outputName = output.getName(); boolean isOutputInterface = output.getDeclaringClass().isInterface(); // A new class of the following form is created, with a unique name // // package org.spongepowered.mod.asm; // public class <className> extends java.lang.Object implements <interf> // // private final Object target // // public <className> (java.lang.Object target) { // super(); // this.target = target; // return; // } // // public void <inputMethod> (<inputMethodType event) { // ((outputTargetType) this.target).outputMethod((outputParameteType) event); // return // } // } // package org.spongepowered.mod.asm; // public class <className> extends java.lang.Object implements <interf> cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER, classNameDesc, null, "java/lang/Object", new String[] { interfaceInternalName }); // private final Object target cw.visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, "target", "Ljava/lang/Object;", null, null); // Constructor // public UniqueClass (java.lang.Object target) { mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "(Ljava/lang/Object;)V", null, null); mv.visitCode(); // super(); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); // this.target = target; mv.visitVarInsn(Opcodes.ALOAD, 0); // Loads this mv.visitVarInsn(Opcodes.ALOAD, 1); // Loads target (from input) mv.visitFieldInsn(Opcodes.PUTFIELD, classNameDesc, "target", "Ljava/lang/Object;"); // return; mv.visitInsn(Opcodes.RETURN); // } // 2 localvars due to inputs: this, target // 2 items on stack after double ALOAD mv.visitMaxs(2, 2); mv.visitEnd(); // Callback method // public void <inputMethod> (<inputMethodType event) { mv = cw.visitMethod(Opcodes.ACC_PUBLIC, inputName, inputMethodDescriptor, null, null); mv.visitCode(); // push((casted) this.target) mv.visitVarInsn(Opcodes.ALOAD, 0); // Loads this mv.visitFieldInsn(Opcodes.GETFIELD, classNameDesc, "target", "Ljava/lang/Object;"); mv.visitTypeInsn(Opcodes.CHECKCAST, outputTargetTypeIntName); // push((casted) event) mv.visitVarInsn(Opcodes.ALOAD, 1); // Loads method parameter 0 mv.visitTypeInsn(Opcodes.CHECKCAST, outputParameterTypeIntName); // ((outputTargetType) this.target).outputMethod((outputParameteType) event); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, outputTargetTypeIntName, outputName, outputMethodDescriptor, isOutputInterface); // return mv.visitInsn(Opcodes.RETURN); // } mv.visitMaxs(2, 2); mv.visitEnd(); cw.visitEnd(); byte[] bytes = cwBase.toByteArray(); return (Class<T>) loader.defineClass(className, bytes); }