JVM规范中JSR/RET的状态



JVM规范的某些部分表明,操作JSR(跳转子程序)、JSR_W(全跳转子程序)和RET(从子程序返回)只能在类文件版本50.0(JDK 1.6)之前使用:

3.13最终编译

(本节假设编译器生成版本号为50.0或更低的类文件,以便可以使用jsr指令。另请参见§4.10.2.5。)

后来:

4.10.2.5.异常和finally

为了实现try-finally构造,生成版本号为50.0或更低的class文件的Java编程语言编译器可以将异常处理功能与两条特殊指令一起使用:jsr("跳转到子例程")和ret

另一方面,操作码描述本身并没有说明对这些特性的贬低。引用的文本只说明了50.0之前版本的情况,但没有明确说明之后的情况。

这条评论(针对一个询问这种贬低或删除背后动机的问题)表明了类似程度的困惑,所以显然我不是唯一一个寻求这一点的人。

在为我的问题添加链接时,我注意到§4.10.1.9:类型检查指令中没有相关操作码。因此,这表明新的基于strackframe的类型验证方案无法处理它们,并且§4.10:类文件的验证写道:

必须使用类型检查验证来验证版本号大于或等于50.0的class文件。

或在§4.10.1:通过类型检查进行验证:中进行更详细的说明

版本号为50.0或以上(§4.1)的class文件必须使用本节中给出的类型检查规则进行验证。

如果并且仅当class文件的版本号等于50.0,那么如果类型检查失败,Java虚拟机实现可以选择尝试通过类型推断进行验证(§4.10.2)

因此,我认为50.0版本的类可能仍然包含jsrret,但存在JVM实现无法验证所述类的风险,因此加载失败。

但后来我发现了一个更明确的规则,在§4.9.1:Static Constraints:中

只有§6.5中记录的指令实例才能出现在code数组中。使用保留操作码(§6.2)或本规范中未记录的任何操作码的指令实例不得出现在code数组中。

如果class文件版本号为51.0或更高,则jsr操作码或json_w操码都不会出现在code数组中。

第一段与这个问题无关,因为说明列于§6.5中,而不是根据§6.2保留的。但第二段明确指出,在51.0及以上版本中,它们是被禁止的。另一方面,如果没有jsrjson_wret操作码是无用的,因为只有这两条指令才能创建类型为returnAddress的堆栈元素(并通过一些astore创建该类型的局部变量),供ret使用。


我仍然认为,§6.5中应该包含一些关于这一点的通知。不幸的是,如果选择类型:bug、类别:Java平台标准版和子类别:规范,Java错误报告网页将隐藏继续按钮。它指出

此子类别用于报告Java语言规范和JVM规范文本中的技术错误和歧义。这里不是在Java语言或JVM中提出新功能的地方。正在进行的功能开发是在OpenJDK中进行的;Java语言规范和JVM规范的相应增强通过Java社区进程进行管理。

但是,通过JCP只是为了在这三个操作码的描述中添加一些澄清注释,感觉太过分了。所以我希望这篇文章能帮助那些自己在规范中找不到答案的人。

相关内容

  • 没有找到相关文章

最新更新