List of usage examples for org.objectweb.asm.tree AbstractInsnNode getOpcode
public int getOpcode()
From source file:org.spongepowered.despector.ast.io.insn.OpcodeDecompiler.java
License:Open Source License
private void handleIntermediate(AbstractInsnNode next) { if (next instanceof JumpInsnNode) { if (next.getOpcode() == GOTO) { if (!this.stack.isEmpty()) { intermediate_stack = true; this.intermediates.add(new IntermediateStackValue(this.stack.pop())); }/*from w ww.j a v a 2 s .c om*/ this.intermediates.add(new IntermediateGoto((JumpInsnNode) next)); } else if (next.getOpcode() == IF_ACMPEQ || next.getOpcode() == IF_ACMPNE || next.getOpcode() == IF_ICMPEQ || next.getOpcode() == IF_ICMPGE || next.getOpcode() == IF_ICMPGT || next.getOpcode() == IF_ICMPLE || next.getOpcode() == IF_ICMPLT || next.getOpcode() == IF_ICMPNE) { Instruction right = this.stack.pop(); Instruction left = this.stack.pop(); this.intermediates.add(new IntermediateCompareJump((JumpInsnNode) next, left, right)); } else { Instruction condition = this.stack.pop(); this.intermediates.add(new IntermediateConditionalJump((JumpInsnNode) next, condition)); } } else if (next instanceof TableSwitchInsnNode) { this.intermediates.add(new IntermediateTableSwitch((TableSwitchInsnNode) next, this.stack.pop())); } else if (next instanceof LookupSwitchInsnNode) { this.intermediates.add(new IntermediateLookupSwitch((LookupSwitchInsnNode) next, this.stack.pop())); } else if (next instanceof LineNumberNode) { } else if (next instanceof LabelNode) { this.intermediates.add(new IntermediateLabel((LabelNode) next)); } else if (next instanceof FrameNode) { if (!this.stack.isEmpty()) { this.intermediates.add(this.intermediates.size() - 1, new IntermediateStackValue(this.stack.pop())); this.stack.push(new DummyInstruction()); intermediate_stack = false; } this.intermediates.add(new IntermediateFrame((FrameNode) next)); } else { if (intermediate_stack && !this.stack.isEmpty() && next.getOpcode() >= IRETURN && next.getOpcode() <= ARETURN) { this.intermediates.add(this.intermediates.size() - 1, new IntermediateStackValue(this.stack.pop())); this.stack.push(new DummyInstruction()); intermediate_stack = false; } OpHandler handle = handlers[next.getOpcode()]; if (handle == null) { System.err.println("Unsupported opcode " + next.getOpcode()); throw new IllegalStateException(); } handle.handle(this, next); } }
From source file:org.spongepowered.granite.launch.transformers.AccessTransformer.java
License:MIT License
@Override public byte[] transform(String name, String transformedName, byte[] bytes) { if (bytes == null || !this.modifiers.containsKey(transformedName)) { return bytes; }/*from w w w .ja v a 2 s.c o m*/ ClassNode classNode = new ClassNode(); ClassReader reader = new ClassReader(bytes); reader.accept(classNode, 0); for (Modifier m : this.modifiers.get(transformedName)) { if (m.isClass) { // Class classNode.access = m.transform(classNode.access); } else if (m.desc == null) { // Field for (FieldNode fieldNode : classNode.fields) { if (m.wildcard || fieldNode.name.equals(m.name)) { fieldNode.access = m.transform(fieldNode.access); if (!m.wildcard) { break; } } } } else { List<MethodNode> overridable = null; for (MethodNode methodNode : classNode.methods) { if (m.wildcard || (methodNode.name.equals(m.name) && methodNode.desc.equals(m.desc))) { boolean wasPrivate = (methodNode.access & ACC_PRIVATE) != 0; methodNode.access = m.transform(methodNode.access); // Constructors always use INVOKESPECIAL // if we changed from private to something else we need to replace all INVOKESPECIAL calls to this method with INVOKEVIRTUAL // so that overridden methods will be called. Only need to scan this class, because obviously the method was private. if (!methodNode.name.equals("<init>") && wasPrivate && (methodNode.access & ACC_PRIVATE) == 0) { if (overridable == null) { overridable = new ArrayList<>(3); } overridable.add(methodNode); } if (!m.wildcard) { break; } } } if (overridable != null) { for (MethodNode methodNode : classNode.methods) { for (Iterator<AbstractInsnNode> itr = methodNode.instructions.iterator(); itr.hasNext();) { AbstractInsnNode insn = itr.next(); if (insn.getOpcode() == INVOKESPECIAL) { MethodInsnNode mInsn = (MethodInsnNode) insn; for (MethodNode replace : overridable) { if (replace.name.equals(mInsn.name) && replace.desc.equals(mInsn.desc)) { mInsn.setOpcode(INVOKEVIRTUAL); break; } } } } } } } } ClassWriter writer = new ClassWriter(0); classNode.accept(writer); return writer.toByteArray(); }
From source file:org.spongepowered.lantern.launch.AccessTransformer.java
License:MIT License
@Override public byte[] transform(String name, String transformedName, byte[] bytes) { if (bytes == null || !this.modifiers.containsKey(transformedName)) { return bytes; }//from w ww.j a v a 2 s . c o m ClassNode classNode = new ClassNode(); ClassReader reader = new ClassReader(bytes); reader.accept(classNode, 0); for (Modifier m : this.modifiers.get(transformedName)) { if (m.isClass) { // Class classNode.access = m.transform(classNode.access); } else if (m.desc == null) { // Field for (FieldNode fieldNode : classNode.fields) { if (m.wildcard || fieldNode.name.equals(m.name)) { fieldNode.access = m.transform(fieldNode.access); if (!m.wildcard) { break; } } } } else { List<MethodNode> overridable = null; for (MethodNode methodNode : classNode.methods) { if (m.wildcard || (methodNode.name.equals(m.name) && methodNode.desc.equals(m.desc))) { boolean wasPrivate = (methodNode.access & ACC_PRIVATE) != 0; methodNode.access = m.transform(methodNode.access); // Constructors always use INVOKESPECIAL // if we changed from private to something else we need to replace all INVOKESPECIAL calls to this method with INVOKEVIRTUAL // so that overridden methods will be called. Only need to scan this class, because obviously the method was private. if (!methodNode.name.equals("<init>") && wasPrivate && (methodNode.access & ACC_PRIVATE) == 0) { if (overridable == null) { overridable = Lists.newArrayListWithExpectedSize(3); } overridable.add(methodNode); } if (!m.wildcard) { break; } } } if (overridable != null) { for (MethodNode methodNode : classNode.methods) { for (Iterator<AbstractInsnNode> itr = methodNode.instructions.iterator(); itr.hasNext();) { AbstractInsnNode insn = itr.next(); if (insn.getOpcode() == INVOKESPECIAL) { MethodInsnNode mInsn = (MethodInsnNode) insn; for (MethodNode replace : overridable) { if (replace.name.equals(mInsn.name) && replace.desc.equals(mInsn.desc)) { mInsn.setOpcode(INVOKEVIRTUAL); break; } } } } } } } } ClassWriter writer = new ClassWriter(0); classNode.accept(writer); return writer.toByteArray(); }
From source file:org.spongepowered.lwts.transformer.AccessTransformer.java
License:MIT License
@Override public byte[] transform(String name, String transformedName, byte[] bytes) { if (this.modifiers == null) { this.modifiers = this.processor.build(); this.processor = null; }//from w ww. j av a 2s . co m if (bytes == null || !this.modifiers.containsKey(transformedName)) { return bytes; } ClassNode classNode = new ClassNode(); ClassReader reader = new ClassReader(bytes); reader.accept(classNode, 0); for (Modifier m : this.modifiers.get(transformedName)) { if (m.isClass) { // Class classNode.access = m.transform(classNode.access); } else if (m.desc == null) { // Field for (FieldNode fieldNode : classNode.fields) { if (m.wildcard || fieldNode.name.equals(m.name)) { fieldNode.access = m.transform(fieldNode.access); if (!m.wildcard) { break; } } } } else { List<MethodNode> overridable = null; for (MethodNode methodNode : classNode.methods) { if (m.wildcard || (methodNode.name.equals(m.name) && methodNode.desc.equals(m.desc))) { boolean wasPrivate = (methodNode.access & ACC_PRIVATE) != 0; methodNode.access = m.transform(methodNode.access); // Constructors always use INVOKESPECIAL // if we changed from private to something else we need to replace all INVOKESPECIAL calls to this method with INVOKEVIRTUAL // so that overridden methods will be called. Only need to scan this class, because obviously the method was private. if (!methodNode.name.equals("<init>") && wasPrivate && (methodNode.access & ACC_PRIVATE) == 0) { if (overridable == null) { overridable = Lists.newArrayListWithExpectedSize(3); } overridable.add(methodNode); } if (!m.wildcard) { break; } } } if (overridable != null) { for (MethodNode methodNode : classNode.methods) { for (Iterator<AbstractInsnNode> itr = methodNode.instructions.iterator(); itr.hasNext();) { AbstractInsnNode insn = itr.next(); if (insn.getOpcode() == INVOKESPECIAL) { MethodInsnNode mInsn = (MethodInsnNode) insn; for (MethodNode replace : overridable) { if (replace.name.equals(mInsn.name) && replace.desc.equals(mInsn.desc)) { mInsn.setOpcode(INVOKEVIRTUAL); break; } } } } } } } } ClassWriter writer = new ClassWriter(0); classNode.accept(writer); return writer.toByteArray(); }
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; }/*from w ww .ja v a 2 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.MixinTransformer.java
License:MIT License
/** * Handles appending instructions from the source method to the target method * /* ww w .jav a 2s . com*/ * @param targetClass * @param targetMethodName * @param sourceMethod */ private void appendInsns(ClassNode targetClass, String targetMethodName, MethodNode sourceMethod) { if (Type.getReturnType(sourceMethod.desc) != Type.VOID_TYPE) { throw new IllegalArgumentException("Attempted to merge insns into a method which does not return void"); } if (targetMethodName == null || targetMethodName.length() == 0) { targetMethodName = sourceMethod.name; } for (MethodNode method : targetClass.methods) { if ((targetMethodName.equals(method.name)) && sourceMethod.desc.equals(method.desc)) { AbstractInsnNode returnNode = null; Iterator<AbstractInsnNode> findReturnIter = method.instructions.iterator(); while (findReturnIter.hasNext()) { AbstractInsnNode insn = findReturnIter.next(); if (insn.getOpcode() == Opcodes.RETURN) { returnNode = insn; break; } } Iterator<AbstractInsnNode> injectIter = sourceMethod.instructions.iterator(); while (injectIter.hasNext()) { AbstractInsnNode insn = injectIter.next(); if (!(insn instanceof LineNumberNode) && insn.getOpcode() != Opcodes.RETURN) { method.instructions.insertBefore(returnNode, insn); } } } } }
From source file:org.spoofax.interpreter.adapter.asm.ASMFactory.java
License:LGPL
public static IStrategoTerm wrap(AbstractInsnNode node) { if (node == null) return None.INSTANCE; switch (node.getType()) { case AbstractInsnNode.FIELD_INSN: return wrap((FieldInsnNode) node); case AbstractInsnNode.FRAME: return wrap((FrameNode) node); case AbstractInsnNode.IINC_INSN: return wrap((IincInsnNode) node); case AbstractInsnNode.INSN: return wrap((InsnNode) node); case AbstractInsnNode.INT_INSN: return wrap((IntInsnNode) node); case AbstractInsnNode.INVOKE_DYNAMIC_INSN: throw new NotImplementedException(); case AbstractInsnNode.JUMP_INSN: return wrap((JumpInsnNode) node); case AbstractInsnNode.LABEL: return wrap((LabelNode) node); case AbstractInsnNode.LDC_INSN: return wrap((LdcInsnNode) node); case AbstractInsnNode.LINE: return wrap((LineNumberNode) node); case AbstractInsnNode.LOOKUPSWITCH_INSN: return wrap((LookupSwitchInsnNode) node); case AbstractInsnNode.METHOD_INSN: return wrap((MethodInsnNode) node); case AbstractInsnNode.MULTIANEWARRAY_INSN: return wrap((MultiANewArrayInsnNode) node); case AbstractInsnNode.TABLESWITCH_INSN: return wrap((TableSwitchInsnNode) node); case AbstractInsnNode.TYPE_INSN: return wrap((TypeInsnNode) node); case AbstractInsnNode.VAR_INSN: return wrap((VarInsnNode) node); case -1://from w ww. j a va 2 s .co m System.err.println("Bogus " + node.getClass().getName()); return None.INSTANCE; default: throw new IllegalArgumentException( "Unknown type " + node.getOpcode() + " for " + node.getClass().getName()); } }
From source file:org.springsource.loaded.TypeDiffComputer.java
License:Apache License
/** * Determine if there any differences between the methods supplied. A MethodDelta object is built to record any differences and * stored against the type delta./*w w w. j av a 2s.c om*/ * * @param oMethod 'old' method * @param nMethod 'new' method * @param td the type delta where changes are currently being accumulated */ private static void computeAnyMethodDifferences(MethodNode oMethod, MethodNode nMethod, TypeDelta td) { MethodDelta md = new MethodDelta(oMethod.name, oMethod.desc); if (oMethod.access != nMethod.access) { md.setAccessChanged(oMethod.access, nMethod.access); } // TODO annotations InsnList oInstructions = oMethod.instructions; InsnList nInstructions = nMethod.instructions; if (oInstructions.size() != nInstructions.size()) { md.setInstructionsChanged(oInstructions.toArray(), nInstructions.toArray()); } else { // TODO Just interested in constructors right now - should add others if (oMethod.name.charAt(0) == '<') { String oInvokeSpecialDescriptor = null; String nInvokeSpecialDescriptor = null; int oUninitCount = 0; int nUninitCount = 0; boolean codeChange = false; for (int i = 0, max = oInstructions.size(); i < max; i++) { AbstractInsnNode oInstruction = oInstructions.get(i); AbstractInsnNode nInstruction = nInstructions.get(i); if (!codeChange) { if (!sameInstruction(oInstruction, nInstruction)) { codeChange = true; } } if (oInstruction.getType() == AbstractInsnNode.TYPE_INSN) { if (oInstruction.getOpcode() == Opcodes.NEW) { oUninitCount++; } } if (nInstruction.getType() == AbstractInsnNode.TYPE_INSN) { if (nInstruction.getOpcode() == Opcodes.NEW) { nUninitCount++; } } if (oInstruction.getType() == AbstractInsnNode.METHOD_INSN) { MethodInsnNode mi = (MethodInsnNode) oInstruction; if (mi.getOpcode() == INVOKESPECIAL && mi.name.equals("<init>")) { if (oUninitCount == 0) { // this is the one! oInvokeSpecialDescriptor = mi.desc; } else { oUninitCount--; } } } if (nInstruction.getType() == AbstractInsnNode.METHOD_INSN) { MethodInsnNode mi = (MethodInsnNode) nInstruction; if (mi.getOpcode() == INVOKESPECIAL && mi.name.equals("<init>")) { if (nUninitCount == 0) { // this is the one! nInvokeSpecialDescriptor = mi.desc; } else { nUninitCount--; } } } } // Has the invokespecial changed? if (oInvokeSpecialDescriptor == null) { if (nInvokeSpecialDescriptor != null) { md.setInvokespecialChanged(oInvokeSpecialDescriptor, nInvokeSpecialDescriptor); } } else { if (!oInvokeSpecialDescriptor.equals(nInvokeSpecialDescriptor)) { md.setInvokespecialChanged(oInvokeSpecialDescriptor, nInvokeSpecialDescriptor); } } if (codeChange) { md.setCodeChanged(oInstructions.toArray(), nInstructions.toArray()); } } } if (md.hasAnyChanges()) { // it needs recording td.addChangedMethod(md); } }
From source file:org.springsource.loaded.TypeDiffComputer.java
License:Apache License
private static boolean sameInstruction(AbstractInsnNode o, AbstractInsnNode n) { if (o.getType() != o.getType() || o.getOpcode() != n.getOpcode()) { return false; }/*from w ww . j a v a 2 s.c o m*/ switch (o.getType()) { case (AbstractInsnNode.INSN): // 0 if (!sameInsnNode(o, n)) { return false; } break; case (AbstractInsnNode.INT_INSN): // 1 if (!sameIntInsnNode(o, n)) { return false; } break; case (AbstractInsnNode.VAR_INSN): // 2 if (!sameVarInsn(o, n)) { return false; } break; case (AbstractInsnNode.TYPE_INSN):// 3 if (!sameTypeInsn(o, n)) { return false; } break; case (AbstractInsnNode.FIELD_INSN): // 4 if (!sameFieldInsn(o, n)) { return false; } break; case (AbstractInsnNode.METHOD_INSN): // 5 if (!sameMethodInsnNode(o, n)) { return false; } break; case (AbstractInsnNode.JUMP_INSN): // 6 if (!sameJumpInsnNode(o, n)) { return false; } break; case (AbstractInsnNode.LABEL): // 7 if (!sameLabelNode(o, n)) { return false; } break; case (AbstractInsnNode.LDC_INSN): // 8 if (!sameLdcInsnNode(o, n)) { return false; } break; case (AbstractInsnNode.IINC_INSN): // 9 if (!sameIincInsn(o, n)) { return false; } break; case (AbstractInsnNode.TABLESWITCH_INSN): // 10 if (!sameTableSwitchInsn(o, n)) { return false; } break; case (AbstractInsnNode.LOOKUPSWITCH_INSN): // 11 if (!sameLookupSwitchInsn(o, n)) { return false; } break; case (AbstractInsnNode.MULTIANEWARRAY_INSN): // 12 if (!sameMultiANewArrayInsn(o, n)) { return false; } break; case (AbstractInsnNode.FRAME): // 13 if (!sameFrameInsn(o, n)) { return false; } break; case (AbstractInsnNode.LINE): // 14 if (!sameLineNumberNode(o, n)) { return false; } break; default: throw new IllegalStateException("nyi " + o.getType()); } return true; }
From source file:pku.sei.checkedcoverage.tracer.instrumentation.PauseTracingInstrumenter.java
License:Creative Commons License
@SuppressWarnings("unchecked") public void transformMethod(final MethodNode method, final ListIterator<MethodNode> methodIt, final String className) { if ((method.access & ACC_ABSTRACT) != 0 || (method.access & ACC_NATIVE) != 0) return;//from www.j a v a2s.co m int tracerLocalVarIndex = (method.access & Opcodes.ACC_STATIC) == 0 ? 1 : 0; for (final Type t : Type.getArgumentTypes(method.desc)) tracerLocalVarIndex += t.getSize(); // increment number of local variables by one (for the threadtracer) ++method.maxLocals; // and increment all local variable indexes after the new one by one for (final Object o : method.localVariables) { final LocalVariableNode localVar = (LocalVariableNode) o; if (localVar.index >= tracerLocalVarIndex) ++localVar.index; } final LabelNode l0 = new LabelNode(); final LabelNode l1 = new LabelNode(); final ListIterator<AbstractInsnNode> insnIt = method.instructions.iterator(); insnIt.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(Tracer.class), "getInstance", "()L" + Type.getInternalName(Tracer.class) + ";")); insnIt.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(Tracer.class), "getThreadTracer", "()L" + Type.getInternalName(ThreadTracer.class) + ";")); insnIt.add(new InsnNode(DUP)); insnIt.add(new VarInsnNode(ASTORE, tracerLocalVarIndex)); insnIt.add(new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(ThreadTracer.class), "pauseTracing", "()V")); insnIt.add(l0); while (insnIt.hasNext()) { final AbstractInsnNode insn = insnIt.next(); switch (insn.getType()) { case AbstractInsnNode.INSN: switch (insn.getOpcode()) { case IRETURN: case LRETURN: case FRETURN: case DRETURN: case ARETURN: case RETURN: insnIt.previous(); insnIt.add(new VarInsnNode(ALOAD, tracerLocalVarIndex)); insnIt.add(new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(ThreadTracer.class), "resumeTracing", "()V")); insnIt.next(); } break; case AbstractInsnNode.IINC_INSN: if (((IincInsnNode) insn).var >= tracerLocalVarIndex) ++((IincInsnNode) insn).var; break; case AbstractInsnNode.VAR_INSN: if (((VarInsnNode) insn).var >= tracerLocalVarIndex) ++((VarInsnNode) insn).var; break; default: break; } } method.instructions.add(l1); method.instructions.add(new VarInsnNode(ALOAD, tracerLocalVarIndex)); method.instructions.add(new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(ThreadTracer.class), "resumeTracing", "()V")); method.instructions.add(new InsnNode(ATHROW)); method.tryCatchBlocks.add(new TryCatchBlockNode(l0, l1, l1, null)); // finally: create a copy of the method that gets the ThreadTracer as argument if (!"<clinit>".equals(method.name) && this.tracer.wasRedefined(className)) { final Type[] oldMethodArguments = Type.getArgumentTypes(method.desc); final Type[] newMethodArguments = Arrays.copyOf(oldMethodArguments, oldMethodArguments.length + 1); newMethodArguments[oldMethodArguments.length] = Type.getType(ThreadTracer.class); final String newMethodDesc = Type.getMethodDescriptor(Type.getReturnType(method.desc), newMethodArguments); final MethodNode newMethod = new MethodNode(method.access, method.name, newMethodDesc, method.signature, (String[]) method.exceptions.toArray(new String[method.exceptions.size()])); methodIt.add(newMethod); final Map<LabelNode, LabelNode> newMethodLabels = LazyMap.decorate(new HashMap<LabelNode, LabelNode>(), new Factory() { public Object create() { return new LabelNode(); } }); // copy the local variables information to the new method for (final Object o : method.localVariables) { final LocalVariableNode lv = (LocalVariableNode) o; newMethod.localVariables.add(new LocalVariableNode(lv.name, lv.desc, lv.signature, newMethodLabels.get(lv.start), newMethodLabels.get(lv.end), lv.index)); } newMethod.maxLocals = method.maxLocals; newMethod.maxStack = method.maxStack; // copy the try-catch-blocks for (final Object o : method.tryCatchBlocks) { final TryCatchBlockNode tcb = (TryCatchBlockNode) o; newMethod.tryCatchBlocks.add(new TryCatchBlockNode(newMethodLabels.get(tcb.start), newMethodLabels.get(tcb.end), newMethodLabels.get(tcb.handler), tcb.type)); } // skip the first 4 instructions, replace them with this: newMethod.instructions.add(new VarInsnNode(ALOAD, tracerLocalVarIndex)); final Iterator<AbstractInsnNode> oldInsnIt = method.instructions.iterator(4); // and add all the other instructions while (oldInsnIt.hasNext()) { final AbstractInsnNode insn = oldInsnIt.next(); newMethod.instructions.add(insn.clone(newMethodLabels)); } } }