2

我正忙于使用 ASM 4.1 编写编译器。我需要将中间语言编译成 java 字节码。我发现 ASM 4.1 API 说,“事实上,这些节点必须 (*) 插入到任何指令节点 i 之前,该节点 i 遵循 GOTO 或 THROW 等无条件分支指令,它是跳转指令的目标,或者启动一个异常处理程序块。” 但是,我在 ASM 指南(“ASM 4.0 A Java 字节码工程库”)中找不到 Frame 的用法。谁知道Frame的用法?visitFrame/FrameNode每个参数是什么意思?为什么我使用ASMifier有时会得到“visitFrame(Opcodes.F_APPEND,...)”,而其他时候会得到“visitFrame(Opcodes.F_SAME,...)”?我无法理解!!例如,代码如下:

    int a = 2;
    int b = 3;
    if(a == 3){
        System.out.println("hello");
    }else{
        System.out.println(a);

        if(b == 23){
            System.out.println("world");
        }else{
            System.out.println(b);
        }
    }

通过使用ASMifier,我可以得到结果(对不起,我不能附上图片,因为没有enghou的声誉),并且有这样的指令:“visitFrame(Opcodes.F_APPEND,2, new Object[]{Opcodes.INTEGER , Opcodes.INTEGER}, 0, null)" . 你能告诉我参数的含义吗?

非常感谢。

4

2 回答 2

2

您可以在下面的链接中找到详细的答案。

是否有更好的堆栈映射框架解释

Java 1.7 引入了这个选项来加速类验证。框架有两部分:变量类型和堆栈类型。第一帧由方法类型描述、初始 ?STORE 调用和方法返回类型决定。

每次 GOTO / JUMP 调用后,您需要提供 Stack Map Frames 的更新描述。为了节省空间,您可以使用 SAME、APPEND 等选项,也可以通过指定变量类型的 FULL 数组再次描述所有变量。

例如,在 CATCH 部分中,您的 Retrun Stack Type 从方法返回类型更改为捕获异常的 Exception 类类型。

如果您使用 goto 命令在不同的循环块之间跳转,则每个循环的执行块可能对循环中使用的变量使用不同的帧描述。

于 2015-11-09T08:34:57.040 回答
0

框架就像有限范围内给定类型的局部变量。局部变量已编号,但如果您解码调试信息,您可以看到它们的名称。

于 2013-07-18T15:25:22.013 回答