MvG*_*MvG 9 java jvm finally opcode jvm-bytecode
JVM规范的某些部分建议操作JSR(Jump SubRoutine),JSR_W(Jump SubRoutine Wide)和RET(从子例程返回)仅可用于类文件版本50.0(JDK 1.6):
(本节假设编译器生成版本号为50.0或更低版本的类文件,以便可以使用jsr指令.另请参见§4.10.2.5.)
然后:
要实现
try-finallyconstruct,生成class版本号为50.0或更低版本的文件的Java编程语言的编译器可以使用异常处理工具和两个特殊指令:jsr("跳转到子例程")和ret("从子例程返回" ").
另一方面,操作码描述本身并未说明这些功能的弃用.引用的文本只说明过去50.0版本中的版本如何,但在此之后并没有明确说明事态.
这个评论(对于询问这种弃用或删除背后的动机的问题)表明了类似的混淆程度,所以显然我并不是唯一一个寻找此问题的人.
MvG*_*MvG 10
在添加我的问题的链接时,我注意到§4.10.1.9:类型检查指令中没有相关的操作码.因此,这表明新的基于strackframe的类型验证方案无法处理它们,并且§4.10:类文件的验证写入:
必须使用类型检查进行验证来验证
class版本号大于或等于50.0的文件.
或者在§4.10.1中更详细地说:按类型检查进行验证:
必须使用本节中给出的类型检查规则验证
class版本号为50.0或更高版本(§4.1)的文件.如果且仅当
class文件的版本号等于50.0时,如果类型检查失败,则Java虚拟机实现可以选择尝试通过类型推断(第4.10.2节)执行验证.
所以我会说版本50.0类可能仍然包含jsr和ret,但是运行JVM实现不会验证所述类的风险,因此加载失败.
只有§6.5中记录的指令实例才会出现在
code数组中.使用保留操作码(第6.2节)的指令实例或本规范中未记录的任何操作码不得出现在code数组中.如果
class文件版本号为51.0或更高,则jsr操作码或jsr_w操作码都不会出现在code数组中.
第一段与此问题无关,因为指令在§6.5中列出,并未根据§6.2保留.但第二段显然标志着它们在51.0及更高版本中被禁止.的RET操作码,在另一方面,是没有无用的JSR或jsr_w,因为只有这两个指令可以创建类型的堆叠元件returnAddress(并且经由一些ASTORE该类型的局部变量),以通过使用保留.
我仍然认为应该在§6.5中包含一些关于这种效果的注意事项.不幸的是,如果选择Type:Bug,Category:Java Platform Standard Edition,Subcategory:specification,Java bug报告网页会隐藏Continue按钮.它说明了这一点
此子类别用于报告Java语言规范和JVM规范文本中的技术错误和含糊之处.它不是在Java语言或JVM中提出新功能的场所.正在进行的功能开发在OpenJDK中进行 ; 通过Java Community Process管理Java语言规范和JVM规范的相应增强.
但是通过JCP只是为了得到一些澄清的注释添加到这三个操作码的描述感觉像是大规模的矫枉过正.所以我希望这篇文章可以帮助那些自己无法在规范中找到答案的人.