0

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.

Jens Björnhager
  • 5,632
  • 3
  • 27
  • 47
Jochen
  • 2,277
  • 15
  • 22

1 Answers1

0

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:

public class Pass1Visitor extends MethodNode {
  MethodVisitor nextVisitor;

  public Pass1Visitor(MethodVisitor nextVisitor) {
    this.nextVisitor= nextVisitor;
  }

  ...

  public void visitEnd() {
    //do stuff the call the second visitor
    thisMethodNode.accept( nextVisitor );
  }
}
Eugene Kuleshov
  • 31,461
  • 5
  • 66
  • 67
  • This is pretty much what I had. I was hoping there'd be a simpler way. (This requires passing around visitors and the MethodNode in addition to all the stuff I need anyway). – Jochen Dec 11 '12 at 07:21
  • I've updated my answer with few more details and examples. Passing around visitors is the main idea in ASM API design. – Eugene Kuleshov Dec 11 '12 at 14:57
  • Well then, I guess I'll have to do it this way... :) – Jochen Dec 11 '12 at 20:36