java.lang.VerifyError:预期与ASM生成的字节码一起出现的堆栈映射框架 [英] java.lang.VerifyError: Expecting a stackmap frame occuring with ASM generated byte code

查看:193
本文介绍了java.lang.VerifyError:预期与ASM生成的字节码一起出现的堆栈映射框架的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆