【问题标题】:How to avoid "Illegal type in constant pool" using "ldc_w <classname>" in Jasmin?如何在 Jasmin 中使用“ldc_w <classname>”避免“常量池中的非法类型”?
【发布时间】:2010-05-06 21:52:23
【问题描述】:

我正在编写一个生成 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) 常量池中的非法类型

查看 CTest.class(Java 版本)的反汇编代码 和带有“javap -c -verbose”的 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 文件, 但它不会转储常量池。

有什么我可以尝试的想法吗?

【问题讨论】:

    标签: java jasmin


    【解决方案1】:

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

    【讨论】:

    • 优秀。添加“.bytecode 49.0”解决了这个问题。谢谢!
    • @jazzdev :我们在 Drools 框架中面临同样的问题。您能否详细说明一下您在哪里添加了字节码 49.0 ?
    • 我在“.class public ...”前面添加了“.bytecode 49.0”行
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多