0

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

我的问题是:有没有一种优雅而方便的方法来做到这一点?

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

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

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

4

1 回答 1

0

如果您需要两次通过字节码,这就是您使用 ASM 的方式。树包(即 MethodNode)将保存所有访问事件,并在您调用 accept() 方法时可以重播它们。内联创建下一个访问者是一个坏主意,但是传递访问者并没有错。请参阅关于 ASM的AOSD.07 论文中“内联方法”部分的 JSRInlinerAdapter 的实现或示例

因此,您的示例将如下所示:

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 );
  }
}
于 2012-12-11T04:35:20.713 回答