2010-05-06 22 views
3

我正在編寫一個生成Jasmin代碼的編譯器,並且想要調用一個將Class作爲參數的方法。如何在Jasmin中使用「ldc_w <classname>」避免「非法鍵入常量池」?

public class CTest 
{ 
    public static void main(String[] args) 
     throws Exception 
    { 
     java.lang.reflect.Array.newInstance(CTest.class, 0); 
    } 
} 

所以在茉莉,我認爲應該是:

.class public CTest2 
.super java/lang/Object 

.method public static main([Ljava/lang/String;)V 
    .limit stack 2 
    .limit locals 1 
    ldc_w CTest2 
    iconst_0 
    invokestatic java/lang/reflect/Array/newInstance(Ljava/lang/Class;I)Ljava/lang/Object; 
    pop 
    return 
.end method 

當我組裝並運行它,我得到:

異常線程 「main」 java.lang.VerifyError的: (類:CTest2,方法:主簽名:([Ljava/lang/String;)V)常量池中的非法類型

查看CTest.class(Java版本)的反彙編代碼 和CTest2.class(茉莉的版本),用「-c的javap -verbose」 他們似乎都成立了常量池以同樣的方式:

const #2 = class  #16; // CTest 
const #16 = Asciz  CTest; 

    0: ldc_w #2; //class CTest 

const #14 = Asciz  CTest2; 
const #17 = class  #14; // CTest2 

    0: ldc_w #17; //class CTest2 

我固定的兩個錯誤在賈斯明瞭,但我看不到 在將類放入常量池中時出現錯誤,因爲「ldc_w」 它將類放在其他指令的常量池中,如 「new」和「anewarray」正確。

我試着用ASM中的TraceClassVisitor查看.class文件, 但它不轉儲常量池。

任何想法,我可以嘗試下?

回答

4

您必須確保該類的版本號至少爲49(請參閱此ASM Javadoc page上的visitLdcInsn)。

+2

非常好。添加「.bytecode 49.0」解決了這個問題。謝謝! – jazzdev 2010-05-20 21:19:42

+0

@jazzdev:我們在Drools框架中面臨同樣的問題。你能否詳細說明你在哪裏添加了字節碼49.0? – ArunRaj 2016-05-23 05:44:15

+0

我在「.class public ...」之前加了一行「.bytecode 49.0」 – jazzdev 2016-05-24 17:31:18

相關問題