2013-01-24 28 views
0

我正在嘗試使用ASM在try/finally塊中封裝一個方法。具體而言,我正在擴展org.objectweb.asm.commons.AdviceAdapter,並遵循在「3.2.3在方法退出前插入代碼」一節中介紹的"Using ASM framework to implement common bytecode transformation patterns"的技術。org.objectweb.asm.commons.LocalVariablesSorter是否錯誤地進行了優化?

我也在使用LocalVariablesSorter(超類AdviceAdapter)在我在finally塊中使用的方法start處添加一個局部變量。

我有一個方法,我試圖用ASM修改。該方法採用三個參數,並沒有自己的當地人:

class Example { 
    public static int f4(int i, long l, int f) { 
     return (int) (i + l + f); 
    } 
} 

由於我finally塊可能是一個例外處理的目標,我添加了一個調用,這樣super.visitFrame(F_NEW, ...),傳遞方法的參數。由於這調用了超類,我希望我的newLocal可以通過LocalVariablesSorter添加到這個框架中。但是當通過我的ASM管道運行時,Java 7給了我錯誤java.lang.VerifyError: Bad local variable type in method Example.f4(IJI)I at offset 32

望着source of LocalVariablesSorter,在visitFrame方法,我看到它有一個布爾changed,如果沒有改變,visitFrame跳過任何新的當地人我可以創建的任何審議。這個changed布爾值似乎只在上游字節碼對由於使用LocalVariablesSorter創建新本地(而且上述f4()方法中沒有發生此類操作)而必須重新映射的變量執行某些操作時才被設置。

通過應用此變通辦法:

 Field field = LocalVariablesSorter.class.getDeclaredField("changed"); 
     field.setAccessible(true); 
     field.setBoolean(this, true); 

我能夠通過Java 7中的驗證。此外,使用TraceClassVisitor ASM工具,我看到的只是finally塊開始前在棧圖框的區別:

前:

FRAME FULL [I J I] [java/lang/Throwable] 

我的反射後破解(新的地方我加入是一個整數):

FRAME FULL [I J I I] [java/lang/Throwable] 

我知道我沒有分享任何周圍的代碼,但我的問題是更一般的。這是changed布爾錯誤的優化LocalVariablesSorter?或者是我以某種方式濫用了它?

回答

0

LocalVariablesSorter.visitFrame(..)調用不會添加任何本地人,它只會通知ASM記錄有關其他幀的信息。您需要撥打LocalVariablesSorter.newLocal(..)來添加您的當地人。

雖然通常情況下,如果您認爲您在ASM中發現了一個錯誤,最好向ASM issue tracker提交錯誤報告,並提供允許重現問題(例如測試類和完整轉換)的測試代碼。

+0

這裏很容易問:)但我會嘗試提取一個最小的測試用例。 – Patrick

相關問題