I’m trying to implement a transformation in ASM that requires two passes over each method. The first to collect information about where instrumentation is needed (has to do with jump target, which is why I need two passes), and the second completes the collected information and adds the instrumentation. This also means that I have to complete the first pass (i.e. process all instructions) before I start the second pass. That’s why the normal chaining pattern that’s discussed in the manual does not work.
My question is: Is there an elegant and convenient way to do it?
The only solution I could come up with so far is to call the second visitor from visitEnd() in the first visitor. The outline looks like this
public class Pass1Visitor extends MethodVisitor {
...
public void visitEnd() {
//do stuff the call the second visitor
thisMethodNode.accept( new Pass2Visitor() );
}
}
I don’t like this solution too much, because I suspect that in future I will have to chain more visitors and I might want to be able to pick and chose. Which with this is really not possible.
If you need two passes trough the bytecode, that is how you do it with ASM. The tree package (i.e. MethodNode) will save all visit events and can replay them back when you call accept() method. It is a bad idea to create next visitor inline, but there is nothing wrong with passing visitor. See implementation of JSRInlinerAdapter or example from “Inline Method” section in AOSD.07 paper about ASM.
So, your example will look something like this: