2010-05-06 56 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