### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core.tests.compiler Index: src/org/eclipse/jdt/core/tests/compiler/regression/BooleanTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BooleanTest.java,v retrieving revision 1.5 diff -u -r1.5 BooleanTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/BooleanTest.java 23 Feb 2005 02:52:37 -0000 1.5 +++ src/org/eclipse/jdt/core/tests/compiler/regression/BooleanTest.java 24 Nov 2005 14:04:01 -0000 @@ -10,6 +10,13 @@ *******************************************************************************/ package org.eclipse.jdt.core.tests.compiler.regression; +import java.io.File; +import java.io.IOException; + +import org.eclipse.jdt.core.ToolFactory; +import org.eclipse.jdt.core.tests.util.Util; +import org.eclipse.jdt.core.util.ClassFileBytesDisassembler; + import junit.framework.Test; import junit.framework.TestSuite; @@ -414,6 +421,802 @@ }, "SUCCESS"); } +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=117120 +public void test018() { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public static float f0;\n" + + " \n" + + " public static void main(String[] args)\n" + + " {\n" + + " long l11 = -26;\n" + + " \n" + + " System.out.println(\n" + + " (((l11 < f0++) || true) != ((true && true) && (!(false || true)))));\n" + + " }\n" + + "}\n", + }, + "true"); + // ensure optimized boolean codegen sequence + String expectedOutput = + " // Method descriptor #17 ([Ljava/lang/String;)V\n" + + " // Stack: 3, Locals: 3\n" + + " public static void main(java.lang.String[] args);\n" + + " 0 ldc2_w [18]\n" + + " 3 lstore_1 [l11]\n" + + " 4 getstatic java.lang.System.out : java.io.PrintStream [20]\n" + + " 7 getstatic X.f0 : float [26]\n" + + " 10 fconst_1\n" + + " 11 fadd\n" + + " 12 putstatic X.f0 : float [26]\n" + + " 15 iconst_1\n" + + " 16 invokevirtual java.io.PrintStream.println(boolean) : void [28]\n" + + " 19 return\n" + + " Line numbers:\n" + + " [pc: 0, line: 6]\n" + + " [pc: 4, line: 8]\n" + + " [pc: 7, line: 9]\n" + + " [pc: 16, line: 8]\n" + + " [pc: 19, line: 10]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 20] local: args index: 0 type: java.lang.String[]\n" + + " [pc: 4, pc: 20] local: l11 index: 1 type: long\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=117120 - variation +public void test019() { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public static float f0;\n" + + " \n" + + " public static void main(String[] args)\n" + + " {\n" + + " long l11 = -26;\n" + + " \n" + + " System.out.println(\n" + + " (((l11 < f0++) || false) != true));\n" + + " }\n" + + "}\n", + }, + "false"); + // ensure optimized boolean codegen sequence + String expectedOutput = + " // Method descriptor #17 ([Ljava/lang/String;)V\n" + + " // Stack: 5, Locals: 3\n" + + " public static void main(java.lang.String[] args);\n" + + " 0 ldc2_w [18]\n" + + " 3 lstore_1 [l11]\n" + + " 4 getstatic java.lang.System.out : java.io.PrintStream [20]\n" + + " 7 lload_1 [l11]\n" + + " 8 l2f\n" + + " 9 getstatic X.f0 : float [26]\n" + + " 12 dup\n" + + " 13 fconst_1\n" + + " 14 fadd\n" + + " 15 putstatic X.f0 : float [26]\n" + + " 18 fcmpg\n" + + " 19 ifge 26\n" + + " 22 iconst_0\n" + + " 23 goto 27\n" + + " 26 iconst_1\n" + + " 27 invokevirtual java.io.PrintStream.println(boolean) : void [28]\n" + + " 30 return\n" + + " Line numbers:\n" + + " [pc: 0, line: 6]\n" + + " [pc: 4, line: 8]\n" + + " [pc: 7, line: 9]\n" + + " [pc: 27, line: 8]\n" + + " [pc: 30, line: 10]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 31] local: args index: 0 type: java.lang.String[]\n" + + " [pc: 4, pc: 31] local: l11 index: 1 type: long\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=117120 - variation +public void test020() { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public static float f0;\n" + + " \n" + + " public static void main(String[] args)\n" + + " {\n" + + " long l11 = -26;\n" + + " \n" + + " System.out.println(\n" + + " (((l11 < f0) | true) != false));\n" + + " }\n" + + "}\n", + }, + "true"); + // ensure optimized boolean codegen sequence + String expectedOutput = + " // Method descriptor #17 ([Ljava/lang/String;)V\n" + + " // Stack: 2, Locals: 3\n" + + " public static void main(java.lang.String[] args);\n" + + " 0 ldc2_w [18]\n" + + " 3 lstore_1 [l11]\n" + + " 4 getstatic java.lang.System.out : java.io.PrintStream [20]\n" + + " 7 iconst_1\n" + + " 8 invokevirtual java.io.PrintStream.println(boolean) : void [26]\n" + + " 11 return\n" + + " Line numbers:\n" + + " [pc: 0, line: 6]\n" + + " [pc: 4, line: 8]\n" + + " [pc: 7, line: 9]\n" + + " [pc: 8, line: 8]\n" + + " [pc: 11, line: 10]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 12] local: args index: 0 type: java.lang.String[]\n" + + " [pc: 4, pc: 12] local: l11 index: 1 type: long\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=117120 - variation +public void test021() { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public static float f0;\n" + + " \n" + + " public static void main(String[] args)\n" + + " {\n" + + " long l11 = -26;\n" + + " \n" + + " System.out.println(\n" + + " (((l11 < f0) && false) != true));\n" + + " }\n" + + "}\n", + }, + "true"); + // ensure optimized boolean codegen sequence + String expectedOutput = + " // Method descriptor #17 ([Ljava/lang/String;)V\n" + + " // Stack: 2, Locals: 3\n" + + " public static void main(java.lang.String[] args);\n" + + " 0 ldc2_w [18]\n" + + " 3 lstore_1 [l11]\n" + + " 4 getstatic java.lang.System.out : java.io.PrintStream [20]\n" + + " 7 iconst_1\n" + + " 8 invokevirtual java.io.PrintStream.println(boolean) : void [26]\n" + + " 11 return\n" + + " Line numbers:\n" + + " [pc: 0, line: 6]\n" + + " [pc: 4, line: 8]\n" + + " [pc: 7, line: 9]\n" + + " [pc: 8, line: 8]\n" + + " [pc: 11, line: 10]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 12] local: args index: 0 type: java.lang.String[]\n" + + " [pc: 4, pc: 12] local: l11 index: 1 type: long\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=117120 - variation +public void test022() { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public static float f0;\n" + + " \n" + + " public static void main(String[] args)\n" + + " {\n" + + " long l11 = -26;\n" + + " \n" + + " System.out.println(\n" + + " (((l11 < f0) & false) != true));\n" + + " }\n" + + "}\n", + }, + "true"); + // ensure optimized boolean codegen sequence + String expectedOutput = + " // Method descriptor #17 ([Ljava/lang/String;)V\n" + + " // Stack: 2, Locals: 3\n" + + " public static void main(java.lang.String[] args);\n" + + " 0 ldc2_w [18]\n" + + " 3 lstore_1 [l11]\n" + + " 4 getstatic java.lang.System.out : java.io.PrintStream [20]\n" + + " 7 iconst_1\n" + + " 8 invokevirtual java.io.PrintStream.println(boolean) : void [26]\n" + + " 11 return\n" + + " Line numbers:\n" + + " [pc: 0, line: 6]\n" + + " [pc: 4, line: 8]\n" + + " [pc: 7, line: 9]\n" + + " [pc: 8, line: 8]\n" + + " [pc: 11, line: 10]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 12] local: args index: 0 type: java.lang.String[]\n" + + " [pc: 4, pc: 12] local: l11 index: 1 type: long\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=117120 +public void test023() { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public static float f0;\n" + + " \n" + + " public static void main(String[] args)\n" + + " {\n" + + " long l11 = -26;\n" + + " \n" + + " System.out.println(\n" + + " (((l11 < f0++) || true) == ((true && true) && (!(false || true)))));\n" + + " }\n" + + "}\n", + }, + "false"); + // ensure optimized boolean codegen sequence + String expectedOutput = + " // Method descriptor #17 ([Ljava/lang/String;)V\n" + + " // Stack: 3, Locals: 3\n" + + " public static void main(java.lang.String[] args);\n" + + " 0 ldc2_w [18]\n" + + " 3 lstore_1 [l11]\n" + + " 4 getstatic java.lang.System.out : java.io.PrintStream [20]\n" + + " 7 getstatic X.f0 : float [26]\n" + + " 10 fconst_1\n" + + " 11 fadd\n" + + " 12 putstatic X.f0 : float [26]\n" + + " 15 iconst_0\n" + + " 16 invokevirtual java.io.PrintStream.println(boolean) : void [28]\n" + + " 19 return\n" + + " Line numbers:\n" + + " [pc: 0, line: 6]\n" + + " [pc: 4, line: 8]\n" + + " [pc: 7, line: 9]\n" + + " [pc: 16, line: 8]\n" + + " [pc: 19, line: 10]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 20] local: args index: 0 type: java.lang.String[]\n" + + " [pc: 4, pc: 20] local: l11 index: 1 type: long\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=117120 - variation +public void test024() { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public static float f0;\n" + + " \n" + + " public static void main(String[] args)\n" + + " {\n" + + " long l11 = -26;\n" + + " \n" + + " System.out.println(\n" + + " (((l11 < f0++) || false) == true));\n" + + " }\n" + + "}\n", + }, + "true"); + // ensure optimized boolean codegen sequence + String expectedOutput = + " // Method descriptor #17 ([Ljava/lang/String;)V\n" + + " // Stack: 5, Locals: 3\n" + + " public static void main(java.lang.String[] args);\n" + + " 0 ldc2_w [18]\n" + + " 3 lstore_1 [l11]\n" + + " 4 getstatic java.lang.System.out : java.io.PrintStream [20]\n" + + " 7 lload_1 [l11]\n" + + " 8 l2f\n" + + " 9 getstatic X.f0 : float [26]\n" + + " 12 dup\n" + + " 13 fconst_1\n" + + " 14 fadd\n" + + " 15 putstatic X.f0 : float [26]\n" + + " 18 fcmpg\n" + + " 19 ifge 26\n" + + " 22 iconst_1\n" + + " 23 goto 27\n" + + " 26 iconst_0\n" + + " 27 invokevirtual java.io.PrintStream.println(boolean) : void [28]\n" + + " 30 return\n" + + " Line numbers:\n" + + " [pc: 0, line: 6]\n" + + " [pc: 4, line: 8]\n" + + " [pc: 7, line: 9]\n" + + " [pc: 27, line: 8]\n" + + " [pc: 30, line: 10]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 31] local: args index: 0 type: java.lang.String[]\n" + + " [pc: 4, pc: 31] local: l11 index: 1 type: long\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=117120 - variation +public void test025() { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public static float f0;\n" + + " \n" + + " public static void main(String[] args)\n" + + " {\n" + + " long l11 = -26;\n" + + " \n" + + " System.out.println(\n" + + " (((l11 < f0) | true) == false));\n" + + " }\n" + + "}\n", + }, + "false"); + // ensure optimized boolean codegen sequence + String expectedOutput = + " // Method descriptor #17 ([Ljava/lang/String;)V\n" + + " // Stack: 2, Locals: 3\n" + + " public static void main(java.lang.String[] args);\n" + + " 0 ldc2_w [18]\n" + + " 3 lstore_1 [l11]\n" + + " 4 getstatic java.lang.System.out : java.io.PrintStream [20]\n" + + " 7 iconst_0\n" + + " 8 invokevirtual java.io.PrintStream.println(boolean) : void [26]\n" + + " 11 return\n" + + " Line numbers:\n" + + " [pc: 0, line: 6]\n" + + " [pc: 4, line: 8]\n" + + " [pc: 7, line: 9]\n" + + " [pc: 8, line: 8]\n" + + " [pc: 11, line: 10]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 12] local: args index: 0 type: java.lang.String[]\n" + + " [pc: 4, pc: 12] local: l11 index: 1 type: long\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=117120 - variation +public void test026() { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public static float f0;\n" + + " \n" + + " public static void main(String[] args)\n" + + " {\n" + + " long l11 = -26;\n" + + " \n" + + " System.out.println(\n" + + " (((l11 < f0) && false) == true));\n" + + " }\n" + + "}\n", + }, + "false"); + // ensure optimized boolean codegen sequence + String expectedOutput = + " // Method descriptor #17 ([Ljava/lang/String;)V\n" + + " // Stack: 2, Locals: 3\n" + + " public static void main(java.lang.String[] args);\n" + + " 0 ldc2_w [18]\n" + + " 3 lstore_1 [l11]\n" + + " 4 getstatic java.lang.System.out : java.io.PrintStream [20]\n" + + " 7 iconst_0\n" + + " 8 invokevirtual java.io.PrintStream.println(boolean) : void [26]\n" + + " 11 return\n" + + " Line numbers:\n" + + " [pc: 0, line: 6]\n" + + " [pc: 4, line: 8]\n" + + " [pc: 7, line: 9]\n" + + " [pc: 8, line: 8]\n" + + " [pc: 11, line: 10]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 12] local: args index: 0 type: java.lang.String[]\n" + + " [pc: 4, pc: 12] local: l11 index: 1 type: long\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=117120 - variation +public void test027() { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public static float f0;\n" + + " \n" + + " public static void main(String[] args)\n" + + " {\n" + + " long l11 = -26;\n" + + " \n" + + " System.out.println(\n" + + " (((l11 < f0) & false) == true));\n" + + " }\n" + + "}\n", + }, + "false"); + // ensure optimized boolean codegen sequence + String expectedOutput = + " // Method descriptor #17 ([Ljava/lang/String;)V\n" + + " // Stack: 2, Locals: 3\n" + + " public static void main(java.lang.String[] args);\n" + + " 0 ldc2_w [18]\n" + + " 3 lstore_1 [l11]\n" + + " 4 getstatic java.lang.System.out : java.io.PrintStream [20]\n" + + " 7 iconst_0\n" + + " 8 invokevirtual java.io.PrintStream.println(boolean) : void [26]\n" + + " 11 return\n" + + " Line numbers:\n" + + " [pc: 0, line: 6]\n" + + " [pc: 4, line: 8]\n" + + " [pc: 7, line: 9]\n" + + " [pc: 8, line: 8]\n" + + " [pc: 11, line: 10]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 12] local: args index: 0 type: java.lang.String[]\n" + + " [pc: 4, pc: 12] local: l11 index: 1 type: long\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=117120 - variation +public void test028() { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public static float f0;\n" + + " \n" + + " public static void main(String[] args)\n" + + " {\n" + + " long l11 = -26;\n" + + " \n" + + " System.out.println(\n" + + " (((l11 < f0) || true) == false));\n" + + " }\n" + + "}\n", + }, + "false"); + // ensure optimized boolean codegen sequence + String expectedOutput = + " // Method descriptor #17 ([Ljava/lang/String;)V\n" + + " // Stack: 2, Locals: 3\n" + + " public static void main(java.lang.String[] args);\n" + + " 0 ldc2_w [18]\n" + + " 3 lstore_1 [l11]\n" + + " 4 getstatic java.lang.System.out : java.io.PrintStream [20]\n" + + " 7 iconst_0\n" + + " 8 invokevirtual java.io.PrintStream.println(boolean) : void [26]\n" + + " 11 return\n" + + " Line numbers:\n" + + " [pc: 0, line: 6]\n" + + " [pc: 4, line: 8]\n" + + " [pc: 7, line: 9]\n" + + " [pc: 8, line: 8]\n" + + " [pc: 11, line: 10]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 12] local: args index: 0 type: java.lang.String[]\n" + + " [pc: 4, pc: 12] local: l11 index: 1 type: long\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=117120 - variation +public void test029() { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public static float f0;\n" + + " \n" + + " public static void main(String[] args)\n" + + " {\n" + + " System.out.println(\n" + + " ((foo() || bar()) || true) && false); \n" + + " }\n" + + " static boolean foo(){ \n" + + " System.out.print(\"foo\");\n" + + " return false;\n" + + " }\n" + + " static boolean bar(){\n" + + " System.out.print(\"bar\");\n" + + " return true;\n" + + " }\n" + + "}\n", + }, + "foobarfalse"); + // ensure optimized boolean codegen sequence + String expectedOutput = + " // Method descriptor #17 ([Ljava/lang/String;)V\n" + + " // Stack: 2, Locals: 1\n" + + " public static void main(java.lang.String[] args);\n" + + " 0 getstatic java.lang.System.out : java.io.PrintStream [18]\n" + + " 3 invokestatic X.foo() : boolean [24]\n" + + " 6 ifne 13\n" + + " 9 invokestatic X.bar() : boolean [28]\n" + + " 12 pop\n" + + " 13 iconst_0\n" + + " 14 invokevirtual java.io.PrintStream.println(boolean) : void [31]\n" + + " 17 return\n" + + " Line numbers:\n" + + " [pc: 0, line: 6]\n" + + " [pc: 3, line: 7]\n" + + " [pc: 14, line: 6]\n" + + " [pc: 17, line: 8]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 18] local: args index: 0 type: java.lang.String[]\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=117120 - variation +public void test030() { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public static float f0;\n" + + " \n" + + " public static void main(String[] args)\n" + + " {\n" + + " long l11 = -26;\n" + + " \n" + + " System.out.println(\n" + + " (((l11 < f0++) || true) == ((foo() || bar()) || true)));\n" + + " }\n" + + " static boolean foo() {\n" + + " System.out.print(\"foo\");\n" + + " return false;\n" + + " }\n" + + " static boolean bar() {\n" + + " System.out.print(\"bar\");\n" + + " return true;\n" + + " }\n" + + "}\n", + }, + "foobartrue"); + // ensure optimized boolean codegen sequence + String expectedOutput = + " // Method descriptor #17 ([Ljava/lang/String;)V\n" + + " // Stack: 3, Locals: 3\n" + + " public static void main(java.lang.String[] args);\n" + + " 0 ldc2_w [18]\n" + + " 3 lstore_1 [l11]\n" + + " 4 getstatic java.lang.System.out : java.io.PrintStream [20]\n" + + " 7 getstatic X.f0 : float [26]\n" + + " 10 fconst_1\n" + + " 11 fadd\n" + + " 12 putstatic X.f0 : float [26]\n" + + " 15 invokestatic X.foo() : boolean [28]\n" + + " 18 ifne 25\n" + + " 21 invokestatic X.bar() : boolean [32]\n" + + " 24 pop\n" + + " 25 iconst_1\n" + + " 26 invokevirtual java.io.PrintStream.println(boolean) : void [35]\n" + + " 29 return\n" + + " Line numbers:\n" + + " [pc: 0, line: 6]\n" + + " [pc: 4, line: 8]\n" + + " [pc: 7, line: 9]\n" + + " [pc: 26, line: 8]\n" + + " [pc: 29, line: 10]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 30] local: args index: 0 type: java.lang.String[]\n" + + " [pc: 4, pc: 30] local: l11 index: 1 type: long\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 BooleanTest.class; } #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/ast/BinaryExpression.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BinaryExpression.java,v retrieving revision 1.52 diff -u -r1.52 BinaryExpression.java --- compiler/org/eclipse/jdt/internal/compiler/ast/BinaryExpression.java 18 Nov 2005 16:46:21 -0000 1.52 +++ compiler/org/eclipse/jdt/internal/compiler/ast/BinaryExpression.java 24 Nov 2005 14:04:04 -0000 @@ -86,14 +86,12 @@ boolean valueRequired) { int pc = codeStream.position; - Label falseLabel, endLabel; if (constant != Constant.NotAConstant) { if (valueRequired) codeStream.generateConstant(constant, implicitConversion); codeStream.recordPositionsFrom(pc, this.sourceStart); return; } - bits |= OnlyValueRequired; switch ((bits & OperatorMASK) >> OperatorSHIFT) { case PLUS : switch (bits & ReturnTypeIDMASK) { @@ -295,33 +293,8 @@ } break; case T_boolean : // logical and - generateOptimizedLogicalAnd( - currentScope, - codeStream, - null, - (falseLabel = new Label(codeStream)), - valueRequired); - /* improving code gen for such a case: boolean b = i < 0 && false; - * since the label has never been used, we have the inlined value on the stack. */ - if (falseLabel.hasForwardReferences()) { - if (valueRequired) { - codeStream.iconst_1(); - if ((bits & IsReturnedValue) != 0) { - codeStream.generateImplicitConversion(this.implicitConversion); - codeStream.generateReturnBytecode(this); - falseLabel.place(); - codeStream.iconst_0(); - } else { - codeStream.goto_(endLabel = new Label(codeStream)); - codeStream.decrStackSize(1); - falseLabel.place(); - codeStream.iconst_0(); - endLabel.place(); - } - } else { - falseLabel.place(); - } - } + generateLogicalAnd(currentScope, codeStream, valueRequired); + break; } break; case OR : @@ -367,33 +340,8 @@ } break; case T_boolean : // logical or - generateOptimizedLogicalOr( - currentScope, - codeStream, - null, - (falseLabel = new Label(codeStream)), - valueRequired); - /* improving code gen for such a case: boolean b = i < 0 || true; - * since the label has never been used, we have the inlined value on the stack. */ - if (falseLabel.hasForwardReferences()) { - if (valueRequired) { - codeStream.iconst_1(); - if ((bits & IsReturnedValue) != 0) { - codeStream.generateImplicitConversion(this.implicitConversion); - codeStream.generateReturnBytecode(this); - falseLabel.place(); - codeStream.iconst_0(); - } else { - codeStream.goto_(endLabel = new Label(codeStream)); - codeStream.decrStackSize(1); - falseLabel.place(); - codeStream.iconst_0(); - endLabel.place(); - } - } else { - falseLabel.place(); - } - } + generateLogicalOr(currentScope, codeStream, valueRequired); + break; } break; case XOR : @@ -439,33 +387,8 @@ } break; case T_boolean : - generateOptimizedLogicalXor( - currentScope, - codeStream, - null, - (falseLabel = new Label(codeStream)), - valueRequired); - /* improving code gen for such a case: boolean b = i < 0 ^ bool; - * since the label has never been used, we have the inlined value on the stack. */ - if (falseLabel.hasForwardReferences()) { - if (valueRequired) { - codeStream.iconst_1(); - if ((bits & IsReturnedValue) != 0) { - codeStream.generateImplicitConversion(this.implicitConversion); - codeStream.generateReturnBytecode(this); - falseLabel.place(); - codeStream.iconst_0(); - } else { - codeStream.goto_(endLabel = new Label(codeStream)); - codeStream.decrStackSize(1); - falseLabel.place(); - codeStream.iconst_0(); - endLabel.place(); - } - } else { - falseLabel.place(); - } - } + generateLogicalXor(currentScope, codeStream, valueRequired); + break; } break; case LEFT_SHIFT : @@ -514,6 +437,7 @@ } break; case GREATER : + Label falseLabel, endLabel; generateOptimizedGreaterThan( currentScope, codeStream, @@ -1152,6 +1076,167 @@ /** * Boolean generation for & */ + public void generateLogicalAnd( + BlockScope currentScope, + CodeStream codeStream, + boolean valueRequired) { + + Constant condConst; + if ((left.implicitConversion & COMPILE_TYPE_MASK) == T_boolean) { + if ((condConst = left.optimizedBooleanConstant()) != Constant.NotAConstant) { + if (condConst.booleanValue() == true) { + // & x + left.generateCode(currentScope, codeStream, false); + right.generateCode(currentScope, codeStream, valueRequired); + } else { + // & x + left.generateCode(currentScope, codeStream, false); + right.generateCode(currentScope, codeStream, false); + if (valueRequired) { + codeStream.iconst_0(); + } + // reposition the endPC + codeStream.updateLastRecordedEndPC(currentScope, codeStream.position); + } + return; + } + if ((condConst = right.optimizedBooleanConstant()) != Constant.NotAConstant) { + if (condConst.booleanValue() == true) { + // x & + left.generateCode(currentScope, codeStream, valueRequired); + right.generateCode(currentScope, codeStream, false); + } else { + // x & + left.generateCode(currentScope, codeStream, false); + right.generateCode(currentScope, codeStream, false); + if (valueRequired) { + codeStream.iconst_0(); + } + // reposition the endPC + codeStream.updateLastRecordedEndPC(currentScope, codeStream.position); + } + return; + } + } + // default case + left.generateCode(currentScope, codeStream, valueRequired); + right.generateCode(currentScope, codeStream, valueRequired); + if (valueRequired) { + codeStream.iand(); + } + // reposition the endPC + codeStream.updateLastRecordedEndPC(currentScope, codeStream.position); + } + + /** + * Boolean generation for | + */ + public void generateLogicalOr(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { + + Constant condConst; + if ((left.implicitConversion & COMPILE_TYPE_MASK) == T_boolean) { + if ((condConst = left.optimizedBooleanConstant()) != Constant.NotAConstant) { + if (condConst.booleanValue() == true) { + // | x + left.generateCode(currentScope, codeStream, false); + right.generateCode(currentScope, codeStream, false); + if (valueRequired) { + codeStream.iconst_1(); + } + // reposition the endPC + codeStream.updateLastRecordedEndPC(currentScope, codeStream.position); + } else { + // | x + left.generateCode(currentScope, codeStream, false); + right.generateCode(currentScope, codeStream, valueRequired); + } + return; + } + if ((condConst = right.optimizedBooleanConstant()) != Constant.NotAConstant) { + if (condConst.booleanValue() == true) { + // x | + left.generateCode(currentScope, codeStream, false); + right.generateCode(currentScope, codeStream, false); + if (valueRequired) { + codeStream.iconst_1(); + } + // reposition the endPC + codeStream.updateLastRecordedEndPC(currentScope, codeStream.position); + } else { + // x | + left.generateCode(currentScope, codeStream, valueRequired); + right.generateCode(currentScope, codeStream, false); + } + return; + } + } + // default case + left.generateCode(currentScope, codeStream, valueRequired); + right.generateCode(currentScope, codeStream, valueRequired); + if (valueRequired) { + codeStream.ior(); + } + // reposition the endPC + codeStream.updateLastRecordedEndPC(currentScope, codeStream.position); + } + + /** + * Boolean generation for ^ + */ + public void generateLogicalXor(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { + + Constant condConst; + if ((left.implicitConversion & COMPILE_TYPE_MASK) == T_boolean) { + if ((condConst = left.optimizedBooleanConstant()) != Constant.NotAConstant) { + if (condConst.booleanValue() == true) { + // ^ x + left.generateCode(currentScope, codeStream, false); + if (valueRequired) { + codeStream.iconst_1(); + } + right.generateCode(currentScope, codeStream, valueRequired); + if (valueRequired) { + codeStream.ixor(); // negate + codeStream.updateLastRecordedEndPC(currentScope, codeStream.position); + } + } else { + // ^ x + left.generateCode(currentScope, codeStream, false); + right.generateCode(currentScope, codeStream, valueRequired); + } + return; + } + if ((condConst = right.optimizedBooleanConstant()) != Constant.NotAConstant) { + if (condConst.booleanValue() == true) { + // x ^ + left.generateCode(currentScope, codeStream, valueRequired); + right.generateCode(currentScope, codeStream, false); + if (valueRequired) { + codeStream.iconst_1(); + codeStream.ixor(); // negate + codeStream.updateLastRecordedEndPC(currentScope, codeStream.position); + } + } else { + // x ^ + left.generateCode(currentScope, codeStream, valueRequired); + right.generateCode(currentScope, codeStream, false); + } + return; + } + } + // default case + left.generateCode(currentScope, codeStream, valueRequired); + right.generateCode(currentScope, codeStream, valueRequired); + if (valueRequired) { + codeStream.ixor(); + } + // reposition the endPC + codeStream.updateLastRecordedEndPC(currentScope, codeStream.position); + } + + /** + * Boolean generation for & + */ public void generateOptimizedLogicalAnd( BlockScope currentScope, CodeStream codeStream, @@ -1170,16 +1255,12 @@ trueLabel, falseLabel, false); - if ((bits & OnlyValueRequired) != 0) { - right.generateCode(currentScope, codeStream, valueRequired); - } else { - right.generateOptimizedBoolean( - currentScope, - codeStream, - trueLabel, - falseLabel, - valueRequired); - } + right.generateOptimizedBoolean( + currentScope, + codeStream, + trueLabel, + falseLabel, + valueRequired); } else { // & x left.generateOptimizedBoolean( @@ -1188,22 +1269,16 @@ trueLabel, falseLabel, false); - Label internalTrueLabel = new Label(codeStream); right.generateOptimizedBoolean( currentScope, codeStream, trueLabel, falseLabel, false); - internalTrueLabel.place(); if (valueRequired) { - if ((bits & OnlyValueRequired) != 0) { - codeStream.iconst_0(); - } else { - if (falseLabel != null) { - // implicit falling through the TRUE case - codeStream.goto_(falseLabel); - } + if (falseLabel != null) { + // implicit falling through the TRUE case + codeStream.goto_(falseLabel); } } // reposition the endPC @@ -1214,16 +1289,12 @@ if ((condConst = right.optimizedBooleanConstant()) != Constant.NotAConstant) { if (condConst.booleanValue() == true) { // x & - if ((bits & OnlyValueRequired) != 0) { - left.generateCode(currentScope, codeStream, valueRequired); - } else { - left.generateOptimizedBoolean( - currentScope, - codeStream, - trueLabel, - falseLabel, - valueRequired); - } + left.generateOptimizedBoolean( + currentScope, + codeStream, + trueLabel, + falseLabel, + valueRequired); right.generateOptimizedBoolean( currentScope, codeStream, @@ -1247,13 +1318,9 @@ falseLabel, false); if (valueRequired) { - if ((bits & OnlyValueRequired) != 0) { - codeStream.iconst_0(); - } else { - if (falseLabel != null) { - // implicit falling through the TRUE case - codeStream.goto_(falseLabel); - } + if (falseLabel != null) { + // implicit falling through the TRUE case + codeStream.goto_(falseLabel); } } // reposition the endPC @@ -1267,19 +1334,17 @@ right.generateCode(currentScope, codeStream, valueRequired); if (valueRequired) { codeStream.iand(); - if ((bits & OnlyValueRequired) == 0) { - if (falseLabel == null) { - if (trueLabel != null) { - // implicit falling through the FALSE case - codeStream.ifne(trueLabel); - } + if (falseLabel == null) { + if (trueLabel != null) { + // implicit falling through the FALSE case + codeStream.ifne(trueLabel); + } + } else { + // implicit falling through the TRUE case + if (trueLabel == null) { + codeStream.ifeq(falseLabel); } else { - // implicit falling through the TRUE case - if (trueLabel == null) { - codeStream.ifeq(falseLabel); - } else { - // no implicit fall through TRUE/FALSE --> should never occur - } + // no implicit fall through TRUE/FALSE --> should never occur } } } @@ -1317,12 +1382,8 @@ false); internalFalseLabel.place(); if (valueRequired) { - if ((bits & OnlyValueRequired) != 0) { - codeStream.iconst_1(); - } else { - if (trueLabel != null) { - codeStream.goto_(trueLabel); - } + if (trueLabel != null) { + codeStream.goto_(trueLabel); } } // reposition the endPC @@ -1335,16 +1396,12 @@ trueLabel, falseLabel, false); - if ((bits & OnlyValueRequired) != 0) { - right.generateCode(currentScope, codeStream, valueRequired); - } else { - right.generateOptimizedBoolean( - currentScope, - codeStream, - trueLabel, - falseLabel, - valueRequired); - } + right.generateOptimizedBoolean( + currentScope, + codeStream, + trueLabel, + falseLabel, + valueRequired); } return; } @@ -1366,28 +1423,20 @@ falseLabel, false); if (valueRequired) { - if ((bits & OnlyValueRequired) != 0) { - codeStream.iconst_1(); - } else { - if (trueLabel != null) { - codeStream.goto_(trueLabel); - } + if (trueLabel != null) { + codeStream.goto_(trueLabel); } } // reposition the endPC codeStream.updateLastRecordedEndPC(currentScope, codeStream.position); } else { // x | - if ((bits & OnlyValueRequired) != 0) { - left.generateCode(currentScope, codeStream, valueRequired); - } else { - left.generateOptimizedBoolean( - currentScope, - codeStream, - trueLabel, - falseLabel, - valueRequired); - } + left.generateOptimizedBoolean( + currentScope, + codeStream, + trueLabel, + falseLabel, + valueRequired); right.generateOptimizedBoolean( currentScope, codeStream, @@ -1403,19 +1452,17 @@ right.generateCode(currentScope, codeStream, valueRequired); if (valueRequired) { codeStream.ior(); - if ((bits & OnlyValueRequired) == 0) { - if (falseLabel == null) { - if (trueLabel != null) { - // implicit falling through the FALSE case - codeStream.ifne(trueLabel); - } + if (falseLabel == null) { + if (trueLabel != null) { + // implicit falling through the FALSE case + codeStream.ifne(trueLabel); + } + } else { + // implicit falling through the TRUE case + if (trueLabel == null) { + codeStream.ifeq(falseLabel); } else { - // implicit falling through the TRUE case - if (trueLabel == null) { - codeStream.ifeq(falseLabel); - } else { - // no implicit fall through TRUE/FALSE --> should never occur - } + // no implicit fall through TRUE/FALSE --> should never occur } } } @@ -1447,7 +1494,7 @@ right.generateOptimizedBoolean( currentScope, codeStream, - falseLabel, + falseLabel, // negating trueLabel, valueRequired); } else { @@ -1458,16 +1505,12 @@ trueLabel, falseLabel, false); - if ((bits & OnlyValueRequired) != 0) { - right.generateCode(currentScope, codeStream, valueRequired); - } else { - right.generateOptimizedBoolean( - currentScope, - codeStream, - trueLabel, - falseLabel, - valueRequired); - } + right.generateOptimizedBoolean( + currentScope, + codeStream, + trueLabel, + falseLabel, + valueRequired); } return; } @@ -1477,7 +1520,7 @@ left.generateOptimizedBoolean( currentScope, codeStream, - falseLabel, + falseLabel, // negating trueLabel, valueRequired); right.generateOptimizedBoolean( @@ -1488,16 +1531,12 @@ false); } else { // x ^ - if ((bits & OnlyValueRequired) != 0) { - left.generateCode(currentScope, codeStream, valueRequired); - } else { - left.generateOptimizedBoolean( - currentScope, - codeStream, - trueLabel, - falseLabel, - valueRequired); - } + left.generateOptimizedBoolean( + currentScope, + codeStream, + trueLabel, + falseLabel, + valueRequired); right.generateOptimizedBoolean( currentScope, codeStream, @@ -1513,19 +1552,17 @@ right.generateCode(currentScope, codeStream, valueRequired); if (valueRequired) { codeStream.ixor(); - if ((bits & OnlyValueRequired) == 0) { - if (falseLabel == null) { - if (trueLabel != null) { - // implicit falling through the FALSE case - codeStream.ifne(trueLabel); - } + if (falseLabel == null) { + if (trueLabel != null) { + // implicit falling through the FALSE case + codeStream.ifne(trueLabel); + } + } else { + // implicit falling through the TRUE case + if (trueLabel == null) { + codeStream.ifeq(falseLabel); } else { - // implicit falling through the TRUE case - if (trueLabel == null) { - codeStream.ifeq(falseLabel); - } else { - // no implicit fall through TRUE/FALSE --> should never occur - } + // no implicit fall through TRUE/FALSE --> should never occur } } } Index: compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java,v retrieving revision 1.57 diff -u -r1.57 EqualExpression.java --- compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java 18 Nov 2005 16:46:22 -0000 1.57 +++ compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java 24 Nov 2005 14:04:05 -0000 @@ -126,45 +126,23 @@ */ public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { + int pc = codeStream.position; if (constant != Constant.NotAConstant) { - int pc = codeStream.position; if (valueRequired) codeStream.generateConstant(constant, implicitConversion); codeStream.recordPositionsFrom(pc, this.sourceStart); return; } - Label falseLabel; - bits |= OnlyValueRequired; - generateOptimizedBoolean( - currentScope, - codeStream, - null, - falseLabel = new Label(codeStream), - valueRequired); - if (falseLabel.hasForwardReferences()) { - if (valueRequired){ - // comparison is TRUE - codeStream.iconst_1(); - if ((bits & IsReturnedValue) != 0){ - codeStream.generateImplicitConversion(this.implicitConversion); - codeStream.generateReturnBytecode(this); - // comparison is FALSE - falseLabel.place(); - codeStream.iconst_0(); - } else { - Label endLabel = new Label(codeStream); - codeStream.goto_(endLabel); - codeStream.decrStackSize(1); - // comparison is FALSE - falseLabel.place(); - codeStream.iconst_0(); - endLabel.place(); - } - codeStream.generateImplicitConversion(implicitConversion); - } else { - falseLabel.place(); - } + + if ((left.implicitConversion & COMPILE_TYPE_MASK) /*compile-time*/ == T_boolean) { + generateBooleanEqual(currentScope, codeStream, valueRequired); + } else { + generateNonBooleanEqual(currentScope, codeStream, valueRequired); } + if (valueRequired) { + codeStream.generateImplicitConversion(implicitConversion); + } + codeStream.recordPositionsFrom(pc, this.sourceStart); } /** * Boolean operator code generation @@ -190,6 +168,150 @@ } } } + + /** + * Boolean generation for == with boolean operands + * + * Note this code does not optimize conditional constants !!!! + */ + public void generateBooleanEqual(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { + + // optimized cases: == x, == x, + // optimized cases: != x, != x, + Constant cst = left.optimizedBooleanConstant(); + if (cst != Constant.NotAConstant) { + Constant rightCst = right.optimizedBooleanConstant(); + if (rightCst != Constant.NotAConstant) { + // == , != + // == , != + left.generateCode(currentScope, codeStream, false); + right.generateCode(currentScope, codeStream, false); + if (valueRequired) { + boolean leftBool = cst.booleanValue(); + boolean rightBool = rightCst.booleanValue(); + if (((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) { + if (leftBool == rightBool) { + codeStream.iconst_1(); + } else { + codeStream.iconst_0(); + } + } else { + if (leftBool != rightBool) { + codeStream.iconst_1(); + } else { + codeStream.iconst_0(); + } + } + } + } else if (cst.booleanValue() == (((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL)) { + // == x, != x + left.generateCode(currentScope, codeStream, false); + right.generateCode(currentScope, codeStream, valueRequired); + } else { + // == x, != x + if (valueRequired) { + Label falseLabel = new Label(codeStream); + left.generateCode(currentScope, codeStream, false); + right.generateOptimizedBoolean(currentScope, codeStream, null, falseLabel, valueRequired); + // comparison is TRUE + codeStream.iconst_0(); + if ((bits & IsReturnedValue) != 0){ + codeStream.generateImplicitConversion(this.implicitConversion); + codeStream.generateReturnBytecode(this); + // comparison is FALSE + falseLabel.place(); + codeStream.iconst_1(); + } else { + Label endLabel = new Label(codeStream); + codeStream.goto_(endLabel); + codeStream.decrStackSize(1); + // comparison is FALSE + falseLabel.place(); + codeStream.iconst_1(); + endLabel.place(); + } + } else { + left.generateCode(currentScope, codeStream, false); + right.generateCode(currentScope, codeStream, false); + } +// left.generateCode(currentScope, codeStream, false); +// right.generateCode(currentScope, codeStream, valueRequired); +// if (valueRequired) { +// codeStream.iconst_1(); +// codeStream.ixor(); // negate +// } + } + return; + } + cst = right.optimizedBooleanConstant(); + if (cst != Constant.NotAConstant) { + if (cst.booleanValue() == (((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL)) { + // x == , x != + left.generateCode(currentScope, codeStream, valueRequired); + right.generateCode(currentScope, codeStream, false); + } else { + // x == , x != + if (valueRequired) { + Label falseLabel = new Label(codeStream); + left.generateOptimizedBoolean(currentScope, codeStream, null, falseLabel, valueRequired); + right.generateCode(currentScope, codeStream, false); + // comparison is TRUE + codeStream.iconst_0(); + if ((bits & IsReturnedValue) != 0){ + codeStream.generateImplicitConversion(this.implicitConversion); + codeStream.generateReturnBytecode(this); + // comparison is FALSE + falseLabel.place(); + codeStream.iconst_1(); + } else { + Label endLabel = new Label(codeStream); + codeStream.goto_(endLabel); + codeStream.decrStackSize(1); + // comparison is FALSE + falseLabel.place(); + codeStream.iconst_1(); + endLabel.place(); + } + } else { + left.generateCode(currentScope, codeStream, false); + right.generateCode(currentScope, codeStream, false); + } +// left.generateCode(currentScope, codeStream, valueRequired); +// right.generateCode(currentScope, codeStream, false); +// if (valueRequired) { +// codeStream.iconst_1(); +// codeStream.ixor(); // negate +// } + } + return; + } + // default case + left.generateCode(currentScope, codeStream, valueRequired); + right.generateCode(currentScope, codeStream, valueRequired); + + if (valueRequired) { + Label falseLabel; + codeStream.if_icmpne(falseLabel = new Label(codeStream)); + // comparison is TRUE + codeStream.iconst_1(); + if ((bits & IsReturnedValue) != 0){ + codeStream.generateImplicitConversion(this.implicitConversion); + codeStream.generateReturnBytecode(this); + // comparison is FALSE + falseLabel.place(); + codeStream.iconst_0(); + } else { + Label endLabel = new Label(codeStream); + codeStream.goto_(endLabel); + codeStream.decrStackSize(1); + // comparison is FALSE + falseLabel.place(); + codeStream.iconst_0(); + endLabel.place(); + } + } + } + /** * Boolean generation for == with boolean operands * @@ -233,6 +355,192 @@ * Boolean generation for == with non-boolean operands * */ + public void generateNonBooleanEqual(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { + + if (((left.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) == T_int) { + Constant cst; + if ((cst = left.constant) != Constant.NotAConstant && cst.intValue() == 0) { + // optimized case: 0 == x, 0 != x + right.generateCode(currentScope, codeStream, valueRequired); + if (valueRequired) { + Label falseLabel = new Label(codeStream); + if (((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) { + codeStream.ifne(falseLabel); + } else { + codeStream.ifeq(falseLabel); + } + // comparison is TRUE + codeStream.iconst_1(); + if ((bits & IsReturnedValue) != 0){ + codeStream.generateImplicitConversion(this.implicitConversion); + codeStream.generateReturnBytecode(this); + // comparison is FALSE + falseLabel.place(); + codeStream.iconst_0(); + } else { + Label endLabel = new Label(codeStream); + codeStream.goto_(endLabel); + codeStream.decrStackSize(1); + // comparison is FALSE + falseLabel.place(); + codeStream.iconst_0(); + endLabel.place(); + } + } + return; + } + if ((cst = right.constant) != Constant.NotAConstant && cst.intValue() == 0) { + // optimized case: x == 0, x != 0 + left.generateCode(currentScope, codeStream, valueRequired); + if (valueRequired) { + Label falseLabel = new Label(codeStream); + if (((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) { + codeStream.ifne(falseLabel); + } else { + codeStream.ifeq(falseLabel); + } + // comparison is TRUE + codeStream.iconst_1(); + if ((bits & IsReturnedValue) != 0){ + codeStream.generateImplicitConversion(this.implicitConversion); + codeStream.generateReturnBytecode(this); + // comparison is FALSE + falseLabel.place(); + codeStream.iconst_0(); + } else { + Label endLabel = new Label(codeStream); + codeStream.goto_(endLabel); + codeStream.decrStackSize(1); + // comparison is FALSE + falseLabel.place(); + codeStream.iconst_0(); + endLabel.place(); + } + } + return; + } + } + + // null cases + if (right instanceof NullLiteral) { + if (left instanceof NullLiteral) { + // null == null, null != null + if (valueRequired) { + if (((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) { + codeStream.iconst_1(); + } else { + codeStream.iconst_0(); + } + } + } else { + // x == null, x != null + left.generateCode(currentScope, codeStream, valueRequired); + if (valueRequired) { + Label falseLabel = new Label(codeStream); + if (((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) { + codeStream.ifnonnull(falseLabel); + } else { + codeStream.ifnull(falseLabel); + } + // comparison is TRUE + codeStream.iconst_1(); + if ((bits & IsReturnedValue) != 0){ + codeStream.generateImplicitConversion(this.implicitConversion); + codeStream.generateReturnBytecode(this); + // comparison is FALSE + falseLabel.place(); + codeStream.iconst_0(); + } else { + Label endLabel = new Label(codeStream); + codeStream.goto_(endLabel); + codeStream.decrStackSize(1); + // comparison is FALSE + falseLabel.place(); + codeStream.iconst_0(); + endLabel.place(); + } + } + } + return; + } else if (left instanceof NullLiteral) { + // null = x, null != x + right.generateCode(currentScope, codeStream, valueRequired); + if (valueRequired) { + Label falseLabel = new Label(codeStream); + if (((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) { + codeStream.ifnonnull(falseLabel); + } else { + codeStream.ifnull(falseLabel); + } + // comparison is TRUE + codeStream.iconst_1(); + if ((bits & IsReturnedValue) != 0){ + codeStream.generateImplicitConversion(this.implicitConversion); + codeStream.generateReturnBytecode(this); + // comparison is FALSE + falseLabel.place(); + codeStream.iconst_0(); + } else { + Label endLabel = new Label(codeStream); + codeStream.goto_(endLabel); + codeStream.decrStackSize(1); + // comparison is FALSE + falseLabel.place(); + codeStream.iconst_0(); + endLabel.place(); + } + } + return; + } + + // default case + left.generateCode(currentScope, codeStream, valueRequired); + right.generateCode(currentScope, codeStream, valueRequired); + if (valueRequired) { + Label falseLabel = new Label(codeStream); + switch ((left.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) { // operand runtime type + case T_int : + codeStream.if_icmpne(falseLabel); + break; + case T_float : + codeStream.fcmpl(); + codeStream.ifne(falseLabel); + break; + case T_long : + codeStream.lcmp(); + codeStream.ifne(falseLabel); + break; + case T_double : + codeStream.dcmpl(); + codeStream.ifne(falseLabel); + break; + default : + codeStream.if_acmpne(falseLabel); + } + // comparison is TRUE + codeStream.iconst_1(); + if ((bits & IsReturnedValue) != 0){ + codeStream.generateImplicitConversion(this.implicitConversion); + codeStream.generateReturnBytecode(this); + // comparison is FALSE + falseLabel.place(); + codeStream.iconst_0(); + } else { + Label endLabel = new Label(codeStream); + codeStream.goto_(endLabel); + codeStream.decrStackSize(1); + // comparison is FALSE + falseLabel.place(); + codeStream.iconst_0(); + endLabel.place(); + } + } + } + + /** + * Boolean generation for == with non-boolean operands + * + */ public void generateOptimizedNonBooleanEqual(BlockScope currentScope, CodeStream codeStream, Label trueLabel, Label falseLabel, boolean valueRequired) { int pc = codeStream.position; @@ -290,19 +598,11 @@ if (left instanceof NullLiteral) { // null == null if (valueRequired) { - if ((bits & OnlyValueRequired) != 0) { - if (((bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) { - codeStream.iconst_1(); - } else { - codeStream.iconst_0(); - } - } else { - if (falseLabel == null) { - // implicit falling through the FALSE case - if (trueLabel != null) { - codeStream.goto_(trueLabel); - } - } + if (falseLabel == null) { + // implicit falling through the FALSE case + if (trueLabel != null) { + codeStream.goto_(trueLabel); + } } } } else { Index: compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java,v retrieving revision 1.53 diff -u -r1.53 ASTNode.java --- compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java 18 Nov 2005 16:46:23 -0000 1.53 +++ compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java 24 Nov 2005 14:04:03 -0000 @@ -25,7 +25,7 @@ public final static int Bit3 = 0x4; // return type (operator) | name reference kind (name ref) | implicit this (this ref) public final static int Bit4 = 0x8; // return type (operator) | first assignment to local (local decl) | undocumented empty block (block, type and method decl) public final static int Bit5 = 0x10; // value for return (expression) | has all method bodies (unit) | supertype ref (type ref) - public final static int Bit6 = 0x20; // depth (name ref, msg) | only value required (binary expression) | ignore need cast check (cast expression) + public final static int Bit6 = 0x20; // depth (name ref, msg) | ignore need cast check (cast expression) public final static int Bit7 = 0x40; // depth (name ref, msg) | operator (operator) | need runtime checkcast (cast expression) | label used (labelStatement) public final static int Bit8 = 0x80; // depth (name ref, msg) | operator (operator) | unsafe cast (cast expression) public final static int Bit9 = 0x100; // depth (name ref, msg) | operator (operator) | is local type (type decl) @@ -88,7 +88,6 @@ // for binary expressions public static final int IsReturnedValue = Bit5; - public static final int OnlyValueRequired = Bit6; // for cast expressions public static final int UnnecessaryCast = Bit15; Index: compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java,v retrieving revision 1.80 diff -u -r1.80 SingleNameReference.java --- compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java 18 Nov 2005 16:46:21 -0000 1.80 +++ compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java 24 Nov 2005 14:04:05 -0000 @@ -342,7 +342,7 @@ codeStream.generateConstant(fieldConstant, implicitConversion); } } else { - if (valueRequired || currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) { + if (valueRequired) { boolean isStatic = fieldBinding.isStatic(); if (!isStatic) { if ((bits & DepthMASK) != 0) {