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 --- 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 13 Jun 2006 09:25:11 -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,36 +3557,21 @@ /* * 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) { + final int NONE = 0, CASE = 1, STANDARD = 2; + int chaining = NONE; for (int i = this.countLabels - 1; i >= 0; i--) { BranchLabel currentLabel = labels[i]; - if (currentLabel.position == gotoLocation) { - if (currentLabel.isStandardLabel()) { - label.appendForwardReferencesFrom(currentLabel); - } - /* - Code required to optimized unreachable gotos. - label.position = POS_NOT_SET; - */ - } else { - break; // same target labels should be contiguous + if (currentLabel.position != gotoLocation) break; + if (currentLabel.isStandardLabel()) { + label.appendForwardReferencesFrom(currentLabel); + chaining |= STANDARD; + } else { // case label + chaining |= CASE; } } + return (chaining & (STANDARD|CASE)) == STANDARD; // check was some standards, and no case } public void init(ClassFile targetClassFile) { this.classFile = targetClassFile; @@ -3622,6 +3608,7 @@ } System.arraycopy(noLabels, 0, labels, 0, length); countLabels = 0; + this.lastAbruptCompletion = -1; stackMax = 0; stackDepth = 0; @@ -4493,6 +4480,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 +5266,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 +5887,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 --- 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 13 Jun 2006 09:25:12 -0000 @@ -907,63 +907,42 @@ super.imul(); this.currentFrame.numberOfStackItems--; } -/* - * 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. - 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; - } - */ - boolean hasStandardLabel = false; + final int NONE = 0, CASE = 1, STANDARD = 2; + int chaining = NONE; + boolean removeFrame = true; for (int i = this.countLabels - 1; i >= 0; i--) { BranchLabel currentLabel = labels[i]; - if (currentLabel.position == gotoLocation) { - if (currentLabel.isStandardLabel()) { - hasStandardLabel = true; - if (currentLabel.forwardReferenceCount == 0 && ((currentLabel.tagBits & BranchLabel.USED) != 0)) { - removeFrame = false; - } - } else if (currentLabel.isCaseLabel()) { + if (currentLabel.position != gotoLocation) break; + if (currentLabel.isStandardLabel()) { + chaining |= STANDARD; + if (currentLabel.forwardReferenceCount == 0 && ((currentLabel.tagBits & BranchLabel.USED) != 0)) { removeFrame = false; } - } else { - break; // same target labels should be contiguous + } else { // case label + removeFrame = false; + chaining |= CASE; } } - if (hasStandardLabel) { + if ((chaining & STANDARD) != 0) { for (int i = this.countLabels - 1; i >= 0; i--) { BranchLabel currentLabel = labels[i]; - if (currentLabel.position == gotoLocation) { - if (currentLabel.isStandardLabel()){ - label.appendForwardReferencesFrom(currentLabel); - // we should remove the frame corresponding to otherLabel position in order to prevent unused stack frame - if (removeFrame) { - currentLabel.tagBits &= ~BranchLabel.USED; - this.removeStackFrameFor(gotoLocation); - } + if (currentLabel.position != gotoLocation) break; + if (currentLabel.isStandardLabel()) { + label.appendForwardReferencesFrom(currentLabel); + // we should remove the frame corresponding to otherLabel position in order to prevent unused stack frame + if (removeFrame) { + currentLabel.tagBits &= ~BranchLabel.USED; + this.removeStackFrameFor(gotoLocation); } - /* - Code required to optimized unreachable gotos. - label.position = POS_NOT_SET; - */ - } else { - break; // same target labels should be contiguous } } } + return (chaining & (STANDARD|CASE)) == STANDARD; // check was some standards, and no case } + public void init(ClassFile targetClassFile) { super.init(targetClassFile); this.framesCounter = 0; Index: compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java,v --- compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java 28 Mar 2006 20:29:56 -0000 1.56 +++ compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java 13 Jun 2006 09:25:09 -0000 @@ -176,7 +176,9 @@ elseInitStateIndex); codeStream.addDefinitelyAssignedVariables(currentScope, elseInitStateIndex); } - if (falseLabel != null) falseLabel.place(); + if (falseLabel != null) { + falseLabel.place(); + } this.elseStatement.generateCode(currentScope, codeStream); } } else if (hasElsePart) { 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 --- 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 13 Jun 2006 09:25:15 -0000 @@ -16,6 +16,7 @@ import org.eclipse.jdt.core.ToolFactory; import org.eclipse.jdt.core.util.ClassFileBytesDisassembler; +import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.core.tests.util.Util; @@ -1405,6 +1406,8 @@ }, ""); String expectedOutput = + " // Method descriptor #15 (Ljava/lang/String;Ljava/lang/String;[LX$IContributionItem;)V\n" + + " // Stack: 3, Locals: 8\n" + " public static void findInsertionPoint(java.lang.String startId, java.lang.String sortId, X.IContributionItem[] items);\n" + " 0 iconst_0\n" + " 1 istore_3 [insertIndex]\n" + @@ -1433,21 +1436,21 @@ " 43 iconst_1\n" + " 44 iadd\n" + " 45 istore 5 [nX]\n" + - " 47 goto 129\n" + + " 47 goto 123\n" + " 50 aload_2 [items]\n" + " 51 iload 5 [nX]\n" + " 53 aaload\n" + " 54 astore 6 [item]\n" + " 56 aload 6 [item]\n" + " 58 invokeinterface X$IContributionItem.isSeparator() : boolean [28] [nargs: 1]\n" + - " 63 ifne 140\n" + + " 63 ifne 134\n" + " 66 aload 6 [item]\n" + " 68 invokeinterface X$IContributionItem.isGroupMarker() : boolean [32] [nargs: 1]\n" + " 73 ifeq 79\n" + - " 76 goto 140\n" + + " 76 goto 134\n" + " 79 aload 6 [item]\n" + " 81 instanceof X$IActionSetContributionItem [35]\n" + - " 84 ifeq 140\n" + + " 84 ifeq 134\n" + " 87 aload_1 [sortId]\n" + " 88 ifnull 117\n" + " 91 aload 6 [item]\n" + @@ -1459,19 +1462,54 @@ " 106 invokevirtual java.lang.String.compareTo(java.lang.String) : int [40]\n" + " 109 iload 4 [compareMetric]\n" + " 111 if_icmpge 117\n" + - " 114 goto 140\n" + + " 114 goto 134\n" + " 117 iload 5 [nX]\n" + " 119 istore_3 [insertIndex]\n" + - " 120 goto 126\n" + - " 123 goto 140\n" + - " 126 iinc 5 1 [nX]\n" + - " 129 iload 5 [nX]\n" + - " 131 aload_2 [items]\n" + - " 132 arraylength\n" + - " 133 if_icmplt 50\n" + - " 136 goto 140\n" + - " 139 astore_3\n" + - " 140 return\n"; + " 120 iinc 5 1 [nX]\n" + + " 123 iload 5 [nX]\n" + + " 125 aload_2 [items]\n" + + " 126 arraylength\n" + + " 127 if_icmplt 50\n" + + " 130 goto 134\n" + + " 133 astore_3\n" + + " 134 return\n" + + " Exception Table:\n" + + " [pc: 0, pc: 38] -> 133 when : java.lang.Exception\n" + + " [pc: 39, pc: 133] -> 133 when : java.lang.Exception\n" + + " Line numbers:\n" + + " [pc: 0, line: 16]\n" + + " [pc: 2, line: 17]\n" + + " [pc: 5, line: 18]\n" + + " [pc: 20, line: 19]\n" + + " [pc: 23, line: 20]\n" + + " [pc: 26, line: 17]\n" + + " [pc: 32, line: 22]\n" + + " [pc: 38, line: 23]\n" + + " [pc: 39, line: 25]\n" + + " [pc: 42, line: 30]\n" + + " [pc: 50, line: 31]\n" + + " [pc: 56, line: 32]\n" + + " [pc: 76, line: 34]\n" + + " [pc: 79, line: 36]\n" + + " [pc: 87, line: 37]\n" + + " [pc: 91, line: 38]\n" + + " [pc: 96, line: 39]\n" + + " [pc: 101, line: 38]\n" + + " [pc: 103, line: 40]\n" + + " [pc: 114, line: 41]\n" + + " [pc: 117, line: 43]\n" + + " [pc: 120, line: 30]\n" + + " [pc: 133, line: 48]\n" + + " [pc: 134, line: 49]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 135] local: startId index: 0 type: java.lang.String\n" + + " [pc: 0, pc: 135] local: sortId index: 1 type: java.lang.String\n" + + " [pc: 0, pc: 135] local: items index: 2 type: X.IContributionItem[]\n" + + " [pc: 2, pc: 133] local: insertIndex index: 3 type: int\n" + + " [pc: 42, pc: 133] local: compareMetric index: 4 type: int\n" + + " [pc: 47, pc: 130] local: nX index: 5 type: int\n" + + " [pc: 56, pc: 120] local: item index: 6 type: X.IContributionItem\n" + + " [pc: 103, pc: 117] local: testId index: 7 type: java.lang.String\n"; try { File f = new File(OUTPUT_DIR + File.separator + "X.class"); @@ -2970,6 +3008,1138 @@ 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 = new CompilerOptions(this.getCompilerOptions()).complianceLevel < ClassFileConstants.JDK1_6 + ? " // 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" + : + " // 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" + + " Stack map table: number of frames 2\n" + + " [pc: 8, same_locals_1_stack_item, stack: {java.lang.Exception}]\n" + + " [pc: 9, same]\n" + + " \n" + + " // Method descriptor #23 ()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" + + " Stack map table: number of frames 3\n" + + " [pc: 7, same]\n" + + " [pc: 9, same_locals_1_stack_item, stack: {java.lang.Exception}]\n" + + " [pc: 10, same]\n" + + " \n" + + " // Method descriptor #25 ()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" + + " Stack map table: number of frames 2\n" + + " [pc: 0, same]\n" + + " [pc: 2, same_locals_1_stack_item, stack: {java.lang.Exception}]\n" + + " \n" + + " // Method descriptor #27 ()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" + + " Stack map table: number of frames 4\n" + + " [pc: 5, append: {int}]\n" + + " [pc: 7, same]\n" + + " [pc: 17, full, stack: {java.lang.Exception}, locals: {X}]\n" + + " [pc: 18, same]\n" + + " \n" + + " // Method descriptor #31 ()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 [32]\n" + + " 26 dup\n" + + " 27 invokespecial java.lang.NullPointerException() [34]\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" + + " Stack map table: number of frames 2\n" + + " [pc: 16, same]\n" + + " [pc: 31, same]\n" + + " \n" + + " // Method descriptor #36 (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" + + " Stack map table: number of frames 4\n" + + " [pc: 28, same]\n" + + " [pc: 29, same]\n" + + " [pc: 32, same]\n" + + " [pc: 37, same]\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 = new CompilerOptions(this.getCompilerOptions()).complianceLevel < ClassFileConstants.JDK1_6 + ? " // 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" + : + " // 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" + + " Stack map table: number of frames 2\n" + + " [pc: 15, same_locals_1_stack_item, stack: {java.lang.Exception}]\n" + + " [pc: 16, same]\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" + + " Stack map table: number of frames 3\n" + + " [pc: 7, same]\n" + + " [pc: 15, same_locals_1_stack_item, stack: {java.lang.Exception}]\n" + + " [pc: 16, same]\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" + + " Stack map table: number of frames 2\n" + + " [pc: 0, same]\n" + + " [pc: 8, same_locals_1_stack_item, stack: {java.lang.Exception}]\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" + + " Stack map table: number of frames 4\n" + + " [pc: 5, append: {int}]\n" + + " [pc: 13, same]\n" + + " [pc: 23, full, stack: {java.lang.Exception}, locals: {X}]\n" + + " [pc: 24, same]\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" + + " Stack map table: number of frames 2\n" + + " [pc: 22, same]\n" + + " [pc: 37, same]\n" + + " \n" + + " // Method descriptor #32 (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" + + " Stack map table: number of frames 4\n" + + " [pc: 28, same]\n" + + " [pc: 36, same]\n" + + " [pc: 39, same]\n" + + " [pc: 44, same]\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 = new CompilerOptions(this.getCompilerOptions()).complianceLevel < ClassFileConstants.JDK1_6 + ? " // 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 11\n" + + " 7 goto 11\n" + + " 10 astore_1\n" + + " 11 return\n" + + " Exception Table:\n" + + " [pc: 0, pc: 7] -> 10 when : java.lang.Exception\n" + + " Line numbers:\n" + + " [pc: 0, line: 5]\n" + + " [pc: 7, line: 6]\n" + + " [pc: 10, line: 8]\n" + + " [pc: 11, line: 10]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 12] 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 11\n" + + " 7 goto 11\n" + + " 10 astore_1\n" + + " 11 return\n" + + " Exception Table:\n" + + " [pc: 0, pc: 7] -> 10 when : java.lang.Exception\n" + + " Line numbers:\n" + + " [pc: 0, line: 13]\n" + + " [pc: 7, line: 14]\n" + + " [pc: 10, line: 16]\n" + + " [pc: 11, line: 18]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 12] local: this index: 0 type: X\n" + + " \n" + + " // Method descriptor #6 ()V\n" + + " // Stack: 1, Locals: 2\n" + + " void foo3();\n" + + " 0 goto 4\n" + + " 3 astore_1\n" + + " 4 return\n" + + " Line numbers:\n" + + " [pc: 0, line: 22]\n" + + " [pc: 3, line: 24]\n" + + " [pc: 4, line: 26]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 5] 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 aload_0 [this]\n" + + " 3 invokevirtual X.bool() : boolean [17]\n" + + " 6 ifne 2\n" + + " 9 goto 13\n" + + " 12 astore_1\n" + + " 13 return\n" + + " Exception Table:\n" + + " [pc: 0, pc: 12] -> 12 when : java.lang.Exception\n" + + " Line numbers:\n" + + " [pc: 0, line: 29]\n" + + " [pc: 12, line: 32]\n" + + " [pc: 13, line: 34]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 14] local: this index: 0 type: X\n" + + " [pc: 2, pc: 9] 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 17\n" + + " 7 aload_0 [this]\n" + + " 8 invokevirtual X.bool() : boolean [17]\n" + + " 11 ifeq 24\n" + + " 14 goto 24\n" + + " 17 aload_0 [this]\n" + + " 18 invokevirtual X.bool() : boolean [17]\n" + + " 21 ifeq 24\n" + + " 24 return\n" + + " Line numbers:\n" + + " [pc: 0, line: 36]\n" + + " [pc: 7, line: 37]\n" + + " [pc: 14, line: 38]\n" + + " [pc: 17, line: 40]\n" + + " [pc: 24, line: 44]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 25] 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" + : + " // 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 11\n" + + " 7 goto 11\n" + + " 10 astore_1\n" + + " 11 return\n" + + " Exception Table:\n" + + " [pc: 0, pc: 7] -> 10 when : java.lang.Exception\n" + + " Line numbers:\n" + + " [pc: 0, line: 5]\n" + + " [pc: 7, line: 6]\n" + + " [pc: 10, line: 8]\n" + + " [pc: 11, line: 10]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 12] local: this index: 0 type: X\n" + + " Stack map table: number of frames 2\n" + + " [pc: 10, same_locals_1_stack_item, stack: {java.lang.Exception}]\n" + + " [pc: 11, same]\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 11\n" + + " 7 goto 11\n" + + " 10 astore_1\n" + + " 11 return\n" + + " Exception Table:\n" + + " [pc: 0, pc: 7] -> 10 when : java.lang.Exception\n" + + " Line numbers:\n" + + " [pc: 0, line: 13]\n" + + " [pc: 7, line: 14]\n" + + " [pc: 10, line: 16]\n" + + " [pc: 11, line: 18]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 12] local: this index: 0 type: X\n" + + " Stack map table: number of frames 3\n" + + " [pc: 7, same]\n" + + " [pc: 10, same_locals_1_stack_item, stack: {java.lang.Exception}]\n" + + " [pc: 11, same]\n" + + " \n" + + " // Method descriptor #6 ()V\n" + + " // Stack: 1, Locals: 2\n" + + " void foo3();\n" + + " 0 goto 4\n" + + " 3 astore_1\n" + + " 4 return\n" + + " Line numbers:\n" + + " [pc: 0, line: 22]\n" + + " [pc: 3, line: 24]\n" + + " [pc: 4, line: 26]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 5] local: this index: 0 type: X\n" + + " Stack map table: number of frames 3\n" + + " [pc: 0, same]\n" + + " [pc: 3, same_locals_1_stack_item, stack: {java.lang.Exception}]\n" + + " [pc: 4, same]\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 aload_0 [this]\n" + + " 3 invokevirtual X.bool() : boolean [17]\n" + + " 6 ifne 2\n" + + " 9 goto 13\n" + + " 12 astore_1\n" + + " 13 return\n" + + " Exception Table:\n" + + " [pc: 0, pc: 12] -> 12 when : java.lang.Exception\n" + + " Line numbers:\n" + + " [pc: 0, line: 29]\n" + + " [pc: 12, line: 32]\n" + + " [pc: 13, line: 34]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 14] local: this index: 0 type: X\n" + + " [pc: 2, pc: 9] local: i index: 1 type: int\n" + + " Stack map table: number of frames 3\n" + + " [pc: 2, append: {int}]\n" + + " [pc: 12, full, stack: {java.lang.Exception}, locals: {X}]\n" + + " [pc: 13, same]\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 17\n" + + " 7 aload_0 [this]\n" + + " 8 invokevirtual X.bool() : boolean [17]\n" + + " 11 ifeq 24\n" + + " 14 goto 24\n" + + " 17 aload_0 [this]\n" + + " 18 invokevirtual X.bool() : boolean [17]\n" + + " 21 ifeq 24\n" + + " 24 return\n" + + " Line numbers:\n" + + " [pc: 0, line: 36]\n" + + " [pc: 7, line: 37]\n" + + " [pc: 14, line: 38]\n" + + " [pc: 17, line: 40]\n" + + " [pc: 24, line: 44]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 25] local: this index: 0 type: X\n" + + " Stack map table: number of frames 2\n" + + " [pc: 17, same]\n" + + " [pc: 24, same]\n" + + " \n" + + " // Method descriptor #29 (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" + + " Stack map table: number of frames 4\n" + + " [pc: 28, same]\n" + + " [pc: 31, same]\n" + + " [pc: 34, same]\n" + + " [pc: 39, same]\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; } Index: src/org/eclipse/jdt/core/tests/compiler/regression/SwitchTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchTest.java,v --- src/org/eclipse/jdt/core/tests/compiler/regression/SwitchTest.java 3 Apr 2006 14:46:13 -0000 1.12 +++ src/org/eclipse/jdt/core/tests/compiler/regression/SwitchTest.java 13 Jun 2006 09:25:13 -0000 @@ -16,6 +16,8 @@ import org.eclipse.jdt.core.ToolFactory; import org.eclipse.jdt.core.tests.util.Util; import org.eclipse.jdt.core.util.ClassFileBytesDisassembler; +import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; +import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import junit.framework.Test; @@ -355,6 +357,226 @@ assertTrue("IOException", false); } } +public void test013() { + this.runConformTest(new String[] { + "X.java", + "public class X {\n" + + "\n" + + " public static void main(String[] args) {\n" + + " X x;\n" + + " Object o = null;\n" + + " for (int i = 0; i < 10; i++) {\n" + + " if (i < 90) {\n" + + " x = new X();\n" + + " if (i > 4) {\n" + + " o = new Object();\n" + + " } else {\n" + + " o = null;\n" + + " }\n" + + " switch (2) {\n" + + " case 0:\n" + + " if (o instanceof String) {\n" + + " System.out.print(\"1\");\n" + + " return;\n" + + " } else {\n" + + " break;\n" + + " }\n" + + " default: {\n" + + " Object diff = o;\n" + + " if (diff != null) {\n" + + " System.out.print(\"2\");\n" + + " }\n" + + " break;\n" + + " }\n" + + " }\n" + + " System.out.print(\"3\"); \n" + + " }\n" + + " }\n" + + " }\n" + + "}\n", + }, + "333332323232323"); + + String expectedOutput = new CompilerOptions(this.getCompilerOptions()).complianceLevel < ClassFileConstants.JDK1_6 + ? " // Method descriptor #15 ([Ljava/lang/String;)V\n" + + " // Stack: 2, Locals: 5\n" + + " public static void main(java.lang.String[] args);\n" + + " 0 aconst_null\n" + + " 1 astore_2 [o]\n" + + " 2 iconst_0\n" + + " 3 istore_3 [i]\n" + + " 4 goto 103\n" + + " 7 iload_3 [i]\n" + + " 8 bipush 90\n" + + " 10 if_icmpge 100\n" + + " 13 new X [1]\n" + + " 16 dup\n" + + " 17 invokespecial X() [16]\n" + + " 20 astore_1 [x]\n" + + " 21 iload_3 [i]\n" + + " 22 iconst_4\n" + + " 23 if_icmple 37\n" + + " 26 new java.lang.Object [3]\n" + + " 29 dup\n" + + " 30 invokespecial java.lang.Object() [8]\n" + + " 33 astore_2 [o]\n" + + " 34 goto 39\n" + + " 37 aconst_null\n" + + " 38 astore_2 [o]\n" + + " 39 iconst_2\n" + + " 40 tableswitch default: 76\n" + + " case 0: 60\n" + + " 60 aload_2 [o]\n" + + " 61 instanceof java.lang.String [17]\n" + + " 64 ifeq 92\n" + + " 67 getstatic java.lang.System.out : java.io.PrintStream [19]\n" + + " 70 ldc [25]\n" + + " 72 invokevirtual java.io.PrintStream.print(java.lang.String) : void [27]\n" + + " 75 return\n" + + " 76 aload_2 [o]\n" + + " 77 astore 4 [diff]\n" + + " 79 aload 4 [diff]\n" + + " 81 ifnull 92\n" + + " 84 getstatic java.lang.System.out : java.io.PrintStream [19]\n" + + " 87 ldc [33]\n" + + " 89 invokevirtual java.io.PrintStream.print(java.lang.String) : void [27]\n" + + " 92 getstatic java.lang.System.out : java.io.PrintStream [19]\n" + + " 95 ldc [35]\n" + + " 97 invokevirtual java.io.PrintStream.print(java.lang.String) : void [27]\n" + + " 100 iinc 3 1 [i]\n" + + " 103 iload_3 [i]\n" + + " 104 bipush 10\n" + + " 106 if_icmplt 7\n" + + " 109 return\n" + + " Line numbers:\n" + + " [pc: 0, line: 5]\n" + + " [pc: 2, line: 6]\n" + + " [pc: 7, line: 7]\n" + + " [pc: 13, line: 8]\n" + + " [pc: 21, line: 9]\n" + + " [pc: 26, line: 10]\n" + + " [pc: 37, line: 12]\n" + + " [pc: 39, line: 14]\n" + + " [pc: 60, line: 16]\n" + + " [pc: 67, line: 17]\n" + + " [pc: 75, line: 18]\n" + + " [pc: 76, line: 23]\n" + + " [pc: 79, line: 24]\n" + + " [pc: 84, line: 25]\n" + + " [pc: 92, line: 30]\n" + + " [pc: 100, line: 6]\n" + + " [pc: 109, line: 33]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 110] local: args index: 0 type: java.lang.String[]\n" + + " [pc: 21, pc: 100] local: x index: 1 type: X\n" + + " [pc: 2, pc: 110] local: o index: 2 type: java.lang.Object\n" + + " [pc: 4, pc: 109] local: i index: 3 type: int\n" + + " [pc: 79, pc: 92] local: diff index: 4 type: java.lang.Object\n" + : + " // Method descriptor #15 ([Ljava/lang/String;)V\n" + + " // Stack: 2, Locals: 5\n" + + " public static void main(java.lang.String[] args);\n" + + " 0 aconst_null\n" + + " 1 astore_2 [o]\n" + + " 2 iconst_0\n" + + " 3 istore_3 [i]\n" + + " 4 goto 103\n" + + " 7 iload_3 [i]\n" + + " 8 bipush 90\n" + + " 10 if_icmpge 100\n" + + " 13 new X [1]\n" + + " 16 dup\n" + + " 17 invokespecial X() [16]\n" + + " 20 astore_1 [x]\n" + + " 21 iload_3 [i]\n" + + " 22 iconst_4\n" + + " 23 if_icmple 37\n" + + " 26 new java.lang.Object [3]\n" + + " 29 dup\n" + + " 30 invokespecial java.lang.Object() [8]\n" + + " 33 astore_2 [o]\n" + + " 34 goto 39\n" + + " 37 aconst_null\n" + + " 38 astore_2 [o]\n" + + " 39 iconst_2\n" + + " 40 tableswitch default: 76\n" + + " case 0: 60\n" + + " 60 aload_2 [o]\n" + + " 61 instanceof java.lang.String [17]\n" + + " 64 ifeq 92\n" + + " 67 getstatic java.lang.System.out : java.io.PrintStream [19]\n" + + " 70 ldc [25]\n" + + " 72 invokevirtual java.io.PrintStream.print(java.lang.String) : void [27]\n" + + " 75 return\n" + + " 76 aload_2 [o]\n" + + " 77 astore 4 [diff]\n" + + " 79 aload 4 [diff]\n" + + " 81 ifnull 92\n" + + " 84 getstatic java.lang.System.out : java.io.PrintStream [19]\n" + + " 87 ldc [33]\n" + + " 89 invokevirtual java.io.PrintStream.print(java.lang.String) : void [27]\n" + + " 92 getstatic java.lang.System.out : java.io.PrintStream [19]\n" + + " 95 ldc [35]\n" + + " 97 invokevirtual java.io.PrintStream.print(java.lang.String) : void [27]\n" + + " 100 iinc 3 1 [i]\n" + + " 103 iload_3 [i]\n" + + " 104 bipush 10\n" + + " 106 if_icmplt 7\n" + + " 109 return\n" + + " Line numbers:\n" + + " [pc: 0, line: 5]\n" + + " [pc: 2, line: 6]\n" + + " [pc: 7, line: 7]\n" + + " [pc: 13, line: 8]\n" + + " [pc: 21, line: 9]\n" + + " [pc: 26, line: 10]\n" + + " [pc: 37, line: 12]\n" + + " [pc: 39, line: 14]\n" + + " [pc: 60, line: 16]\n" + + " [pc: 67, line: 17]\n" + + " [pc: 75, line: 18]\n" + + " [pc: 76, line: 23]\n" + + " [pc: 79, line: 24]\n" + + " [pc: 84, line: 25]\n" + + " [pc: 92, line: 30]\n" + + " [pc: 100, line: 6]\n" + + " [pc: 109, line: 33]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 110] local: args index: 0 type: java.lang.String[]\n" + + " [pc: 21, pc: 100] local: x index: 1 type: X\n" + + " [pc: 2, pc: 110] local: o index: 2 type: java.lang.Object\n" + + " [pc: 4, pc: 109] local: i index: 3 type: int\n" + + " [pc: 79, pc: 92] local: diff index: 4 type: java.lang.Object\n" + + " Stack map table: number of frames 8\n" + + " [pc: 7, full, stack: {}, locals: {java.lang.String[], _, java.lang.Object, int}]\n" + + " [pc: 37, full, stack: {}, locals: {java.lang.String[], X, java.lang.Object, int}]\n" + + " [pc: 39, same]\n" + + " [pc: 60, same]\n" + + " [pc: 76, same]\n" + + " [pc: 92, same]\n" + + " [pc: 100, full, stack: {}, locals: {java.lang.String[], _, java.lang.Object, int}]\n" + + " [pc: 103, same]\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) { + e.printStackTrace(); + assertTrue("ClassFormatException", false); + } catch (IOException e) { + e.printStackTrace(); + assertTrue("IOException", false); + } +} public static Class testClass() { return SwitchTest.class; }