Community
Participate
Working Groups
Using 2.1, we have a VerifyError: java.lang.VerifyError: (class: Test, method: foo signature: (Z)I) Register 1 contains wrong type Exception in thread "main" when executing the compiled code of this source: public class Test { static int foo(boolean bool) { int j; try { if (bool) { return 1; } j = 2; } finally { if (bool) { j = 3; } } return j; } public static void main(String[] args) { foo(false); } }
public class X extends java.lang.Object { public X(); static int foo(boolean); public static void main(java.lang.String[]); } Method X() 0 aload_0 1 invokespecial #9 <Method java.lang.Object()> 4 return Method int foo(boolean) 0 iload_0 1 ifeq 9 4 jsr 26 7 iconst_1 8 ireturn 9 iconst_2 10 istore_1 11 goto 20 14 astore_3 15 jsr 26 18 aload_3 19 athrow 20 jsr 26 23 goto 35 26 astore_2 27 iload_0 28 ifeq 33 31 iconst_3 32 istore_1 33 ret 2 35 iload_1 36 ireturn Exception table: from to target type 0 14 14 any Method void main(java.lang.String[]) 0 iconst_0 1 invokestatic #23 <Method int foo(boolean)> 4 pop 5 return
Our bytecode is perfectly legite, this is a VM bytecode verifier bug. Same issue with other compilers (javac or jikes).
Javac's report is located here http://developer.java.sun.com/developer/bugParade/bugs/4494152.html This is actually a workaround against a bytecode verifier bug, which they incorrectly categorized as a compiler bug instead (see their last comments). Javac's report seems to go towards deprecated the JSR bytecode, since then their verifier no longer crashes. Instead, they suggest inlining subroutines (i.e. inlining finally blocks at each exit point instead). The net result is copying bytecode sequences for working around their VM bug, then what about backward compatibility with previous binaries exhibiting this issue ? Their handling of this problem is really inconsistent. Also when running on J9, there is no problem. J9's verifier doesn't have this bug.
Won't fix, this isn't a compiler bug, but rather a bug in Sun's bytecode verification implementation.