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

What determines the locals of a stackmap frame of a java bytecode try catch handler?

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

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

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

这是在JVMS §4.10.1.6中指定的:

An instruction satisfies an exception handler if the instructions's outgoing type state is ExcStackFrame, and the handler's target (the initial instruction of the handler code) is type safe assuming an incoming type state T. The type state T is derived from ExcStackFrame by replacing the operand stack with a stack whose sole element is the handler's exception class.

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

您(代码生成器)决定如何解决这个问题。通过声明一个具有所有可能类型的公共超类型的变量或通过删除局部变量,这相当于将变量的类型设置为 topverification type system 的根类型标记为不可用变量。

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