在为我的问题添加链接时,我注意到§4.10.1.9: Type Checking Instructions中没有相关操作码。所以这表明新的基于 strackframe 的类型验证方案无法处理它们,并且§4.10: Verification of class Files写道:
必须使用类型检查验证来验证class
版本号大于或等于 50.0 的文件。
或者在§4.10.1 中更详细地说明:通过类型检查进行验证:
class
版本号为 50.0 或更高(第4.1节)的文件必须使用本节中给出的类型检查规则进行验证。
当且仅当class
文件的版本号等于 50.0 时,如果类型检查失败,Java 虚拟机实现可能会选择尝试通过类型推断执行验证(第 4.10.2 节)。
所以我想说一个 50.0 版本的类可能仍然包含jsr和ret,但存在一些风险,即 JVM 实现不会验证所述类,因此加载它会失败。
但后来我在§4.9.1中发现了一个更明确的规则:静态约束:
只有§6.5中记录的指令实例可能会出现在code
数组中。使用保留操作码(第 6.2 节)或本规范中未记录的任何操作码的指令实例不得出现在code
数组中。
如果class
文件版本号为 51.0 或更高版本,则jsr操作码或jsr_w操作码都不会出现在code
数组中。
第一段与这个问题无关,因为说明在第 6.5 节中列出,并且根据第 6.2 节没有保留。但是第二段明确地将它们标记为在 51.0 及更高版本中被禁止。另一方面,如果没有jsr或jsr_w ,则ret操作码是无用的,因为只有这两条指令才能创建类型的堆栈元素(并通过一些存储该类型的局部变量)以供ret使用。returnAddress
我仍然认为应该在 §6.5 中包含一些关于此效果的通知。不幸的是,如果选择 Type: Bug、 Category: Java Platform Standard Edition、 Subcategory: specification , Java bug 报告网页会隐藏Continue按钮。它指出
此子类别用于报告 Java 语言规范和 JVM 规范文本中的技术错误和歧义。它不是提出 Java 语言或 JVM 新特性的场所。正在进行的功能开发是在OpenJDK中进行的;Java 语言规范和 JVM 规范的相应增强是通过Java Community Process管理的。
But going through the JCP just to get some clarifying notes added to the descriptions of these three opcodes feels like massive overkill. So I hope that this post here helps those who on their own fail to find an answer in the specification itself.