2013-07-23 44 views
1

我想查看方法調用的參數。所以,如果我調用foo:方法調用訪問變量/常量值

x = 4; 

y = 5; 

... 

foo(x, y, 20, 25); 

我想打印參數(4,5,20,25) 我瞭解這些參數被壓入堆棧方法被調用之前。如何從方法的局部變量數組中獲取值(如果已初始化或常量)?

visitVarInsn()和VarInsnNode沒有辦法從數組中查找實際值。

我需要使用分析器和解釋器來做到這一點,還是有更簡單的方法嗎?

編輯:想通了如何做到這一點。 我修改了BasicValue和BasicInterpreter來說明字節碼指令參數。 因此,表示像BIPUSH這樣的指令的值包含有關正在推送的值的信息,而不僅僅是類型信息。 幀進行檢查以同樣的方式與分析

+0

你想解決什麼問題? – Bohemian

+0

你想在編譯時(不運行程序)或運行時靜態地找到參數嗎? (第二個beeing更容易) – ruediste

+0

我需要靜態找到它們。我只需要知道它們是否被初始化,以及初始值 – zaz

回答

0

它不涉及到ASM和字節碼操作,但以防萬一 -

如果方法FOO屬於與接口方法的類你可以使用Proxy來包裝接口實現和攔截方法名稱。

此外,你可能會發現this答案有用的ASM字節碼修改。

1

直接傳遞給方法調用(20和25)的常量數值很容易靜態檢索 - 它們將導致您可以在visitIntInsn中讀取的推送指令。較小的值將導致您可以使用visitInsn捕獲的const指令,通過visitLdcInsn可以捕獲較大的值。

我不相信通常可以靜態地確定在方法調用點綁定到變量的值。您將需要進行數據流分析(使用分析器和解釋器,如您所建議的那樣),它應該能夠爲每個變量提供可能值的範圍。在一般情況下,這不會給你明確的值,而是會在特定情況下只分配一次或分配多次的無條件變量。