java.lang.VerifyError:预期与ASM生成的字节码一起出现的堆栈映射框架 [英] java.lang.VerifyError: Expecting a stackmap frame occuring with ASM generated byte code
问题描述
我使用 ASM 5.0 在main.class
中生成了Java字节代码,如下所示.
I generated java byte code in main.class
as follows using ASM 5.0.
这是我生成的代码:
javap -c _main.class
输出
public jcalc.lang.CalcObject call();
Code:
0: ldc #9 // String _main/max
2: invokestatic #28 // Method jcalc/lang/Binding.getBindingFromMain:(Ljava/lang/String;)Ljcalc/lang/Binding;
5: ldc #20 // String A
7: invokevirtual #38 // Method jcalc/lang/Binding.refVariable:(Ljava/lang/String;)Ljcalc/lang/CalcObject;
10: checkcast #40 // class jcalc/lang/CalcNumber
13: ldc #9 // String _main/max
15: invokestatic #28 // Method jcalc/lang/Binding.getBindingFromMain:(Ljava/lang/String;)Ljcalc/lang/Binding;
18: ldc #22 // String B
20: invokevirtual #38 // Method jcalc/lang/Binding.refVariable:(Ljava/lang/String;)Ljcalc/lang/CalcObject;
23: checkcast #40 // class jcalc/lang/CalcNumber
26: invokevirtual #44 // Method jcalc/lang/CalcNumber.operatorGreaterThan:(Ljcalc/lang/CalcNumber;)Ljcalc/lang/CalcBoolean;
29: dup
30: astore_3
31: instanceof #46 // class jcalc/lang/CalcBoolean
34: iconst_0
35: if_icmpeq 38
38: aload_3
39: invokevirtual #52 // Method jcalc/lang/CalcObject.isNonNull:()I
42: istore_2
43: aload_3
44: if_icmpeq 61
47: ldc #9 // String _main/max
49: invokestatic #28 // Method jcalc/lang/Binding.getBindingFromMain:(Ljava/lang/String;)Ljcalc/lang/Binding;
52: ldc #20 // String A
54: invokevirtual #38 // Method jcalc/lang/Binding.refVariable:(Ljava/lang/String;)Ljcalc/lang/CalcObject;
57: astore_1
58: goto 72
61: ldc #9 // String _main/max
63: invokestatic #28 // Method jcalc/lang/Binding.getBindingFromMain:(Ljava/lang/String;)Ljcalc/lang/Binding;
66: ldc #22 // String B
68: invokevirtual #38 // Method jcalc/lang/Binding.refVariable:(Ljava/lang/String;)Ljcalc/lang/CalcObject;
71: astore_1
72: aload_1
73: areturn
但是执行时,
Caused by: java.lang.VerifyError: Expecting a stackmap frame at branch target 38
Exception Details:
Location:
_main/max.call()Ljcalc/lang/CalcObject; @35: if_icmpeq
Reason:
Expected stackmap frame at this location.
Bytecode:
0x0000000: 1209 b800 1c12 14b6 0026 c000 2812 09b8
0x0000010: 001c 1216 b600 26c0 0028 b600 2c59 4ec1
0x0000020: 002e 039f 0003 2db6 0034 3d2d 9f00 1112
0x0000030: 09b8 001c 1214 b600 264c a700 0e12 09b8
0x0000040: 001c 1216 b600 264c 2bb0
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at jcalc.lang.Binding.defineFunction(Binding.java:87)
at _main.call(Unknown Source)
... 7 more
我知道无论条件是否满足,分支操作都不得更改堆栈大小.
I know that branch operations must not change stack size whether the condition is satisfied.
但是在第35行中,if_icmpeq
操作只是跳转到下一个操作,因此不会影响堆栈.
But in the line 35 the if_icmpeq
operation just jumps to the next operation, so it won't affect the stack.
我正在使用Java 1.6. 任何人都可以对指令验证规则或在何处找到文档进行详细说明.
I am using Java 1.6. Can anybody give a detailed explanation about the instruction verification rule or where to find the documents.
非常感谢.
推荐答案
我解决了我的问题.
当加载/存储指令出现TypeCast问题时,ASM无法生成正确的堆栈映射框架.
When the load/store instructions have TypeCast issues, the ASM can't generate corrent stackmap frame.
所以下次您看到一条消息
So next time you see there's a message
java.lang.VerifyError:期望在分支目标45处有一个堆栈图框架
java.lang.VerifyError: Expecting a stackmap frame at branch target 45
检查加载/存储指令的类型.
check the types of load/store instructions.
这篇关于java.lang.VerifyError:预期与ASM生成的字节码一起出现的堆栈映射框架的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!