2012-12-10 44 views
0

我想在ASM中實現一個轉換,需要兩遍遍過每個方法。第一個收集關於需要什麼儀器的信息(與跳轉目標有關,這就是爲什麼我需要兩次通行證),第二個完成收集的信息並添加儀器。這也意味着在我開始第二輪之前,我必須完成第一輪(即處理所有的指令)。這就是爲什麼手冊中討論的常規鏈接模式不起作用。如何鏈ASM方​​法訪問者端到端

我的問題是:是否有一個優雅和方便的方法來做到這一點?

到目前爲止,我唯一可以提出的解決方案是在第一個訪問者中從visitEnd()調用第二個訪問者。輪廓看起來像這樣

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

我不喜歡這種解決方案太多,因爲我懷疑,在未來我將不得不鏈更多的遊客,我可能希望能夠挑萬選。這是真的不可能的。

回答

0

如果您需要兩次通過字節碼,那麼您是如何使用ASM進行處理的。樹形包(即MethodNode)將保存所有訪問事件,並且可以在調用accept()方法時重放它們。在線創建下一位訪問者是一個好主意,但傳遞訪問者沒有任何問題。請參閱JSRInlinerAdapter的實施或關於ASM的「內聯方法」部分的示例AOSD.07 paper

所以,你的例子將是這個樣子:

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

這是一個很值得我有什麼。我希望有一個更簡單的方法。 (這需要傳遞訪問者和MethodNode以及我所需要的所有東西)。 – Jochen

+0

我已經更新了幾個更詳細的例子和答案。傳遞訪問者是ASM API設計的主要思想。 –

+0

那麼,我想我必須這樣做... :) – Jochen