什么决定了 java 字节码 try catch 处理程序的堆栈图帧的局部变量?

Aur*_*Lee 7 java bytecode javac

假设我们用 try catch 块包围了一些字节码指令,并且本地类型在 try catch 块范围之间发生变化(以前用于 int 类型的本地寄存器现在用于引用类型,位于 TCB 内部)。

这个try catch块的handler只能有一个frame(不允许分割,java字节码规则)。但问题是,如果在本地类型更改之前抛出异常,则指针框架会有所不同。

根据在 TCB 中抛出异常时设置的本地类型,处理程序必须具有不同的帧,但这在 java 字节码中是不可能的。因此我的问题是:处理程序框架对应于 TCB 中的哪个部分?它会使用“超级类型”而不是选择一个(-> 未初始化)吗?

Hol*_*ger 11

这在JVMS §4.10.1.6 中指定:

如果指令的传出类型 state 是,则指令满足异常处理程序ExcStackFrame,并且处理程序的目标(处理程序代码的初始指令)是类型安全的,假设传入类型 state T。类型状态TExcStackFrame通过用一个堆栈替换操作数堆栈来派生的,堆栈的唯一元素是处理程序的异常类。

换句话说,异常处理程序保护的所有指令的输出状态必须具有可分配给异常处理程序变量的局部变量。

您(代码生成器)决定如何解决这个问题。要么声明一个变量具有所有可能类型的公共超类型,要么删除局部变量,这相当于将变量的类型设置为top验证类型系统的根类型标记了一个不可用的变量。

对于普通的 Java 代码,不可能使用try在关联catch块内的块中声明的变量。您也不能将变量重新声明为不同的类型。因此,它总是归结为删除这些变量,并且只有在受保护的代码之前已经存在的变量。