2011-04-29 48 views
1

編輯:解決方法是,我使用aastore,當我應該使用iastore,因爲我想存儲一個項目整數,而aastore只適用於數組對象爲什麼不會這個字節碼驗證

我有以下方法我在字節碼生成作爲構造

aload_0 
invokespecial java/lang/Object/<init>()V 
aload_0 
new java/lang/StringBuilder 
dup 
invokespecial java/lang/StringBuilder/<init>()V 
putfield com/js/interpreter/custom_types/1e9ebd0/s Ljava/lang/StringBuilder; 
aload_0 
iconst_0 
putfield com/js/interpreter/custom_types/1e9ebd0/l I 
aload_0 
iconst_0 
multianewarray [I 1 
astore_1 
iconst_0 
istore_2 
goto 23 
18:aload_1 
iload_2 
iconst_0 
aastore 
iinc 2 1 
23:iload_2 
iconst_0 
if_icmplt 18 
aload_1 
putfield com/js/interpreter/custom_types/1e9ebd0/a [I 
return 

然而,它未能驗證,給予方法:簽名:()V)希望找到對象/堆棧

陣列

不過,我可以去通過,並知道在堆棧上項目的精確數目在所有時間:

aload_0 
1 
    invokespecial java/lang/Object/<init>()V 
0 
    aload_0 
1 
    new java/lang/StringBuilder 
2 
    dup 
3 
    invokespecial java/lang/StringBuilder/<init>()V 
2 
    putfield com/js/interpreter/custom_types/1e9ebd0/s Ljava/lang/StringBuilder; 
0 
    aload_0 
1 
    iconst_0 
2 
    putfield com/js/interpreter/custom_types/1e9ebd0/l I 
0 
    aload_0 
1 
    iconst_0 
2 
    multianewarray [I 1 
2 
    astore_1 
1 
    iconst_0 
2 
    istore_2 
1 
    goto 23 
    18:aload_1 
2 
    iload_2 
3 
    iconst_0 
4 
    aastore 
1 
    iinc 2 1 
1 
    23:iload_2 
2 
    iconst_0 
3 
    if_icmplt 18 
1 
    aload_1 
2 
    putfield com/js/interpreter/custom_types/1e9ebd0/a [I 
0 
    return 

當我通過司法驗證運行它,它並沒有給我一個y有用的消息(它甚至無法驗證由javac生成的類)。

這裏可能會發生什麼?有什麼問題?

+0

不是說這是有問題的,但爲什麼你用'multianewarray [I 1'而不是'a newarray'? – MeBigFatGuy 2011-04-29 06:50:09

+0

一般地生成multianewarray指令更容易。我打算在以後優化這些東西。 – 2011-04-29 06:53:51

+0

我想「預計在堆棧上找到對象/數組」,意味着你有堆棧上某處的參數類型錯誤....一個int而不是一個引用?也許你應該擴展你的堆棧元素數量和類型。 – subsub 2011-04-29 07:20:12

回答

1

我沒有看到這個問題上,但這是我在進入字節碼調試地獄時所做的:

  • 忽略不必要的代碼。目前看來,循環是一個nop(你永遠不會進入身體循環,因爲你用零初始化局部變量2,對吧?)。所以我只會讓循環的主體爲空,並查看驗證錯誤是否持續。
  • 然後,我將開始刪除其他部分(各個字段的初始化),直到錯誤消失。
+0

問題是我正在測試代碼生成器。我不想僅僅優化它,因爲那樣當它無法優化時,它會間歇性地失敗。我的意思是,如果我刪除循環,它驗證罰款。但是當循環*不是*可移動時,我需要它來工作。我不能將循環分成更小的部分,否則會導致堆棧不一致,所以我無法進一步分割和克服。 – 2011-04-29 08:13:41

+1

使用更多的智能(用流行指令替換操作數),我設法弄清楚這是因爲我正在使用一個aastore指令而不是一個int數組中的iastore指令。 – 2011-04-29 08:24:09

+0

我在說,通過逐漸刪除生成的代碼片段,您可以將零件導入驗證問題。所以你現在知道問題是由於循環。開始刪除循環中的單個部分,直到找到發生故障的部分。 – 2011-04-29 08:26:18

1

也許我很困惑,但你做

1 
jsr 23 

... 

23: iload_2 
2 

但23後,我覺得會是3堆棧

A0 
<return address> 
I2 
+0

謝謝,你是對的,我很困惑。我正在尋找goto,而不是jsr。但是,我仍然得到與修復相同的驗證錯誤。 – 2011-04-29 07:01:34

+0

我已更新字節碼以反映此修正。 – 2011-04-29 07:07:06

相關問題