我有一個方法,我已經在Java 7(主要版本51)類中進行了更改。使用javap
,我查看了字節碼和堆棧幀映射。一切都看起來不錯:爲什麼Java 7 Bytecode Verifier會抱怨這個堆棧框架?
public int addOne(int);
flags: ACC_PUBLIC
Code:
stack=2, locals=2, args_size=2
0: iload_1
1: iconst_0
2: invokestatic #50 // Method isSomething:(I)Z
5: ifeq 12
8: iconst_0
9: goto 13
12: iconst_1
13: iadd
14: ireturn
StackMapTable: number_of_entries = 2
frame_type = 255 /* full_frame */
offset_delta = 12
locals = [ class test/Target, int ]
stack = [ int ]
frame_type = 255 /* full_frame */
offset_delta = 0
locals = [ class test/Target, int ]
stack = [ int, int ]
這驗證拋出此異常:
java.lang.VerifyError: Expecting a stackmap frame at branch target 12
Exception Details:
Location:
test/Target.addOne(I)I @5: ifeq
Reason:
Expected stackmap frame at this location.
Bytecode:
0000000: 1b03 b800 3299 0007 03a7 0004 0460 ac
是什麼力量推動我瘋狂的是,我有編譯器生成從Java源相同的代碼,它看起來是這樣的:
public int addOne(int);
flags: ACC_PUBLIC
Code:
stack=2, locals=2, args_size=2
0: iload_1
1: iconst_0
2: invokestatic #16 // Method isSomething:(I)Z
5: ifeq 12
8: iconst_0
9: goto 13
12: iconst_1
13: iadd
14: ireturn
StackMapTable: number_of_entries = 2
frame_type = 76 /* same_locals_1_stack_item */
stack = [ int ]
frame_type = 255 /* full_frame */
offset_delta = 0
locals = [ class test/Target, int ]
stack = [ int, int ]
注意,僅堆棧幀中的地圖差異是噸他合成的地圖有全部的框架 - 但這不應該導致差異。有誰知道爲什麼更靈活可能不喜歡我的綜合地圖?
你是什麼用來修改字節碼? – Vulcan
Javassist。我正在使用自己的代碼來計算堆棧幀。 –
您的合成堆棧地圖框中的所有內容都適合我。也許這個問題是由堆棧映射幀的順序造成的?如果'same_locals_1_stack_item'框架在全幀之前被聲明*,我不認爲它會讓本地人複製,導致該框架被忽略並導致錯誤。我不熟悉框架的順序是否重要,但我確定它必須在某種程度上對'same_locals_1_stack_item'類型正常運行非常重要,所以它可能是一個延伸,但是嘗試交換堆棧的順序地圖框架。 – Vulcan