我開發與ASM的檢測引擎,我需要攔截的方法,其中接收陣列類型的參數調用。爲此,我實施了MethodVisitor
,並在其visitMethodInsn
中檢查desc
參數是否指定了數組類型的任何參數。如果目標方法沒有數組類型的參數,那麼我無關並且插入原始方法調用:super.visitMethodInsn(opcode, owner, name, desc);
如何避免的VerifyError:「希望找到堆棧未初始化對象」的對象已經初始化
另一方面,如果目標方法具有數組類型的參數,那麼我必須執行一個針對其論點的具體行動。我獲得訪問每個參數的最簡單的解決方案是調用一箇中介方法,具有與目標方法相同的描述符,並且在此介體中,我可以輕鬆訪問其參數(與傳遞給目標方法的參數相對應)。
然而,當目標方法是一個實例的構造(<init>
)出現一個問題。
NEW XXX
DUP
INVOKESPECIAL XXXX.<init>()
根據我上面的解釋,我移動INVOKESPECIAL
呼叫到調解方法和新創建的對象是該中介的第一個參數的方法:在Java的new XXX()
如下被翻譯成字節碼。然而,驗證者爲這個介體產生一個錯誤,報告介體的第一個參數(它將成爲目標方法的第一個參數 - <init>
)不是一個「單元化對象」。更確切地說,我得到了錯誤:Exception in thread "main" java.lang.VerifyError: Expecting to find unitialized object on stack」
。
一旦我用兩種不同的方法分割字節碼NEW
和INVOKESPECIAL
,驗證者聲稱傳遞給INVOKESPECIAL
的參數已經被初始化。
任何建議來解決這個問題呢? (請不要回答我避免介體並直接訪問堆棧中的參數,因爲複製並替換佔用堆棧中任意位置的參數並非易事)。
「mediator」方法是什麼意思? – vijay
想象一下,在某些時候,我的工具引擎正在攔截目標方法的調用:'obj.foo(x)'。因此,在這一點上,我將這個調用替換爲:'obj.foo(x)',by:'mediator $ foo(obj,x)' - 在這種情況下,調解器$ foo是調用方類中的一個新的靜態方法。因此,'mediator $ foo(obj,x)'完成它需要的東西,然後調用目標:'obj.foo(x)'。 –
是靜態還是實例方法的中介方法? – vijay