在添加我的问题的链接时,我注意到有问题的操作码不存在§4.10.1.9:类型检查说明 http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.10.1.9。所以这表明新的基于 strackframe 的类型验证方案无法处理它们,并且§4.10:类文件的验证 http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.10 writes:
必须使用类型检查验证来验证class
版本号大于或等于 50.0 的文件。
或者更详细地在§4.10.1:通过类型检查进行验证 http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.10.1:
A class
版本号为50.0或以上的文件(§4.1 http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.1)必须使用本节中给出的类型检查规则进行验证。
当且仅当,一个class
文件的版本号等于 50.0,那么如果类型检查失败,Java 虚拟机实现可能会选择尝试通过类型推断来执行验证(§4.10.2 http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.10.2).
所以我会说版本 50.0 类may仍含有jsr and ret,但存在 JVM 实现不会验证所述类并因此加载失败的风险。
但后来我发现了一个更明确的规则,§4.9.1:静态约束 http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1:
仅记录的说明的实例§6.5 http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5可能会出现在code
大批。使用保留操作码的指令实例(§6.2 http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.2)或本规范中未记录的任何操作码不得出现在code
array.
If the class
文件版本号为 51.0 或以上,则jsr操作码或jsr_w操作码可能出现在code
array.
第一段与此问题无关,因为说明已在第 6.5 节中列出,并且根据第 6.2 节不予保留。但第二段明确将它们标记为在 51.0 及更高版本中禁止的。这ret另一方面,如果没有操作码,则毫无用处jsr or jsr_w,因为只有这两条指令可以创建类型为的堆栈元素returnAddress
(并通过一些astore该类型的局部变量)被使用ret.
我仍然认为第 6.5 节中应该包含一些关于此效果的通知。不幸的是,Java 错误报告网页 http://bugreport.java.com/隐藏Continue按钮,如果选择类型:Bug, 类别:Java平台标准版, 子类别:规格。它指出
该子类别用于报告 Java 语言规范和 JVM 规范文本中的技术错误和歧义。它不是提出 Java 语言或 JVM 新功能的场所。持续的功能开发是在OpenJDK http://openjdk.java.net/jeps/; Java 语言规范和 JVM 规范的相应增强是通过Java 社区进程 http://www.jcp.org/.
但是,仅仅为了在这三个操作码的描述中添加一些澄清说明而浏览 JCP 感觉就有点矫枉过正了。因此,我希望这篇文章可以帮助那些无法在规范本身中找到答案的人。