0

各メソッドに2つのパスを必要とする変換をASMに実装しようとしています。1つ目はインストルメンテーションが必要な場所に関する情報を収集し(ジャンプターゲットと関係があるため、2つのパスが必要です)、2つ目は収集した情報を完成させてインストルメンテーションを追加します。これは、2番目のパスを開始する前に、最初のパスを完了する(つまり、すべての命令を処理する)必要があることも意味します。そのため、マニュアルで説明されている通常の連鎖パターンは機能しません。

私の質問は:それを行うためのエレガントで便利な方法はありますか?

これまでに思いついた唯一の解決策は、最初のビジターのvisitEnd()から2番目のビジターを呼び出すことです。アウトラインはこんな感じ

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

私はこのソリューションがあまり好きではありません。将来、より多くの訪問者を連鎖させる必要があり、選択して選択できるようにしたいと思うからです。これでは実際には不可能です。

4

1 に答える 1

0

バイトコードを介して 2 つのパスが必要な場合は、ASM でそれを行う方法です。ツリー パッケージ (つまり MethodNode) はすべての訪問イベントを保存し、accept() メソッドを呼び出したときにそれらを再生できます。次の訪問者をインラインで作成するのは悪い考えですが、訪問者を渡すことに問題はありません。JSRInlinerAdapterの実装、または ASM に関するAOSD.07 ペーパーの「インライン メソッド」セクションの例を参照してください。

したがって、例は次のようになります。

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 に答える