如何将ASM MethodVisitors端到端链接

时间:2012-12-10 11:57:49

标签: java java-bytecode-asm

我正在尝试在ASM中实现需要两次遍历每个方法的转换。第一个收集有关需要检测的位置的信息(与跳转目标有关,这就是我需要两次通过的原因),第二个完成收集的信息并添加检测。这也意味着我必须在开始第二遍之前完成第一遍(即处理所有指令)。这就是为什么手册中讨论的正常链接模式不起作用的原因。

我的问题是:有优雅便捷的方法吗?

到目前为止,我能想出的唯一解决方案是在第一个访问者中调用visitEnd()中的第二个访问者。大纲看起来像这样

public class Pass1Visitor extends MethodVisitor {
  ...
  public void visitEnd() {
    //do stuff the call the second visitor
    thisMethodNode.accept( new Pass2Visitor() );
  }
}

我不太喜欢这个解决方案,因为我怀疑将来我将不得不链接更多的访客,我可能希望能够挑选和选择。哪个是真的不可能。

1 个答案:

答案 0 :(得分:0)

如果你需要两次通过字节码,那就是你用ASM做的。树包(即MethodNode)将保存所有访问事件,并且可以在调用accept()方法时重放它们。传递下一个访客是一个坏主意,但传递访问者并没有错。请参阅JSRInlinerAdapter中关于ASM的AOSD.07 paper中的“内联方法”部分的实施{/ 3}}。

所以,你的例子看起来像这样:

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 );
  }
}