gpt4 book ai didi

java - 操作数堆栈欠载

转载 作者:行者123 更新时间:2023-11-30 09:17:22 25 4
gpt4 key购买 nike

我有这个程序可以从 java 文件生成字节码。而对于这个简单的 test() 方法

public void test()
{
boolean a = false;
if (a || true)
{
boolean b = false;
}
}

,它会生成如下一段字节码

public void test()
Code:
7: iconst_0
8: istore_1
9: iload_1
10: ifne 13
13: iconst_0
14: istore_2
15: return

当我执行该类时,我一直在 test() 中的操作数堆栈运行不足,我不明白这是为什么,因为生成的字节码看起来不错(对我来说)

谁能帮我调试一下?

(这是我跟踪堆栈所做的事情

public void test()
Code:
7: iconst_0
(1 on the stack)
8: istore_1
(0 on the stack)
9: iload_1
(1 on the stack)
10: ifne 13
(0 on the stack)
13: iconst_0
(1 on the stack)
14: istore_2
(0 on the stack)
15: return

是的,堆栈对我来说很好!)

编辑:这是 javac

生成的字节码
public void test();
Code:
0: iconst_0
1: istore_1
2: iload_1
3: ifne 6
6: iconst_0
7: istore_2
8: return

最佳答案

当我尝试这个时

public class MainDump implements Opcodes {

public static byte[] dump() throws Exception {

ClassWriter cw = new ClassWriter(0);
FieldVisitor fv;
MethodVisitor mv;
AnnotationVisitor av0;

cw.visit(V1_7, ACC_PUBLIC + ACC_SUPER, "Main", null, "java/lang/Object", null);

cw.visitSource("Main.java", null);

{
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitCode();
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitLineNumber(1, l0);
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
mv.visitInsn(RETURN);
Label l1 = new Label();
mv.visitLabel(l1);
mv.visitLocalVariable("this", "LMain;", null, l0, l1, 0);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC, "test", "()V", null, null);
mv.visitCode();
mv.visitInsn(ICONST_0);
mv.visitVarInsn(ISTORE, 1);
mv.visitVarInsn(ILOAD, 1);
Label l2 = new Label();
mv.visitJumpInsn(IFEQ, l2);
mv.visitInsn(ICONST_0);
mv.visitVarInsn(ISTORE, 2);
mv.visitLabel(l2);
mv.visitFrame(Opcodes.F_APPEND, 1, new Object[]{Opcodes.INTEGER}, 0, null);
mv.visitInsn(RETURN);
mv.visitMaxs(1, 3);
mv.visitEnd();
}
cw.visitEnd();

return cw.toByteArray();
}

public static void main(String... ignored) throws Exception {
Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
defineClass.setAccessible(true);

byte[] dump = dump();
defineClass.invoke(Thread.currentThread().getContextClassLoader(), dump, 0, dump.length);
new Main().test();
}
}

这有效,但是如果我放弃堆栈帧调整,我会收到此错误

Exception in thread "main" java.lang.VerifyError: Expecting a stackmap frame at branch target 8
Exception Details:
Location:
Main.test()V @3: ifeq
Reason:
Expected stackmap frame at this location.
Bytecode:
0000000: 033c 1b99 0005 033d b1

简而言之,对于Java 7,堆栈操作不足以通过有效性。

关于java - 操作数堆栈欠载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18985248/

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