3

我正在编写一个生成 Jasmin 代码的编译器,并希望调用一个将 Class 作为参数的方法。

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

所以在 Jasmin 中,我认为应该是:

.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: (class: CTest2, method: main signature: ([Ljava/lang/String;)V) 常量池中的非法类型

使用“javap -c -verbose”查看 CTest.class(Java 版本)和 CTest2.class(Jasmin 版本)的反汇编代码,它们似乎都以相同的方式设置常量池:

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

我已经修复了 Jasmin 中的两个错误,但是当将类放入“ldc_w”的常量池中时,我看不出它做错了什么,它将类放入常量池中以获取其他指令,例如“new”和“anewarray” “正确。

我尝试在 ASM 中使用 TraceClassVisitor 查看 .class 文件,但它不会转储常量池。

有什么想法我可以尝试下一步吗?

4

1 回答 1

4

您必须确保该类的版本号至少为 49(请参阅此ASM Javadoc 页面上的 visitLdcInsn )。

于 2010-05-19T22:35:08.417 回答