Java字节码生成,嵌套循环 - 分支目标 114 处的堆栈图帧不一致

问题描述 投票:0回答:1

我正在玩Java字节码生成(使用Clojure和https://github.com/jgpc42/insn),目前我正在尝试为嵌套

for
循环生成字节码,下面是相关部分生成的字节码,但是当我尝试运行它时,我得到:

 Exception in thread "main" java.lang.VerifyError: Inconsistent stackmap frames at branch target 114

for
相关的部分字节码:

     111: bipush        0
     113: istore_0
     114: iload_0
     115: bipush        3
     117: if_icmpge     154
     120: bipush        0
     122: istore_1
     123: iload_0
     124: bipush        3
     126: if_icmpge     147
     129: invokestatic  #14                 // Method my/pkg/RaspIvok.getInvoker:()Lrasp_lang/lib/core2/Invoker;
     132: invokestatic  #44                 // Method my/pkg/RaspIvok.getPrintln:()Lmy/pkg/Test/Println;
     135: ldc           #46                 // String Hello
     137: invokevirtual #49                 // Method rasp_lang/lib/core2/Invoker.call:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
     140: pop
     141: iinc          1, 1
     144: goto          123
     147: pop
     148: iinc          0, 1
     151: goto          114
     154: return

如何理解以解决问题有任何帮助吗?

谢谢

java clojure java-bytecode-asm
1个回答
0
投票

在每条字节码指令中,类验证器都有一个关于堆栈有多大以及每个槽中有哪些类型的精确模型。

代码可以自然地(仅从顶部)或通过 151 处的

GOTO
“流入”114。

进入第 114 项的这两条路线没有相同的堆栈模型。要么是上面的类型不一样,要么是尺寸不一样。

快速浏览一下,在“注释”中说明堆栈上的效果:

我们进入空栈,然后:

 +1    111: bipush        0
 -1    113: istore_0
 +1    114: iload_0
 +1    115: bipush        3
 -2    117: if_icmpge     154
 +1    120: bipush        0
 -1    122: istore_1
 +1    123: iload_0
 +1    124: bipush        3
 -2    126: if_icmpge     147
 +1    129: invokestatic  #14                 // Method my/pkg/RaspIvok.getInvoker:()Lrasp_lang/lib/core2/Invoker;
 +1    132: invokestatic  #44                 // Method my/pkg/RaspIvok.getPrintln:()Lmy/pkg/Test/Println;
 +1    135: ldc           #46                 // String Hello
 -3+1  137: invokevirtual #49                 // Method rasp_lang/lib/core2/Invoker.call:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
 -1    140: pop
 0     141: iinc          1, 1
 0     144: goto          123
 -1    147: pop
 0     148: iinc          0, 1
 0     151: goto          114
 0     154: return

一切都处于平衡状态。除了 147: pop 之外,它毫无意义,意味着当您到达“151: goto 114”时总和为 -1,但当您“自然”到达 114 时总和为 0。

我不知道147:流行音乐是从哪里来的。看起来,如果你摆脱它,这应该可行。

© www.soinside.com 2019 - 2024. All rights reserved.