You have two solutions:
1. Use the visitInsn(int opcode) method in MethodVisitor :
//this is the custom method visitor private class InsertInitCodeBeforeReturnMethodVisitor extends MethodVisitor{ public InsertInitCodeBeforeReturnMethodVisitor(MethodVisitor mv) { super(Opcodes.ASM4, mv); } @Override public void visitInsn(int opcode) { //whenever we find a RETURN, we instert the code, here only crazy example code switch(opcode) { case Opcodes.IRETURN: case Opcodes.FRETURN: case Opcodes.ARETURN: case Opcodes.LRETURN: case Opcodes.DRETURN: case Opcodes.RETURN: mv.visitVarInsn(Opcodes.ALOAD, 42); break; default: // do nothing } super.visitInsn(opcode); } }
2. Use the onMethodExit(int opcode) method in the AdviceAdapter at org.objectweb.asm.commons :
//this is the custom method visitor private class InsertInitCodeBeforeReturnMethodVisitor extends AdviceAdapter{ public InsertInitCodeBeforeReturnMethodVisitor(MethodVisitor mv, int access, String name, String desc) { super(Opcodes.ASM4, mv, access, name, desc); } @Override protected void onMethodExit(int opcode) { if(opcode != Opcdoes.ATHROW) { mv.visitVarInsn(Opcodes.ALOAD, 42); } } }
I personally like the AdviceAdapter better because it eliminates the headache associated with actually calling the original return command, as well as with the first solution (e.g. super.visitInsn(opcode); ). And secondly, it provides a good abstraction specifically for visits to RETURN (and ATHORW ) ATHORW ; which does not match the visitInsn(int opcode) method in vanilla MethodVisitor , where you need to find visits to RETURN commands among many others, such as DUP s, ICONST_0 , etc., that might or might not be relevant to the problem.
But it again depends on the problem. If this is the only tool that runs, I will stick with the AdviceAdapter . If there are other things you would like to do in conjunction with the RETURN instructions, I could stay with a simple MethodVisitor , as this could give me more flexibility. This suggests that I used the AdviceAdapter little over a year for a heavy tool with managed tools, it has been developed so far!
Edit:
visitor method application
It’s often not clear how to use or apply the visitor / adapter method (at least for me), so I put together a quick code example here: gist.github.com/VijayKrishna/1ca807c952187a7d8c4d , which shows how to use the method adapter, through the corresponding visitor class / adapter class. In the sample code snippet, I changed the name of the method adapter from what I use in this answer, but they do the same. In addition, the code snippet shows a method adapter that extends the AdviceAdapter .
So, you first “call” the class adapter as follows:
ClassReader cr = new ClassReader(in); ClassWriter cw = new ClassWriter(ClassReader.EXPAND_FRAMES); ReturnAdapter returnAdapter = new ReturnAdapter(cw, className); cr.accept(returnAdapter, 0);
Then you execute it by adapting the methods as follows in the class-adapter visitMethod :
MethodVisitor mv; mv = cv.visitMethod(access, name, desc, signature, exceptions); mv = new MethodReturnAdapter(Opcodes.ASM4, className, access, name, desc, mv); return mv;