Community
Participate
Working Groups
Test case: public class X { public static final int CONST = 0x7fffffff; public static void main(String[] args) { int i = CONST; switch (i) { case CONST: System.out.println("SUCCESS"); break; } } } This code compiles fine on Eclipse 2.0, but the resulting .class file executiuon leads to VerifyError on a 1.3.1 VM. java.lang.VerifyError: (class: X, method: main signature: ([Ljava/lang/String;)V) Illegal instruction found at offset 4 Exception in thread "main". On a 1.4 VM the problem has been fixed. Looking at the Sun bug database, we found the problem: See Re: http://developer.java.sun.com/developer/bugParade/bugs/4411025.html for further details. The bytecodes generated by Eclipse are: Method void main(java.lang.String[]) 0 ldc #16 <Integer 2147483647> 2 istore_1 3 iload_1 4 tableswitch 2147483647 to 2147483647: default=32 2147483647: 24 24 getstatic #22 <Field java.io.PrintStream out> 27 ldc #24 <String "SUCCESS"> 29 invokevirtual #30 <Method void println(java.lang.String)> 32 return The bytecodes generated by Sun 1.3.1 or 1.4 are: Method void main(java.lang.String[]) 0 ldc #2 <Integer 2147483647> 2 istore_1 3 iload_1 4 lookupswitch 1: default=32 2147483647: 24 24 getstatic #3 <Field java.io.PrintStream out> 27 ldc #4 <String "SUCCESS"> 29 invokevirtual #5 <Method void println(java.lang.String)> 32 return The difference is the lookupswitch instead of a tableswitch. We might want to generate a workaround to generate a lookupswitch if target < 1.4.
Yes, I think we want to work-around the VM bug for such targets.
Proposed fix from Olivier: if (needSwitch) { int max = localKeysCopy[caseCount - 1]; int min = localKeysCopy[0]; if ((long) (caseCount * 2.5) > ((long) max - (long) min)) { if (max > 0x7FFF0000 && currentScope.environment ().options.complianceLevel < CompilerOptions.JDK1_4) { // we need a special case // see http://dev.eclipse.org/bugs/show_bug.cgi?id=21557 codeStream.lookupswitch(defaultLabel, constants, sortedIndexes, caseLabels); } else { codeStream.tableswitch( defaultLabel, min, max, constants, sortedIndexes, caseLabels); } } else { codeStream.lookupswitch(defaultLabel, constants, sortedIndexes, caseLabels); } codeStream.updateLastRecordedEndPC(codeStream.position); }
Integrated, fixed.
Verified.
Verified
Verified in 2.1 M1