### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java,v retrieving revision 1.133.2.3 diff -u -r1.133.2.3 CodeStream.java --- compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java 8 Jun 2006 15:47:16 -0000 1.133.2.3 +++ compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java 12 Jun 2006 16:06:17 -0000 @@ -136,6 +136,7 @@ // a jump to the next bytecode. public BranchLabel[] labels = new BranchLabel[LABELS_INCREMENT]; public int lastEntryPC; // last entry recorded + public int lastAbruptCompletion; // position of last instruction which abrupts completion: goto/return/athrow public int[] lineSeparatorPositions; public LocalVariableBinding[] locals = new LocalVariableBinding[LOCALS_INCREMENT]; @@ -239,7 +240,7 @@ } public void addVisibleLocalVariable(LocalVariableBinding localBinding) { if (((this.generateAttributes & ClassFileConstants.ATTR_VARS) == 0) - && ((this.generateAttributes & ClassFileConstants.ATTR_STACK_MAP) == 0)) + && ((this.generateAttributes & ClassFileConstants.ATTR_STACK_MAP) == 0)) return; if (visibleLocalsCount >= visibleLocals.length) @@ -354,6 +355,7 @@ } position++; bCodeStream[classFileOffset++] = Opcodes.OPC_areturn; + this.lastAbruptCompletion = this.position; } public void arrayAt(int typeBindingID) { switch (typeBindingID) { @@ -521,6 +523,7 @@ } position++; bCodeStream[classFileOffset++] = Opcodes.OPC_athrow; + this.lastAbruptCompletion = this.position; } public void baload() { if (DEBUG) System.out.println(position + "\t\tbaload"); //$NON-NLS-1$ @@ -859,6 +862,7 @@ } position++; bCodeStream[classFileOffset++] = Opcodes.OPC_dreturn; + this.lastAbruptCompletion = this.position; } public void dstore(int iArg) { if (DEBUG) System.out.println(position + "\t\tdstore:"+iArg); //$NON-NLS-1$ @@ -1293,6 +1297,7 @@ } position++; bCodeStream[classFileOffset++] = Opcodes.OPC_freturn; + this.lastAbruptCompletion = this.position; } public void fstore(int iArg) { if (DEBUG) System.out.println(position + "\t\tfstore:"+iArg); //$NON-NLS-1$ @@ -2944,7 +2949,7 @@ if (classFileOffset >= bCodeStream.length) { resizeByteArray(); } - this.inlineForwardReferencesFromLabelsTargeting(label, position); + boolean chained = this.inlineForwardReferencesFromLabelsTargeting(label, position); /* Possible optimization for code such as: public Object foo() { @@ -2961,29 +2966,25 @@ } The goto around the else block for the first if will be unreachable, because the thenClause of the second if - returns. - See inlineForwardReferencesFromLabelsTargeting defined - on the Label class for the remaining part of this - optimization. - if (!lbl.isBranchTarget(position)) { - switch(bCodeStream[classFileOffset-1]) { - case Opcodes.OPC_return : - case Opcodes.OPC_areturn: - return; - } + returns. Also see 114894 }*/ + if (chained && this.lastAbruptCompletion == this.position) { + return; + } position++; bCodeStream[classFileOffset++] = Opcodes.OPC_goto; label.branch(); + this.lastAbruptCompletion = this.position; } -final public void goto_w(BranchLabel lbl) { - if (DEBUG) System.out.println(position + "\t\tgotow:"+lbl); //$NON-NLS-1$ +final public void goto_w(BranchLabel label) { + if (DEBUG) System.out.println(position + "\t\tgotow:"+label); //$NON-NLS-1$ if (classFileOffset >= bCodeStream.length) { resizeByteArray(); } position++; bCodeStream[classFileOffset++] = Opcodes.OPC_goto_w; - lbl.branchWide(); + label.branchWide(); + this.lastAbruptCompletion = this.position; } public void i2b() { if (DEBUG) System.out.println(position + "\t\ti2b"); //$NON-NLS-1$ @@ -3556,27 +3557,15 @@ /* * Some placed labels might be branching to a goto bytecode which we can optimize better. */ -public void inlineForwardReferencesFromLabelsTargeting(BranchLabel label, int gotoLocation) { - -/* - Code required to optimized unreachable gotos. - public boolean isBranchTarget(int location) { - Label[] labels = codeStream.labels; - for (int i = codeStream.countLabels - 1; i >= 0; i--){ - Label label = labels[i]; - if ((label.position == location) && label.isStandardLabel()){ - return true; - } - } - return false; - } - */ +public boolean inlineForwardReferencesFromLabelsTargeting(BranchLabel label, int gotoLocation) { + boolean chained = false; for (int i = this.countLabels - 1; i >= 0; i--) { BranchLabel currentLabel = labels[i]; if (currentLabel.position == gotoLocation) { if (currentLabel.isStandardLabel()) { label.appendForwardReferencesFrom(currentLabel); + chained |= (label.tagBits & BranchLabel.USED) != 0; } /* Code required to optimized unreachable gotos. @@ -3586,6 +3575,7 @@ break; // same target labels should be contiguous } } + return chained; } public void init(ClassFile targetClassFile) { this.classFile = targetClassFile; @@ -3622,6 +3612,7 @@ } System.arraycopy(noLabels, 0, labels, 0, length); countLabels = 0; + this.lastAbruptCompletion = -1; stackMax = 0; stackDepth = 0; @@ -4493,6 +4484,7 @@ } position++; bCodeStream[classFileOffset++] = Opcodes.OPC_ireturn; + this.lastAbruptCompletion = this.position; } public boolean isDefinitelyAssigned(Scope scope, int initStateIndex, LocalVariableBinding local) { // Mirror of UnconditionalFlowInfo.isDefinitelyAssigned(..) @@ -5278,6 +5270,7 @@ } position++; bCodeStream[classFileOffset++] = Opcodes.OPC_lreturn; + this.lastAbruptCompletion = this.position; } public void lshl() { if (DEBUG) System.out.println(position + "\t\tlshl"); //$NON-NLS-1$ @@ -5898,6 +5891,7 @@ } position++; bCodeStream[classFileOffset++] = Opcodes.OPC_return; + this.lastAbruptCompletion = this.position; } public void saload() { if (DEBUG) System.out.println(position + "\t\tsaload"); //$NON-NLS-1$ Index: compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java,v retrieving revision 1.7.2.1 diff -u -r1.7.2.1 StackMapFrameCodeStream.java --- compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java 8 Jun 2006 15:47:16 -0000 1.7.2.1 +++ compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java 12 Jun 2006 16:06:18 -0000 @@ -910,7 +910,7 @@ /* * Some placed labels might be branching to a goto bytecode which we can optimize better. */ -public void inlineForwardReferencesFromLabelsTargeting(BranchLabel label, int gotoLocation) { +public boolean inlineForwardReferencesFromLabelsTargeting(BranchLabel label, int gotoLocation) { /* Code required to optimized unreachable gotos. @@ -925,6 +925,7 @@ return false; } */ + boolean chained = false; boolean hasStandardLabel = false; boolean removeFrame = true; for (int i = this.countLabels - 1; i >= 0; i--) { @@ -948,6 +949,7 @@ if (currentLabel.position == gotoLocation) { if (currentLabel.isStandardLabel()){ label.appendForwardReferencesFrom(currentLabel); + chained |= (label.tagBits & BranchLabel.USED) != 0; // we should remove the frame corresponding to otherLabel position in order to prevent unused stack frame if (removeFrame) { currentLabel.tagBits &= ~BranchLabel.USED; @@ -963,6 +965,7 @@ } } } + return chained; } public void init(ClassFile targetClassFile) { super.init(targetClassFile); #P org.eclipse.jdt.core.tests.compiler Index: src/org/eclipse/jdt/core/tests/compiler/regression/TryStatementTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryStatementTest.java,v retrieving revision 1.25 diff -u -r1.25 TryStatementTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/TryStatementTest.java 11 Apr 2006 06:56:08 -0000 1.25 +++ src/org/eclipse/jdt/core/tests/compiler/regression/TryStatementTest.java 12 Jun 2006 16:06:22 -0000 @@ -2970,6 +2970,737 @@ assertTrue(false); } } +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=114894 +public void test047() { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " boolean bool() { return true; }\n" + + " void foo() {\n" + + " try {\n" + + " if (bool()) {\n" + + " return;\n" + + " }\n" + + " } catch (Exception e) {\n" + + " }\n" + + " }\n" + + " int foo2() {\n" + + " try {\n" + + " while (bool()) {\n" + + " return 0;\n" + + " }\n" + + " } catch (Exception e) {\n" + + " }\n" + + " return 1;\n" + + " }\n" + + " long foo3() {\n" + + " try {\n" + + " do {\n" + + " if (true) return 0L;\n" + + " } while (bool());\n" + + " } catch (Exception e) {\n" + + " }\n" + + " return 1L;\n" + + " } \n" + + " float foo4() {\n" + + " try {\n" + + " for (int i = 0; bool(); i++) {\n" + + " return 0.0F;\n" + + " }\n" + + " } catch (Exception e) {\n" + + " }\n" + + " return 1.0F;\n" + + " } \n" + + " double bar() {\n" + + " if (bool()) {\n" + + " if (bool())\n" + + " return 0.0;\n" + + " } else {\n" + + " if (bool()) {\n" + + " throw new NullPointerException();\n" + + " }\n" + + " }\n" + + " return 1.0;\n" + + " }\n" + + " void baz(int i) {\n" + + " if (bool()) {\n" + + " switch(i) {\n" + + " case 0 : return;\n" + + " default : break;\n" + + " }\n" + + " } else {\n" + + " bool();\n" + + " }\n" + + " }\n" + + "}\n", + }, + ""); + + String expectedOutput = + " // Method descriptor #6 ()V\n" + + " // Stack: 1, Locals: 1\n" + + " public X();\n" + + " 0 aload_0 [this]\n" + + " 1 invokespecial java.lang.Object() [8]\n" + + " 4 return\n" + + " Line numbers:\n" + + " [pc: 0, line: 1]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 5] local: this index: 0 type: X\n" + + " \n" + + " // Method descriptor #15 ()Z\n" + + " // Stack: 1, Locals: 1\n" + + " boolean bool();\n" + + " 0 iconst_1\n" + + " 1 ireturn\n" + + " Line numbers:\n" + + " [pc: 0, line: 2]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 2] local: this index: 0 type: X\n" + + " \n" + + " // Method descriptor #6 ()V\n" + + " // Stack: 1, Locals: 2\n" + + " void foo();\n" + + " 0 aload_0 [this]\n" + + " 1 invokevirtual X.bool() : boolean [17]\n" + + " 4 ifeq 9\n" + + " 7 return\n" + + " 8 astore_1\n" + + " 9 return\n" + + " Exception Table:\n" + + " [pc: 0, pc: 7] -> 8 when : java.lang.Exception\n" + + " Line numbers:\n" + + " [pc: 0, line: 5]\n" + + " [pc: 7, line: 6]\n" + + " [pc: 8, line: 8]\n" + + " [pc: 9, line: 10]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 10] local: this index: 0 type: X\n" + + " \n" + + " // Method descriptor #22 ()I\n" + + " // Stack: 1, Locals: 2\n" + + " int foo2();\n" + + " 0 aload_0 [this]\n" + + " 1 invokevirtual X.bool() : boolean [17]\n" + + " 4 ifeq 10\n" + + " 7 iconst_0\n" + + " 8 ireturn\n" + + " 9 astore_1\n" + + " 10 iconst_1\n" + + " 11 ireturn\n" + + " Exception Table:\n" + + " [pc: 0, pc: 7] -> 9 when : java.lang.Exception\n" + + " Line numbers:\n" + + " [pc: 0, line: 13]\n" + + " [pc: 7, line: 14]\n" + + " [pc: 9, line: 16]\n" + + " [pc: 10, line: 18]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 12] local: this index: 0 type: X\n" + + " \n" + + " // Method descriptor #24 ()J\n" + + " // Stack: 2, Locals: 2\n" + + " long foo3();\n" + + " 0 lconst_0\n" + + " 1 lreturn\n" + + " 2 astore_1\n" + + " 3 lconst_1\n" + + " 4 lreturn\n" + + " Line numbers:\n" + + " [pc: 0, line: 23]\n" + + " [pc: 2, line: 25]\n" + + " [pc: 3, line: 27]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 5] local: this index: 0 type: X\n" + + " \n" + + " // Method descriptor #26 ()F\n" + + " // Stack: 1, Locals: 2\n" + + " float foo4();\n" + + " 0 iconst_0\n" + + " 1 istore_1 [i]\n" + + " 2 goto 7\n" + + " 5 fconst_0\n" + + " 6 freturn\n" + + " 7 aload_0 [this]\n" + + " 8 invokevirtual X.bool() : boolean [17]\n" + + " 11 ifne 5\n" + + " 14 goto 18\n" + + " 17 astore_1\n" + + " 18 fconst_1\n" + + " 19 freturn\n" + + " Exception Table:\n" + + " [pc: 0, pc: 5] -> 17 when : java.lang.Exception\n" + + " [pc: 7, pc: 17] -> 17 when : java.lang.Exception\n" + + " Line numbers:\n" + + " [pc: 0, line: 31]\n" + + " [pc: 5, line: 32]\n" + + " [pc: 7, line: 31]\n" + + " [pc: 17, line: 34]\n" + + " [pc: 18, line: 36]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 20] local: this index: 0 type: X\n" + + " [pc: 2, pc: 14] local: i index: 1 type: int\n" + + " \n" + + " // Method descriptor #30 ()D\n" + + " // Stack: 2, Locals: 1\n" + + " double bar();\n" + + " 0 aload_0 [this]\n" + + " 1 invokevirtual X.bool() : boolean [17]\n" + + " 4 ifeq 16\n" + + " 7 aload_0 [this]\n" + + " 8 invokevirtual X.bool() : boolean [17]\n" + + " 11 ifeq 31\n" + + " 14 dconst_0\n" + + " 15 dreturn\n" + + " 16 aload_0 [this]\n" + + " 17 invokevirtual X.bool() : boolean [17]\n" + + " 20 ifeq 31\n" + + " 23 new java.lang.NullPointerException [31]\n" + + " 26 dup\n" + + " 27 invokespecial java.lang.NullPointerException() [33]\n" + + " 30 athrow\n" + + " 31 dconst_1\n" + + " 32 dreturn\n" + + " Line numbers:\n" + + " [pc: 0, line: 39]\n" + + " [pc: 7, line: 40]\n" + + " [pc: 14, line: 41]\n" + + " [pc: 16, line: 43]\n" + + " [pc: 23, line: 44]\n" + + " [pc: 31, line: 47]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 33] local: this index: 0 type: X\n" + + " \n" + + " // Method descriptor #35 (I)V\n" + + " // Stack: 1, Locals: 2\n" + + " void baz(int i);\n" + + " 0 aload_0 [this]\n" + + " 1 invokevirtual X.bool() : boolean [17]\n" + + " 4 ifeq 32\n" + + " 7 iload_1 [i]\n" + + " 8 tableswitch default: 29\n" + + " case 0: 28\n" + + " 28 return\n" + + " 29 goto 37\n" + + " 32 aload_0 [this]\n" + + " 33 invokevirtual X.bool() : boolean [17]\n" + + " 36 pop\n" + + " 37 return\n" + + " Line numbers:\n" + + " [pc: 0, line: 50]\n" + + " [pc: 7, line: 51]\n" + + " [pc: 28, line: 52]\n" + + " [pc: 32, line: 56]\n" + + " [pc: 37, line: 58]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 38] local: this index: 0 type: X\n" + + " [pc: 0, pc: 38] local: i index: 1 type: int\n"; + try { + File f = new File(OUTPUT_DIR + File.separator + "X.class"); + byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f); + ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler(); + String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED); + int index = result.indexOf(expectedOutput); + if (index == -1 || expectedOutput.length() == 0) { + System.out.println(Util.displayString(result, 3)); + } + if (index == -1) { + assertEquals("Wrong contents", expectedOutput, result); + } + } catch (org.eclipse.jdt.core.util.ClassFormatException e) { + assertTrue(false); + } catch (IOException e) { + assertTrue(false); + } +} + +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=114894 - variation +public void test048() { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " boolean bool() { return true; }\n" + + " void foo() {\n" + + " try {\n" + + " if (bool()) {\n" + + " throw new NullPointerException();\n" + + " }\n" + + " } catch (Exception e) {\n" + + " }\n" + + " }\n" + + " void foo2() {\n" + + " try {\n" + + " while (bool()) {\n" + + " throw new NullPointerException();\n" + + " }\n" + + " } catch (Exception e) {\n" + + " }\n" + + " }\n" + + " void foo3() {\n" + + " try {\n" + + " do {\n" + + " if (true) throw new NullPointerException();\n" + + " } while (bool());\n" + + " } catch (Exception e) {\n" + + " }\n" + + " } \n" + + " void foo4() {\n" + + " try {\n" + + " for (int i = 0; bool(); i++) {\n" + + " throw new NullPointerException();\n" + + " }\n" + + " } catch (Exception e) {\n" + + " }\n" + + " } \n" + + " void bar() {\n" + + " if (bool()) {\n" + + " if (bool())\n" + + " throw new NullPointerException();\n" + + " } else {\n" + + " if (bool()) {\n" + + " throw new NullPointerException();\n" + + " }\n" + + " }\n" + + " }\n" + + " void baz(int i) {\n" + + " if (bool()) {\n" + + " switch(i) {\n" + + " case 0 : throw new NullPointerException();\n" + + " default : break;\n" + + " }\n" + + " } else {\n" + + " bool();\n" + + " }\n" + + " }\n" + + "}\n", + }, + ""); + + String expectedOutput = + " // Method descriptor #6 ()V\n" + + " // Stack: 1, Locals: 1\n" + + " public X();\n" + + " 0 aload_0 [this]\n" + + " 1 invokespecial java.lang.Object() [8]\n" + + " 4 return\n" + + " Line numbers:\n" + + " [pc: 0, line: 1]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 5] local: this index: 0 type: X\n" + + " \n" + + " // Method descriptor #15 ()Z\n" + + " // Stack: 1, Locals: 1\n" + + " boolean bool();\n" + + " 0 iconst_1\n" + + " 1 ireturn\n" + + " Line numbers:\n" + + " [pc: 0, line: 2]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 2] local: this index: 0 type: X\n" + + " \n" + + " // Method descriptor #6 ()V\n" + + " // Stack: 2, Locals: 2\n" + + " void foo();\n" + + " 0 aload_0 [this]\n" + + " 1 invokevirtual X.bool() : boolean [17]\n" + + " 4 ifeq 16\n" + + " 7 new java.lang.NullPointerException [19]\n" + + " 10 dup\n" + + " 11 invokespecial java.lang.NullPointerException() [21]\n" + + " 14 athrow\n" + + " 15 astore_1\n" + + " 16 return\n" + + " Exception Table:\n" + + " [pc: 0, pc: 15] -> 15 when : java.lang.Exception\n" + + " Line numbers:\n" + + " [pc: 0, line: 5]\n" + + " [pc: 7, line: 6]\n" + + " [pc: 15, line: 8]\n" + + " [pc: 16, line: 10]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 17] local: this index: 0 type: X\n" + + " \n" + + " // Method descriptor #6 ()V\n" + + " // Stack: 2, Locals: 2\n" + + " void foo2();\n" + + " 0 aload_0 [this]\n" + + " 1 invokevirtual X.bool() : boolean [17]\n" + + " 4 ifeq 16\n" + + " 7 new java.lang.NullPointerException [19]\n" + + " 10 dup\n" + + " 11 invokespecial java.lang.NullPointerException() [21]\n" + + " 14 athrow\n" + + " 15 astore_1\n" + + " 16 return\n" + + " Exception Table:\n" + + " [pc: 0, pc: 15] -> 15 when : java.lang.Exception\n" + + " Line numbers:\n" + + " [pc: 0, line: 13]\n" + + " [pc: 7, line: 14]\n" + + " [pc: 15, line: 16]\n" + + " [pc: 16, line: 18]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 17] local: this index: 0 type: X\n" + + " \n" + + " // Method descriptor #6 ()V\n" + + " // Stack: 2, Locals: 2\n" + + " void foo3();\n" + + " 0 new java.lang.NullPointerException [19]\n" + + " 3 dup\n" + + " 4 invokespecial java.lang.NullPointerException() [21]\n" + + " 7 athrow\n" + + " 8 astore_1\n" + + " 9 return\n" + + " Exception Table:\n" + + " [pc: 0, pc: 8] -> 8 when : java.lang.Exception\n" + + " Line numbers:\n" + + " [pc: 0, line: 22]\n" + + " [pc: 8, line: 24]\n" + + " [pc: 9, line: 26]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 10] local: this index: 0 type: X\n" + + " \n" + + " // Method descriptor #6 ()V\n" + + " // Stack: 2, Locals: 2\n" + + " void foo4();\n" + + " 0 iconst_0\n" + + " 1 istore_1 [i]\n" + + " 2 goto 13\n" + + " 5 new java.lang.NullPointerException [19]\n" + + " 8 dup\n" + + " 9 invokespecial java.lang.NullPointerException() [21]\n" + + " 12 athrow\n" + + " 13 aload_0 [this]\n" + + " 14 invokevirtual X.bool() : boolean [17]\n" + + " 17 ifne 5\n" + + " 20 goto 24\n" + + " 23 astore_1\n" + + " 24 return\n" + + " Exception Table:\n" + + " [pc: 0, pc: 23] -> 23 when : java.lang.Exception\n" + + " Line numbers:\n" + + " [pc: 0, line: 29]\n" + + " [pc: 5, line: 30]\n" + + " [pc: 13, line: 29]\n" + + " [pc: 23, line: 32]\n" + + " [pc: 24, line: 34]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 25] local: this index: 0 type: X\n" + + " [pc: 2, pc: 20] local: i index: 1 type: int\n" + + " \n" + + " // Method descriptor #6 ()V\n" + + " // Stack: 2, Locals: 1\n" + + " void bar();\n" + + " 0 aload_0 [this]\n" + + " 1 invokevirtual X.bool() : boolean [17]\n" + + " 4 ifeq 22\n" + + " 7 aload_0 [this]\n" + + " 8 invokevirtual X.bool() : boolean [17]\n" + + " 11 ifeq 37\n" + + " 14 new java.lang.NullPointerException [19]\n" + + " 17 dup\n" + + " 18 invokespecial java.lang.NullPointerException() [21]\n" + + " 21 athrow\n" + + " 22 aload_0 [this]\n" + + " 23 invokevirtual X.bool() : boolean [17]\n" + + " 26 ifeq 37\n" + + " 29 new java.lang.NullPointerException [19]\n" + + " 32 dup\n" + + " 33 invokespecial java.lang.NullPointerException() [21]\n" + + " 36 athrow\n" + + " 37 return\n" + + " Line numbers:\n" + + " [pc: 0, line: 36]\n" + + " [pc: 7, line: 37]\n" + + " [pc: 14, line: 38]\n" + + " [pc: 22, line: 40]\n" + + " [pc: 29, line: 41]\n" + + " [pc: 37, line: 44]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 38] local: this index: 0 type: X\n" + + " \n" + + " // Method descriptor #31 (I)V\n" + + " // Stack: 2, Locals: 2\n" + + " void baz(int i);\n" + + " 0 aload_0 [this]\n" + + " 1 invokevirtual X.bool() : boolean [17]\n" + + " 4 ifeq 39\n" + + " 7 iload_1 [i]\n" + + " 8 tableswitch default: 36\n" + + " case 0: 28\n" + + " 28 new java.lang.NullPointerException [19]\n" + + " 31 dup\n" + + " 32 invokespecial java.lang.NullPointerException() [21]\n" + + " 35 athrow\n" + + " 36 goto 44\n" + + " 39 aload_0 [this]\n" + + " 40 invokevirtual X.bool() : boolean [17]\n" + + " 43 pop\n" + + " 44 return\n" + + " Line numbers:\n" + + " [pc: 0, line: 46]\n" + + " [pc: 7, line: 47]\n" + + " [pc: 28, line: 48]\n" + + " [pc: 39, line: 52]\n" + + " [pc: 44, line: 54]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 45] local: this index: 0 type: X\n" + + " [pc: 0, pc: 45] local: i index: 1 type: int\n"; + try { + File f = new File(OUTPUT_DIR + File.separator + "X.class"); + byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f); + ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler(); + String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED); + int index = result.indexOf(expectedOutput); + if (index == -1 || expectedOutput.length() == 0) { + System.out.println(Util.displayString(result, 3)); + } + if (index == -1) { + assertEquals("Wrong contents", expectedOutput, result); + } + } catch (org.eclipse.jdt.core.util.ClassFormatException e) { + assertTrue(false); + } catch (IOException e) { + assertTrue(false); + } +} +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=114894 - variation +public void test049() { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " boolean bool() { return true; }\n" + + " void foo() {\n" + + " check: try {\n" + + " if (bool()) {\n" + + " break check;\n" + + " }\n" + + " } catch (Exception e) {\n" + + " }\n" + + " }\n" + + " void foo2() {\n" + + " check: try {\n" + + " while (bool()) {\n" + + " break check;\n" + + " }\n" + + " } catch (Exception e) {\n" + + " }\n" + + " }\n" + + " void foo3() {\n" + + " check: try {\n" + + " do {\n" + + " if (true) break check;\n" + + " } while (bool());\n" + + " } catch (Exception e) {\n" + + " }\n" + + " } \n" + + " void foo4() {\n" + + " check: try {\n" + + " for (int i = 0; bool(); i++) {\n" + + " break check;\n" + + " }\n" + + " } catch (Exception e) {\n" + + " }\n" + + " } \n" + + " void bar() {\n" + + " check: if (bool()) {\n" + + " if (bool())\n" + + " break check;\n" + + " } else {\n" + + " if (bool()) {\n" + + " break check;\n" + + " }\n" + + " }\n" + + " }\n" + + " void baz(int i) {\n" + + " check: if (bool()) {\n" + + " switch(i) {\n" + + " case 0 : break check;\n" + + " default : break;\n" + + " }\n" + + " } else {\n" + + " bool();\n" + + " }\n" + + " }\n" + + "}\n", + }, + ""); + + String expectedOutput = + " // Method descriptor #6 ()V\n" + + " // Stack: 1, Locals: 1\n" + + " public X();\n" + + " 0 aload_0 [this]\n" + + " 1 invokespecial java.lang.Object() [8]\n" + + " 4 return\n" + + " Line numbers:\n" + + " [pc: 0, line: 1]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 5] local: this index: 0 type: X\n" + + " \n" + + " // Method descriptor #15 ()Z\n" + + " // Stack: 1, Locals: 1\n" + + " boolean bool();\n" + + " 0 iconst_1\n" + + " 1 ireturn\n" + + " Line numbers:\n" + + " [pc: 0, line: 2]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 2] local: this index: 0 type: X\n" + + " \n" + + " // Method descriptor #6 ()V\n" + + " // Stack: 1, Locals: 2\n" + + " void foo();\n" + + " 0 aload_0 [this]\n" + + " 1 invokevirtual X.bool() : boolean [17]\n" + + " 4 ifeq 14\n" + + " 7 goto 14\n" + + " 10 goto 14\n" + + " 13 astore_1\n" + + " 14 return\n" + + " Exception Table:\n" + + " [pc: 0, pc: 7] -> 13 when : java.lang.Exception\n" + + " [pc: 10, pc: 13] -> 13 when : java.lang.Exception\n" + + " Line numbers:\n" + + " [pc: 0, line: 5]\n" + + " [pc: 7, line: 6]\n" + + " [pc: 13, line: 8]\n" + + " [pc: 14, line: 10]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 15] local: this index: 0 type: X\n" + + " \n" + + " // Method descriptor #6 ()V\n" + + " // Stack: 1, Locals: 2\n" + + " void foo2();\n" + + " 0 aload_0 [this]\n" + + " 1 invokevirtual X.bool() : boolean [17]\n" + + " 4 ifeq 14\n" + + " 7 goto 14\n" + + " 10 goto 14\n" + + " 13 astore_1\n" + + " 14 return\n" + + " Exception Table:\n" + + " [pc: 0, pc: 7] -> 13 when : java.lang.Exception\n" + + " [pc: 10, pc: 13] -> 13 when : java.lang.Exception\n" + + " Line numbers:\n" + + " [pc: 0, line: 13]\n" + + " [pc: 7, line: 14]\n" + + " [pc: 13, line: 16]\n" + + " [pc: 14, line: 18]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 15] local: this index: 0 type: X\n" + + " \n" + + " // Method descriptor #6 ()V\n" + + " // Stack: 1, Locals: 2\n" + + " void foo3();\n" + + " 0 goto 7\n" + + " 3 goto 7\n" + + " 6 astore_1\n" + + " 7 return\n" + + " Exception Table:\n" + + " [pc: 3, pc: 6] -> 6 when : java.lang.Exception\n" + + " Line numbers:\n" + + " [pc: 0, line: 22]\n" + + " [pc: 6, line: 24]\n" + + " [pc: 7, line: 26]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 8] local: this index: 0 type: X\n" + + " \n" + + " // Method descriptor #6 ()V\n" + + " // Stack: 1, Locals: 2\n" + + " void foo4();\n" + + " 0 iconst_0\n" + + " 1 istore_1 [i]\n" + + " 2 goto 8\n" + + " 5 goto 19\n" + + " 8 aload_0 [this]\n" + + " 9 invokevirtual X.bool() : boolean [17]\n" + + " 12 ifne 5\n" + + " 15 goto 19\n" + + " 18 astore_1\n" + + " 19 return\n" + + " Exception Table:\n" + + " [pc: 0, pc: 5] -> 18 when : java.lang.Exception\n" + + " [pc: 8, pc: 18] -> 18 when : java.lang.Exception\n" + + " Line numbers:\n" + + " [pc: 0, line: 29]\n" + + " [pc: 5, line: 30]\n" + + " [pc: 8, line: 29]\n" + + " [pc: 18, line: 32]\n" + + " [pc: 19, line: 34]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 20] local: this index: 0 type: X\n" + + " [pc: 2, pc: 15] local: i index: 1 type: int\n" + + " \n" + + " // Method descriptor #6 ()V\n" + + " // Stack: 1, Locals: 1\n" + + " void bar();\n" + + " 0 aload_0 [this]\n" + + " 1 invokevirtual X.bool() : boolean [17]\n" + + " 4 ifeq 20\n" + + " 7 aload_0 [this]\n" + + " 8 invokevirtual X.bool() : boolean [17]\n" + + " 11 ifeq 27\n" + + " 14 goto 27\n" + + " 17 goto 27\n" + + " 20 aload_0 [this]\n" + + " 21 invokevirtual X.bool() : boolean [17]\n" + + " 24 ifeq 27\n" + + " 27 return\n" + + " Line numbers:\n" + + " [pc: 0, line: 36]\n" + + " [pc: 7, line: 37]\n" + + " [pc: 14, line: 38]\n" + + " [pc: 20, line: 40]\n" + + " [pc: 27, line: 44]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 28] local: this index: 0 type: X\n" + + " \n" + + " // Method descriptor #28 (I)V\n" + + " // Stack: 1, Locals: 2\n" + + " void baz(int i);\n" + + " 0 aload_0 [this]\n" + + " 1 invokevirtual X.bool() : boolean [17]\n" + + " 4 ifeq 34\n" + + " 7 iload_1 [i]\n" + + " 8 tableswitch default: 31\n" + + " case 0: 28\n" + + " 28 goto 39\n" + + " 31 goto 39\n" + + " 34 aload_0 [this]\n" + + " 35 invokevirtual X.bool() : boolean [17]\n" + + " 38 pop\n" + + " 39 return\n" + + " Line numbers:\n" + + " [pc: 0, line: 46]\n" + + " [pc: 7, line: 47]\n" + + " [pc: 28, line: 48]\n" + + " [pc: 34, line: 52]\n" + + " [pc: 39, line: 54]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 40] local: this index: 0 type: X\n" + + " [pc: 0, pc: 40] local: i index: 1 type: int\n"; + try { + File f = new File(OUTPUT_DIR + File.separator + "X.class"); + byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f); + ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler(); + String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED); + int index = result.indexOf(expectedOutput); + if (index == -1 || expectedOutput.length() == 0) { + System.out.println(Util.displayString(result, 3)); + } + if (index == -1) { + assertEquals("Wrong contents", expectedOutput, result); + } + } catch (org.eclipse.jdt.core.util.ClassFormatException e) { + assertTrue(false); + } catch (IOException e) { + assertTrue(false); + } +} public static Class testClass() { return TryStatementTest.class; }