gpt4 book ai didi

java - 为什么 ASM 无法为我的生成类计算出正确的最大值?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:54:07 27 4
gpt4 key购买 nike

我正在使用 ASM 3.1 生成一个虚拟类。它只有一个简单的构造函数,没有其他方法:

public class TestAsm {

public static void main(String... args) throws Throwable {
ClassWriter sw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
sw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER, "test/SubCls", null, "test/SuperCls", null);
sw.visitField(Opcodes.ACC_PUBLIC, "i", "I", null, null);

MethodVisitor mv = sw.visitMethod(0, "<init>", "()V", null, null);
// mv.visitMaxs(2, 1);
mv.visitCode();
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "test/SuperCls", "<init>", "()V");
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitInsn(Opcodes.ICONST_2);
mv.visitFieldInsn(Opcodes.PUTFIELD, "test/SubCls", "i", "I");
mv.visitInsn(Opcodes.RETURN);
mv.visitEnd();

sw.visitEnd();
byte[] cls = sw.toByteArray();
FileOutputStream fos = new FileOutputStream("bin/test/SubCls.class");
fos.write(cls);
fos.close();

SuperCls o = (SuperCls) Class.forName("test.SubCls").newInstance();
System.out.println(o.i);

System.out.println(o.getClass().getDeclaredField("i").getInt(o));
}
}

如您所见,根据文档,我指定了 ClassWriter.COMPUTE_FRAMES 标志,这将计算我所有方法的堆栈大小和局部大小。但是当我运行这段代码时,我得到一个错误:

Exception in thread "main" java.lang.VerifyError: (class: test/SubCls, method: <init> signature: ()V) Stack size too large
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
at test.TestAsm.main(TestAsm.java:33)

我使用“javap -c”检查了生成的类文件,发现堆栈大小和局部大小不正确:

$ javap -c SubCls -verbose
public class test.SubCls extends test.SuperCls
minor version: 0
major version: 50
Constant pool:
const #1 = Asciz test/SubCls;
const #2 = class #1; // test/SubCls
const #3 = Asciz test/SuperCls;
const #4 = class #3; // test/SuperCls
const #5 = Asciz i;
const #6 = Asciz I;
const #7 = Asciz <init>;
const #8 = Asciz ()V;
const #9 = NameAndType #7:#8;// "<init>":()V
const #10 = Method #4.#9; // test/SuperCls."<init>":()V
const #11 = NameAndType #5:#6;// i:I
const #12 = Field #2.#11; // test/SubCls.i:I
const #13 = Asciz Code;

{
public int i;


test.SubCls();
Code:
Stack=0, Locals=1, Args_size=1
0: aload_0
1: invokespecial #10; //Method test/SuperCls."<init>":()V
4: aload_0
5: iconst_2
6: putfield #12; //Field i:I
9: return

}

当我手动调用 visitMaxs(2, 1) 时,这个错误就会消失。
但我不知道为什么 ASM 无法为我计算出正确的最大值。谁能给我一个提示?

最佳答案

调用mv.visitMaxs(0, 0);;我确实在某个地方读到过,发现它很奇怪所以我记得了。

关于java - 为什么 ASM 无法为我的生成类计算出正确的最大值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14180795/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com