2012-08-13 24 views
0

使用ASM 4.我從另一種語言即時生成字節碼。它產生了以下內容,但我不清楚發生了什麼。我的猜測是try/catch塊會干擾堆棧。前兩行是加載一個Lambda2,然後需要它成爲堆棧最深處的最後一項,但我不明白是什麼讓它在一路上消失。無法將操作數從空棧中彈出

看起來,在指令13堆棧消失。這是它進入try/catch塊的地方。當它進入try/catch塊時,堆棧會被拋出嗎?如果是這樣,那將解釋問題。

java.lang.RuntimeException: Error at instruction 43: Cannot pop operand off an empty stack. apply()Ljava/lang/Object; 
00000 R . . : : L0 
00001 R . . : :  LINENUMBER 1 L0 
00002 R . . : :  LDC "foo" 
00003 R . . : R :  INVOKESTATIC com/stralos/asm/ASMUtil.getUserFunc (Ljava/lang/Object;)Ljava/lang/Object; 
00004 R . . : R : L1 
00005 R . . : R :  LINENUMBER 1 L1 
00006 R . . : R :  CHECKCAST com/stralos/lang/Lambda2 
00007 R . . : R : L2 
00008 R . . : R :  LINENUMBER 1 L2 
00009 R . . : R :  LDC 1 
00010 R . . : R J :  INVOKESTATIC java/lang/Long.valueOf (J)Ljava/lang/Long; 
00011 R . . : R R : L3 
00012 R . . : R R :  LINENUMBER 1 L3 
00013 ?  :  LDC 1 
00014 ?  :  INVOKESTATIC java/lang/Long.valueOf (J)Ljava/lang/Long; 
00015 ?  : L4 
00016 ?  :  LINENUMBER 1 L4 
00017 ?  :  ASTORE 1 
00018 ?  : L5 
00019 ?  :  GOTO L6 
00020 R . . : R : L7 
00021 R . . : R :  LINENUMBER 1 L7 
00022 R . . : R : FRAME SAME1 java/lang/Throwable 
00023 R . . : R :  ASTORE 2 
00024 R . R : : L8 
00025 R . R : :  LINENUMBER 1 L8 
00026 R . R : :  NEW shen/lambda/ToRun$1 
00027 R . R : R :  DUP 
00028 R . R : R R : L9 
00029 R . R : R R :  LINENUMBER 1 L9 
00030 R . R : R R :  INVOKESPECIAL shen/lambda/ToRun$1.<init>()V 
00031 R . R : R : L10 
00032 R . R : R :  LINENUMBER 1 L10 
00033 R . R : R :  CHECKCAST com/stralos/lang/Lambda1 
00034 R . R : R :  ALOAD 2 
00035 R . R : R R :  INVOKEVIRTUAL com/stralos/lang/Lambda1.apply (Ljava/lang/Object;)Ljava/lang/Object; 
00036 R . R : R :  ASTORE 1 
00037 R R R : : L6 
00038 R R R : :  LINENUMBER 1 L6 
00039 R R R : : FRAME FULL [shen/eval/ToEvaluate$0 java/lang/Object] [com/stralos/lang/Lambda2 java/lang/Long] 
00040 R R R : :  ALOAD 1 
00041 R R R : R : L11 
00042 R R R : R :  LINENUMBER 1 L11 
00043 R R R : R :  INVOKEVIRTUAL com/stralos/lang/Lambda2.apply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; 
00044 ?  :  ARETURN 
00045 ?  : L12 
    TRYCATCHBLOCK L3 L5 L7 java/lang/Throwable 
+0

'invokevirtual'在操作數棧上沒有任何參數?你期望怎麼做? – oldrinb 2012-08-14 00:14:50

+0

是的,我明白這一點。我的問題是操作數在哪裏?應該有適當的數量推堆棧上這個工作。例如,爲什麼他們在13歲時消失? – mentics 2012-08-14 02:40:56

+0

'L10'下降到'L6' :-) – oldrinb 2012-08-14 04:33:22

回答

1

是的,當進入catch()塊時堆棧是空的。由於catch處理程序無法知道try {}塊內是否發生了異常,堆棧可能處於try {}塊的任何可能狀態。

此外,在try {}模塊中修改的任何本地變量在進入catch()模塊時都不能被假定爲處於任何特定狀態,但在您的情況下這不是問題。

所以,當退出catch塊時,您需要確保堆棧處於與沒有拋出異常一樣的狀態。在這種情況下,您需要在代碼到達L6時用Lambda2對象和Long對象填充堆棧。