我正在嘗試使用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
?或者是我以某種方式濫用了它?
這裏很容易問:)但我會嘗試提取一個最小的測試用例。 – Patrick