View | Details | Raw Unified | Return to bug 117120
Collapse All | Expand All

(-)src/org/eclipse/jdt/core/tests/compiler/regression/BooleanTest.java (+803 lines)
Lines 10-15 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.jdt.core.tests.compiler.regression;
11
package org.eclipse.jdt.core.tests.compiler.regression;
12
12
13
import java.io.File;
14
import java.io.IOException;
15
16
import org.eclipse.jdt.core.ToolFactory;
17
import org.eclipse.jdt.core.tests.util.Util;
18
import org.eclipse.jdt.core.util.ClassFileBytesDisassembler;
19
13
import junit.framework.Test;
20
import junit.framework.Test;
14
import junit.framework.TestSuite;
21
import junit.framework.TestSuite;
15
22
Lines 414-419 Link Here
414
		},
421
		},
415
		"SUCCESS");
422
		"SUCCESS");
416
}
423
}
424
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=117120
425
public void test018() {
426
	this.runConformTest(
427
		new String[] {
428
			"X.java",
429
			"public class X {\n" + 
430
			"  public static float f0;\n" + 
431
			"  \n" + 
432
			"  public static void main(String[] args)\n" + 
433
			"  {\n" + 
434
			"    long l11 = -26;\n" + 
435
			"    \n" + 
436
			"    System.out.println(\n" + 
437
			"        (((l11 < f0++) || true) != ((true && true) && (!(false || true)))));\n" + 
438
			"  }\n" + 
439
			"}\n",
440
		},
441
		"true");
442
	// 	ensure optimized boolean codegen sequence
443
	String expectedOutput =
444
		"  // Method descriptor #17 ([Ljava/lang/String;)V\n" + 
445
		"  // Stack: 3, Locals: 3\n" + 
446
		"  public static void main(java.lang.String[] args);\n" + 
447
		"     0  ldc2_w <Long -26> [18]\n" + 
448
		"     3  lstore_1 [l11]\n" + 
449
		"     4  getstatic java.lang.System.out : java.io.PrintStream [20]\n" + 
450
		"     7  getstatic X.f0 : float [26]\n" + 
451
		"    10  fconst_1\n" + 
452
		"    11  fadd\n" + 
453
		"    12  putstatic X.f0 : float [26]\n" + 
454
		"    15  iconst_1\n" + 
455
		"    16  invokevirtual java.io.PrintStream.println(boolean) : void [28]\n" + 
456
		"    19  return\n" + 
457
		"      Line numbers:\n" + 
458
		"        [pc: 0, line: 6]\n" + 
459
		"        [pc: 4, line: 8]\n" + 
460
		"        [pc: 7, line: 9]\n" + 
461
		"        [pc: 16, line: 8]\n" + 
462
		"        [pc: 19, line: 10]\n" + 
463
		"      Local variable table:\n" + 
464
		"        [pc: 0, pc: 20] local: args index: 0 type: java.lang.String[]\n" + 
465
		"        [pc: 4, pc: 20] local: l11 index: 1 type: long\n";
466
	
467
	try {
468
		File f = new File(OUTPUT_DIR + File.separator + "X.class");
469
		byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
470
		ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
471
		String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED);
472
		int index = result.indexOf(expectedOutput);
473
		if (index == -1 || expectedOutput.length() == 0) {
474
			System.out.println(Util.displayString(result, 3));
475
		}
476
		if (index == -1) {
477
			assertEquals("Wrong contents", expectedOutput, result);
478
		}
479
	} catch (org.eclipse.jdt.core.util.ClassFormatException e) {
480
		assertTrue(false);
481
	} catch (IOException e) {
482
		assertTrue(false);
483
	}		
484
}
485
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=117120 - variation
486
public void test019() {
487
	this.runConformTest(
488
		new String[] {
489
			"X.java",
490
			"public class X {\n" + 
491
			"  public static float f0;\n" + 
492
			"  \n" + 
493
			"  public static void main(String[] args)\n" + 
494
			"  {\n" + 
495
			"    long l11 = -26;\n" + 
496
			"    \n" + 
497
			"    System.out.println(\n" + 
498
			"        (((l11 < f0++) || false) != true));\n" + 
499
			"  }\n" + 
500
			"}\n",
501
		},
502
		"false");
503
	// 	ensure optimized boolean codegen sequence
504
	String expectedOutput =
505
		"  // Method descriptor #17 ([Ljava/lang/String;)V\n" + 
506
		"  // Stack: 5, Locals: 3\n" + 
507
		"  public static void main(java.lang.String[] args);\n" + 
508
		"     0  ldc2_w <Long -26> [18]\n" + 
509
		"     3  lstore_1 [l11]\n" + 
510
		"     4  getstatic java.lang.System.out : java.io.PrintStream [20]\n" + 
511
		"     7  lload_1 [l11]\n" + 
512
		"     8  l2f\n" + 
513
		"     9  getstatic X.f0 : float [26]\n" + 
514
		"    12  dup\n" + 
515
		"    13  fconst_1\n" + 
516
		"    14  fadd\n" + 
517
		"    15  putstatic X.f0 : float [26]\n" + 
518
		"    18  fcmpg\n" + 
519
		"    19  ifge 26\n" + 
520
		"    22  iconst_0\n" + 
521
		"    23  goto 27\n" + 
522
		"    26  iconst_1\n" + 
523
		"    27  invokevirtual java.io.PrintStream.println(boolean) : void [28]\n" + 
524
		"    30  return\n" + 
525
		"      Line numbers:\n" + 
526
		"        [pc: 0, line: 6]\n" + 
527
		"        [pc: 4, line: 8]\n" + 
528
		"        [pc: 7, line: 9]\n" + 
529
		"        [pc: 27, line: 8]\n" + 
530
		"        [pc: 30, line: 10]\n" + 
531
		"      Local variable table:\n" + 
532
		"        [pc: 0, pc: 31] local: args index: 0 type: java.lang.String[]\n" + 
533
		"        [pc: 4, pc: 31] local: l11 index: 1 type: long\n";
534
	
535
	try {
536
		File f = new File(OUTPUT_DIR + File.separator + "X.class");
537
		byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
538
		ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
539
		String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED);
540
		int index = result.indexOf(expectedOutput);
541
		if (index == -1 || expectedOutput.length() == 0) {
542
			System.out.println(Util.displayString(result, 3));
543
		}
544
		if (index == -1) {
545
			assertEquals("Wrong contents", expectedOutput, result);
546
		}
547
	} catch (org.eclipse.jdt.core.util.ClassFormatException e) {
548
		assertTrue(false);
549
	} catch (IOException e) {
550
		assertTrue(false);
551
	}		
552
}
553
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=117120 - variation
554
public void test020() {
555
	this.runConformTest(
556
		new String[] {
557
			"X.java",
558
			"public class X {\n" + 
559
			"  public static float f0;\n" + 
560
			"  \n" + 
561
			"  public static void main(String[] args)\n" + 
562
			"  {\n" + 
563
			"    long l11 = -26;\n" + 
564
			"    \n" + 
565
			"    System.out.println(\n" + 
566
			"        (((l11 < f0) | true) != false));\n" + 
567
			"  }\n" + 
568
			"}\n",
569
		},
570
		"true");
571
	// 	ensure optimized boolean codegen sequence
572
	String expectedOutput =
573
		"  // Method descriptor #17 ([Ljava/lang/String;)V\n" + 
574
		"  // Stack: 2, Locals: 3\n" + 
575
		"  public static void main(java.lang.String[] args);\n" + 
576
		"     0  ldc2_w <Long -26> [18]\n" + 
577
		"     3  lstore_1 [l11]\n" + 
578
		"     4  getstatic java.lang.System.out : java.io.PrintStream [20]\n" + 
579
		"     7  iconst_1\n" + 
580
		"     8  invokevirtual java.io.PrintStream.println(boolean) : void [26]\n" + 
581
		"    11  return\n" + 
582
		"      Line numbers:\n" + 
583
		"        [pc: 0, line: 6]\n" + 
584
		"        [pc: 4, line: 8]\n" + 
585
		"        [pc: 7, line: 9]\n" + 
586
		"        [pc: 8, line: 8]\n" + 
587
		"        [pc: 11, line: 10]\n" + 
588
		"      Local variable table:\n" + 
589
		"        [pc: 0, pc: 12] local: args index: 0 type: java.lang.String[]\n" + 
590
		"        [pc: 4, pc: 12] local: l11 index: 1 type: long\n";
591
	
592
	try {
593
		File f = new File(OUTPUT_DIR + File.separator + "X.class");
594
		byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
595
		ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
596
		String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED);
597
		int index = result.indexOf(expectedOutput);
598
		if (index == -1 || expectedOutput.length() == 0) {
599
			System.out.println(Util.displayString(result, 3));
600
		}
601
		if (index == -1) {
602
			assertEquals("Wrong contents", expectedOutput, result);
603
		}
604
	} catch (org.eclipse.jdt.core.util.ClassFormatException e) {
605
		assertTrue(false);
606
	} catch (IOException e) {
607
		assertTrue(false);
608
	}		
609
}
610
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=117120 - variation
611
public void test021() {
612
	this.runConformTest(
613
		new String[] {
614
			"X.java",
615
			"public class X {\n" + 
616
			"  public static float f0;\n" + 
617
			"  \n" + 
618
			"  public static void main(String[] args)\n" + 
619
			"  {\n" + 
620
			"    long l11 = -26;\n" + 
621
			"    \n" + 
622
			"    System.out.println(\n" + 
623
			"        (((l11 < f0) && false) != true));\n" + 
624
			"  }\n" + 
625
			"}\n",
626
		},
627
		"true");
628
	// 	ensure optimized boolean codegen sequence
629
	String expectedOutput =
630
		"  // Method descriptor #17 ([Ljava/lang/String;)V\n" + 
631
		"  // Stack: 2, Locals: 3\n" + 
632
		"  public static void main(java.lang.String[] args);\n" + 
633
		"     0  ldc2_w <Long -26> [18]\n" + 
634
		"     3  lstore_1 [l11]\n" + 
635
		"     4  getstatic java.lang.System.out : java.io.PrintStream [20]\n" + 
636
		"     7  iconst_1\n" + 
637
		"     8  invokevirtual java.io.PrintStream.println(boolean) : void [26]\n" + 
638
		"    11  return\n" + 
639
		"      Line numbers:\n" + 
640
		"        [pc: 0, line: 6]\n" + 
641
		"        [pc: 4, line: 8]\n" + 
642
		"        [pc: 7, line: 9]\n" + 
643
		"        [pc: 8, line: 8]\n" + 
644
		"        [pc: 11, line: 10]\n" + 
645
		"      Local variable table:\n" + 
646
		"        [pc: 0, pc: 12] local: args index: 0 type: java.lang.String[]\n" + 
647
		"        [pc: 4, pc: 12] local: l11 index: 1 type: long\n";
648
	
649
	try {
650
		File f = new File(OUTPUT_DIR + File.separator + "X.class");
651
		byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
652
		ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
653
		String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED);
654
		int index = result.indexOf(expectedOutput);
655
		if (index == -1 || expectedOutput.length() == 0) {
656
			System.out.println(Util.displayString(result, 3));
657
		}
658
		if (index == -1) {
659
			assertEquals("Wrong contents", expectedOutput, result);
660
		}
661
	} catch (org.eclipse.jdt.core.util.ClassFormatException e) {
662
		assertTrue(false);
663
	} catch (IOException e) {
664
		assertTrue(false);
665
	}		
666
}
667
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=117120 - variation
668
public void test022() {
669
	this.runConformTest(
670
		new String[] {
671
			"X.java",
672
			"public class X {\n" + 
673
			"  public static float f0;\n" + 
674
			"  \n" + 
675
			"  public static void main(String[] args)\n" + 
676
			"  {\n" + 
677
			"    long l11 = -26;\n" + 
678
			"    \n" + 
679
			"    System.out.println(\n" + 
680
			"        (((l11 < f0) & false) != true));\n" + 
681
			"  }\n" + 
682
			"}\n",
683
		},
684
		"true");
685
	// 	ensure optimized boolean codegen sequence
686
	String expectedOutput =
687
		"  // Method descriptor #17 ([Ljava/lang/String;)V\n" + 
688
		"  // Stack: 2, Locals: 3\n" + 
689
		"  public static void main(java.lang.String[] args);\n" + 
690
		"     0  ldc2_w <Long -26> [18]\n" + 
691
		"     3  lstore_1 [l11]\n" + 
692
		"     4  getstatic java.lang.System.out : java.io.PrintStream [20]\n" + 
693
		"     7  iconst_1\n" + 
694
		"     8  invokevirtual java.io.PrintStream.println(boolean) : void [26]\n" + 
695
		"    11  return\n" + 
696
		"      Line numbers:\n" + 
697
		"        [pc: 0, line: 6]\n" + 
698
		"        [pc: 4, line: 8]\n" + 
699
		"        [pc: 7, line: 9]\n" + 
700
		"        [pc: 8, line: 8]\n" + 
701
		"        [pc: 11, line: 10]\n" + 
702
		"      Local variable table:\n" + 
703
		"        [pc: 0, pc: 12] local: args index: 0 type: java.lang.String[]\n" + 
704
		"        [pc: 4, pc: 12] local: l11 index: 1 type: long\n";
705
	
706
	try {
707
		File f = new File(OUTPUT_DIR + File.separator + "X.class");
708
		byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
709
		ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
710
		String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED);
711
		int index = result.indexOf(expectedOutput);
712
		if (index == -1 || expectedOutput.length() == 0) {
713
			System.out.println(Util.displayString(result, 3));
714
		}
715
		if (index == -1) {
716
			assertEquals("Wrong contents", expectedOutput, result);
717
		}
718
	} catch (org.eclipse.jdt.core.util.ClassFormatException e) {
719
		assertTrue(false);
720
	} catch (IOException e) {
721
		assertTrue(false);
722
	}		
723
}
724
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=117120
725
public void test023() {
726
	this.runConformTest(
727
		new String[] {
728
			"X.java",
729
			"public class X {\n" + 
730
			"  public static float f0;\n" + 
731
			"  \n" + 
732
			"  public static void main(String[] args)\n" + 
733
			"  {\n" + 
734
			"    long l11 = -26;\n" + 
735
			"    \n" + 
736
			"    System.out.println(\n" + 
737
			"        (((l11 < f0++) || true) == ((true && true) && (!(false || true)))));\n" + 
738
			"  }\n" + 
739
			"}\n",
740
		},
741
		"false");
742
	// 	ensure optimized boolean codegen sequence
743
	String expectedOutput =
744
		"  // Method descriptor #17 ([Ljava/lang/String;)V\n" + 
745
		"  // Stack: 3, Locals: 3\n" + 
746
		"  public static void main(java.lang.String[] args);\n" + 
747
		"     0  ldc2_w <Long -26> [18]\n" + 
748
		"     3  lstore_1 [l11]\n" + 
749
		"     4  getstatic java.lang.System.out : java.io.PrintStream [20]\n" + 
750
		"     7  getstatic X.f0 : float [26]\n" + 
751
		"    10  fconst_1\n" + 
752
		"    11  fadd\n" + 
753
		"    12  putstatic X.f0 : float [26]\n" + 
754
		"    15  iconst_0\n" + 
755
		"    16  invokevirtual java.io.PrintStream.println(boolean) : void [28]\n" + 
756
		"    19  return\n" + 
757
		"      Line numbers:\n" + 
758
		"        [pc: 0, line: 6]\n" + 
759
		"        [pc: 4, line: 8]\n" + 
760
		"        [pc: 7, line: 9]\n" + 
761
		"        [pc: 16, line: 8]\n" + 
762
		"        [pc: 19, line: 10]\n" + 
763
		"      Local variable table:\n" + 
764
		"        [pc: 0, pc: 20] local: args index: 0 type: java.lang.String[]\n" + 
765
		"        [pc: 4, pc: 20] local: l11 index: 1 type: long\n";
766
	
767
	try {
768
		File f = new File(OUTPUT_DIR + File.separator + "X.class");
769
		byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
770
		ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
771
		String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED);
772
		int index = result.indexOf(expectedOutput);
773
		if (index == -1 || expectedOutput.length() == 0) {
774
			System.out.println(Util.displayString(result, 3));
775
		}
776
		if (index == -1) {
777
			assertEquals("Wrong contents", expectedOutput, result);
778
		}
779
	} catch (org.eclipse.jdt.core.util.ClassFormatException e) {
780
		assertTrue(false);
781
	} catch (IOException e) {
782
		assertTrue(false);
783
	}		
784
}
785
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=117120 - variation
786
public void test024() {
787
	this.runConformTest(
788
		new String[] {
789
			"X.java",
790
			"public class X {\n" + 
791
			"  public static float f0;\n" + 
792
			"  \n" + 
793
			"  public static void main(String[] args)\n" + 
794
			"  {\n" + 
795
			"    long l11 = -26;\n" + 
796
			"    \n" + 
797
			"    System.out.println(\n" + 
798
			"        (((l11 < f0++) || false) == true));\n" + 
799
			"  }\n" + 
800
			"}\n",
801
		},
802
		"true");
803
	// 	ensure optimized boolean codegen sequence
804
	String expectedOutput =
805
		"  // Method descriptor #17 ([Ljava/lang/String;)V\n" + 
806
		"  // Stack: 5, Locals: 3\n" + 
807
		"  public static void main(java.lang.String[] args);\n" + 
808
		"     0  ldc2_w <Long -26> [18]\n" + 
809
		"     3  lstore_1 [l11]\n" + 
810
		"     4  getstatic java.lang.System.out : java.io.PrintStream [20]\n" + 
811
		"     7  lload_1 [l11]\n" + 
812
		"     8  l2f\n" + 
813
		"     9  getstatic X.f0 : float [26]\n" + 
814
		"    12  dup\n" + 
815
		"    13  fconst_1\n" + 
816
		"    14  fadd\n" + 
817
		"    15  putstatic X.f0 : float [26]\n" + 
818
		"    18  fcmpg\n" + 
819
		"    19  ifge 26\n" + 
820
		"    22  iconst_1\n" + 
821
		"    23  goto 27\n" + 
822
		"    26  iconst_0\n" + 
823
		"    27  invokevirtual java.io.PrintStream.println(boolean) : void [28]\n" + 
824
		"    30  return\n" + 
825
		"      Line numbers:\n" + 
826
		"        [pc: 0, line: 6]\n" + 
827
		"        [pc: 4, line: 8]\n" + 
828
		"        [pc: 7, line: 9]\n" + 
829
		"        [pc: 27, line: 8]\n" + 
830
		"        [pc: 30, line: 10]\n" + 
831
		"      Local variable table:\n" + 
832
		"        [pc: 0, pc: 31] local: args index: 0 type: java.lang.String[]\n" + 
833
		"        [pc: 4, pc: 31] local: l11 index: 1 type: long\n";
834
	
835
	try {
836
		File f = new File(OUTPUT_DIR + File.separator + "X.class");
837
		byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
838
		ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
839
		String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED);
840
		int index = result.indexOf(expectedOutput);
841
		if (index == -1 || expectedOutput.length() == 0) {
842
			System.out.println(Util.displayString(result, 3));
843
		}
844
		if (index == -1) {
845
			assertEquals("Wrong contents", expectedOutput, result);
846
		}
847
	} catch (org.eclipse.jdt.core.util.ClassFormatException e) {
848
		assertTrue(false);
849
	} catch (IOException e) {
850
		assertTrue(false);
851
	}		
852
}
853
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=117120 - variation
854
public void test025() {
855
	this.runConformTest(
856
		new String[] {
857
			"X.java",
858
			"public class X {\n" + 
859
			"  public static float f0;\n" + 
860
			"  \n" + 
861
			"  public static void main(String[] args)\n" + 
862
			"  {\n" + 
863
			"    long l11 = -26;\n" + 
864
			"    \n" + 
865
			"    System.out.println(\n" + 
866
			"        (((l11 < f0) | true) == false));\n" + 
867
			"  }\n" + 
868
			"}\n",
869
		},
870
		"false");
871
	// 	ensure optimized boolean codegen sequence
872
	String expectedOutput =
873
		"  // Method descriptor #17 ([Ljava/lang/String;)V\n" + 
874
		"  // Stack: 2, Locals: 3\n" + 
875
		"  public static void main(java.lang.String[] args);\n" + 
876
		"     0  ldc2_w <Long -26> [18]\n" + 
877
		"     3  lstore_1 [l11]\n" + 
878
		"     4  getstatic java.lang.System.out : java.io.PrintStream [20]\n" + 
879
		"     7  iconst_0\n" + 
880
		"     8  invokevirtual java.io.PrintStream.println(boolean) : void [26]\n" + 
881
		"    11  return\n" + 
882
		"      Line numbers:\n" + 
883
		"        [pc: 0, line: 6]\n" + 
884
		"        [pc: 4, line: 8]\n" + 
885
		"        [pc: 7, line: 9]\n" + 
886
		"        [pc: 8, line: 8]\n" + 
887
		"        [pc: 11, line: 10]\n" + 
888
		"      Local variable table:\n" + 
889
		"        [pc: 0, pc: 12] local: args index: 0 type: java.lang.String[]\n" + 
890
		"        [pc: 4, pc: 12] local: l11 index: 1 type: long\n";
891
	
892
	try {
893
		File f = new File(OUTPUT_DIR + File.separator + "X.class");
894
		byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
895
		ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
896
		String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED);
897
		int index = result.indexOf(expectedOutput);
898
		if (index == -1 || expectedOutput.length() == 0) {
899
			System.out.println(Util.displayString(result, 3));
900
		}
901
		if (index == -1) {
902
			assertEquals("Wrong contents", expectedOutput, result);
903
		}
904
	} catch (org.eclipse.jdt.core.util.ClassFormatException e) {
905
		assertTrue(false);
906
	} catch (IOException e) {
907
		assertTrue(false);
908
	}		
909
}
910
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=117120 - variation
911
public void test026() {
912
	this.runConformTest(
913
		new String[] {
914
			"X.java",
915
			"public class X {\n" + 
916
			"  public static float f0;\n" + 
917
			"  \n" + 
918
			"  public static void main(String[] args)\n" + 
919
			"  {\n" + 
920
			"    long l11 = -26;\n" + 
921
			"    \n" + 
922
			"    System.out.println(\n" + 
923
			"        (((l11 < f0) && false) == true));\n" + 
924
			"  }\n" + 
925
			"}\n",
926
		},
927
		"false");
928
	// 	ensure optimized boolean codegen sequence
929
	String expectedOutput =
930
		"  // Method descriptor #17 ([Ljava/lang/String;)V\n" + 
931
		"  // Stack: 2, Locals: 3\n" + 
932
		"  public static void main(java.lang.String[] args);\n" + 
933
		"     0  ldc2_w <Long -26> [18]\n" + 
934
		"     3  lstore_1 [l11]\n" + 
935
		"     4  getstatic java.lang.System.out : java.io.PrintStream [20]\n" + 
936
		"     7  iconst_0\n" + 
937
		"     8  invokevirtual java.io.PrintStream.println(boolean) : void [26]\n" + 
938
		"    11  return\n" + 
939
		"      Line numbers:\n" + 
940
		"        [pc: 0, line: 6]\n" + 
941
		"        [pc: 4, line: 8]\n" + 
942
		"        [pc: 7, line: 9]\n" + 
943
		"        [pc: 8, line: 8]\n" + 
944
		"        [pc: 11, line: 10]\n" + 
945
		"      Local variable table:\n" + 
946
		"        [pc: 0, pc: 12] local: args index: 0 type: java.lang.String[]\n" + 
947
		"        [pc: 4, pc: 12] local: l11 index: 1 type: long\n" + 
948
		"}";
949
	
950
	try {
951
		File f = new File(OUTPUT_DIR + File.separator + "X.class");
952
		byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
953
		ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
954
		String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED);
955
		int index = result.indexOf(expectedOutput);
956
		if (index == -1 || expectedOutput.length() == 0) {
957
			System.out.println(Util.displayString(result, 3));
958
		}
959
		if (index == -1) {
960
			assertEquals("Wrong contents", expectedOutput, result);
961
		}
962
	} catch (org.eclipse.jdt.core.util.ClassFormatException e) {
963
		assertTrue(false);
964
	} catch (IOException e) {
965
		assertTrue(false);
966
	}		
967
}
968
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=117120 - variation
969
public void test027() {
970
	this.runConformTest(
971
		new String[] {
972
			"X.java",
973
			"public class X {\n" + 
974
			"  public static float f0;\n" + 
975
			"  \n" + 
976
			"  public static void main(String[] args)\n" + 
977
			"  {\n" + 
978
			"    long l11 = -26;\n" + 
979
			"    \n" + 
980
			"    System.out.println(\n" + 
981
			"        (((l11 < f0) & false) == true));\n" + 
982
			"  }\n" + 
983
			"}\n",
984
		},
985
		"false");
986
	// 	ensure optimized boolean codegen sequence
987
	String expectedOutput =
988
		"  // Method descriptor #17 ([Ljava/lang/String;)V\n" + 
989
		"  // Stack: 2, Locals: 3\n" + 
990
		"  public static void main(java.lang.String[] args);\n" + 
991
		"     0  ldc2_w <Long -26> [18]\n" + 
992
		"     3  lstore_1 [l11]\n" + 
993
		"     4  getstatic java.lang.System.out : java.io.PrintStream [20]\n" + 
994
		"     7  iconst_0\n" + 
995
		"     8  invokevirtual java.io.PrintStream.println(boolean) : void [26]\n" + 
996
		"    11  return\n" + 
997
		"      Line numbers:\n" + 
998
		"        [pc: 0, line: 6]\n" + 
999
		"        [pc: 4, line: 8]\n" + 
1000
		"        [pc: 7, line: 9]\n" + 
1001
		"        [pc: 8, line: 8]\n" + 
1002
		"        [pc: 11, line: 10]\n" + 
1003
		"      Local variable table:\n" + 
1004
		"        [pc: 0, pc: 12] local: args index: 0 type: java.lang.String[]\n" + 
1005
		"        [pc: 4, pc: 12] local: l11 index: 1 type: long\n";
1006
	
1007
	try {
1008
		File f = new File(OUTPUT_DIR + File.separator + "X.class");
1009
		byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
1010
		ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
1011
		String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED);
1012
		int index = result.indexOf(expectedOutput);
1013
		if (index == -1 || expectedOutput.length() == 0) {
1014
			System.out.println(Util.displayString(result, 3));
1015
		}
1016
		if (index == -1) {
1017
			assertEquals("Wrong contents", expectedOutput, result);
1018
		}
1019
	} catch (org.eclipse.jdt.core.util.ClassFormatException e) {
1020
		assertTrue(false);
1021
	} catch (IOException e) {
1022
		assertTrue(false);
1023
	}		
1024
}
1025
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=117120 - variation
1026
public void test028() {
1027
	this.runConformTest(
1028
		new String[] {
1029
			"X.java",
1030
			"public class X {\n" + 
1031
			"  public static float f0;\n" + 
1032
			"  \n" + 
1033
			"  public static void main(String[] args)\n" + 
1034
			"  {\n" + 
1035
			"    long l11 = -26;\n" + 
1036
			"    \n" + 
1037
			"    System.out.println(\n" + 
1038
			"        (((l11 < f0) || true) == false));\n" + 
1039
			"  }\n" + 
1040
			"}\n",
1041
		},
1042
		"false");
1043
	// 	ensure optimized boolean codegen sequence
1044
	String expectedOutput =
1045
		"  // Method descriptor #17 ([Ljava/lang/String;)V\n" + 
1046
		"  // Stack: 2, Locals: 3\n" + 
1047
		"  public static void main(java.lang.String[] args);\n" + 
1048
		"     0  ldc2_w <Long -26> [18]\n" + 
1049
		"     3  lstore_1 [l11]\n" + 
1050
		"     4  getstatic java.lang.System.out : java.io.PrintStream [20]\n" + 
1051
		"     7  iconst_0\n" + 
1052
		"     8  invokevirtual java.io.PrintStream.println(boolean) : void [26]\n" + 
1053
		"    11  return\n" + 
1054
		"      Line numbers:\n" + 
1055
		"        [pc: 0, line: 6]\n" + 
1056
		"        [pc: 4, line: 8]\n" + 
1057
		"        [pc: 7, line: 9]\n" + 
1058
		"        [pc: 8, line: 8]\n" + 
1059
		"        [pc: 11, line: 10]\n" + 
1060
		"      Local variable table:\n" + 
1061
		"        [pc: 0, pc: 12] local: args index: 0 type: java.lang.String[]\n" + 
1062
		"        [pc: 4, pc: 12] local: l11 index: 1 type: long\n";
1063
	
1064
	try {
1065
		File f = new File(OUTPUT_DIR + File.separator + "X.class");
1066
		byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
1067
		ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
1068
		String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED);
1069
		int index = result.indexOf(expectedOutput);
1070
		if (index == -1 || expectedOutput.length() == 0) {
1071
			System.out.println(Util.displayString(result, 3));
1072
		}
1073
		if (index == -1) {
1074
			assertEquals("Wrong contents", expectedOutput, result);
1075
		}
1076
	} catch (org.eclipse.jdt.core.util.ClassFormatException e) {
1077
		assertTrue(false);
1078
	} catch (IOException e) {
1079
		assertTrue(false);
1080
	}		
1081
}
1082
1083
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=117120 - variation
1084
public void test029() {
1085
	this.runConformTest(
1086
		new String[] {
1087
			"X.java",
1088
			"public class X {\n" + 
1089
			"  public static float f0;\n" + 
1090
			"  \n" + 
1091
			"  public static void main(String[] args)\n" + 
1092
			"  {\n" + 
1093
			"   	System.out.println(\n" + 
1094
			"   			((foo() || bar()) || true) && false); 		\n" + 
1095
			"  }\n" + 
1096
			"  static boolean foo(){ \n" + 
1097
			"	  System.out.print(\"foo\");\n" + 
1098
			"	  return false;\n" + 
1099
			"  }\n" + 
1100
			"  static boolean bar(){\n" + 
1101
			"	  System.out.print(\"bar\");\n" + 
1102
			"	  return true;\n" + 
1103
			"  }\n" + 
1104
			"}\n",
1105
		},
1106
		"foobarfalse");
1107
	// 	ensure optimized boolean codegen sequence
1108
	String expectedOutput =
1109
		"  // Method descriptor #17 ([Ljava/lang/String;)V\n" + 
1110
		"  // Stack: 2, Locals: 1\n" + 
1111
		"  public static void main(java.lang.String[] args);\n" + 
1112
		"     0  getstatic java.lang.System.out : java.io.PrintStream [18]\n" + 
1113
		"     3  invokestatic X.foo() : boolean [24]\n" + 
1114
		"     6  ifne 13\n" + 
1115
		"     9  invokestatic X.bar() : boolean [28]\n" + 
1116
		"    12  pop\n" + 
1117
		"    13  iconst_0\n" + 
1118
		"    14  invokevirtual java.io.PrintStream.println(boolean) : void [31]\n" + 
1119
		"    17  return\n" + 
1120
		"      Line numbers:\n" + 
1121
		"        [pc: 0, line: 6]\n" + 
1122
		"        [pc: 3, line: 7]\n" + 
1123
		"        [pc: 14, line: 6]\n" + 
1124
		"        [pc: 17, line: 8]\n" + 
1125
		"      Local variable table:\n" + 
1126
		"        [pc: 0, pc: 18] local: args index: 0 type: java.lang.String[]\n";
1127
	
1128
	try {
1129
		File f = new File(OUTPUT_DIR + File.separator + "X.class");
1130
		byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
1131
		ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
1132
		String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED);
1133
		int index = result.indexOf(expectedOutput);
1134
		if (index == -1 || expectedOutput.length() == 0) {
1135
			System.out.println(Util.displayString(result, 3));
1136
		}
1137
		if (index == -1) {
1138
			assertEquals("Wrong contents", expectedOutput, result);
1139
		}
1140
	} catch (org.eclipse.jdt.core.util.ClassFormatException e) {
1141
		assertTrue(false);
1142
	} catch (IOException e) {
1143
		assertTrue(false);
1144
	}		
1145
}
1146
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=117120 - variation
1147
public void test030() {
1148
	this.runConformTest(
1149
		new String[] {
1150
			"X.java",
1151
			"public class X {\n" + 
1152
			"  public static float f0;\n" + 
1153
			"  \n" + 
1154
			"  public static void main(String[] args)\n" + 
1155
			"  {\n" + 
1156
			"    long l11 = -26;\n" + 
1157
			"    \n" + 
1158
			"    System.out.println(\n" + 
1159
			"        (((l11 < f0++) || true) == ((foo() || bar()) || true)));\n" + 
1160
			"  }\n" + 
1161
			"  static boolean foo() {\n" + 
1162
			"	  System.out.print(\"foo\");\n" + 
1163
			"	  return false;\n" + 
1164
			"  }\n" + 
1165
			"  static boolean bar() {\n" + 
1166
			"	  System.out.print(\"bar\");\n" + 
1167
			"	  return true;\n" + 
1168
			"  }\n" + 
1169
			"}\n",
1170
		},
1171
		"foobartrue");
1172
	// 	ensure optimized boolean codegen sequence
1173
	String expectedOutput =
1174
		"  // Method descriptor #17 ([Ljava/lang/String;)V\n" + 
1175
		"  // Stack: 3, Locals: 3\n" + 
1176
		"  public static void main(java.lang.String[] args);\n" + 
1177
		"     0  ldc2_w <Long -26> [18]\n" + 
1178
		"     3  lstore_1 [l11]\n" + 
1179
		"     4  getstatic java.lang.System.out : java.io.PrintStream [20]\n" + 
1180
		"     7  getstatic X.f0 : float [26]\n" + 
1181
		"    10  fconst_1\n" + 
1182
		"    11  fadd\n" + 
1183
		"    12  putstatic X.f0 : float [26]\n" + 
1184
		"    15  invokestatic X.foo() : boolean [28]\n" + 
1185
		"    18  ifne 25\n" + 
1186
		"    21  invokestatic X.bar() : boolean [32]\n" + 
1187
		"    24  pop\n" + 
1188
		"    25  iconst_1\n" + 
1189
		"    26  invokevirtual java.io.PrintStream.println(boolean) : void [35]\n" + 
1190
		"    29  return\n" + 
1191
		"      Line numbers:\n" + 
1192
		"        [pc: 0, line: 6]\n" + 
1193
		"        [pc: 4, line: 8]\n" + 
1194
		"        [pc: 7, line: 9]\n" + 
1195
		"        [pc: 26, line: 8]\n" + 
1196
		"        [pc: 29, line: 10]\n" + 
1197
		"      Local variable table:\n" + 
1198
		"        [pc: 0, pc: 30] local: args index: 0 type: java.lang.String[]\n" + 
1199
		"        [pc: 4, pc: 30] local: l11 index: 1 type: long\n";
1200
	
1201
	try {
1202
		File f = new File(OUTPUT_DIR + File.separator + "X.class");
1203
		byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
1204
		ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
1205
		String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED);
1206
		int index = result.indexOf(expectedOutput);
1207
		if (index == -1 || expectedOutput.length() == 0) {
1208
			System.out.println(Util.displayString(result, 3));
1209
		}
1210
		if (index == -1) {
1211
			assertEquals("Wrong contents", expectedOutput, result);
1212
		}
1213
	} catch (org.eclipse.jdt.core.util.ClassFormatException e) {
1214
		assertTrue(false);
1215
	} catch (IOException e) {
1216
		assertTrue(false);
1217
	}		
1218
}
1219
417
public static Class testClass() {
1220
public static Class testClass() {
418
	return BooleanTest.class;
1221
	return BooleanTest.class;
419
}
1222
}
(-)compiler/org/eclipse/jdt/internal/compiler/ast/BinaryExpression.java (-209 / +246 lines)
Lines 86-99 Link Here
86
		boolean valueRequired) {
86
		boolean valueRequired) {
87
87
88
		int pc = codeStream.position;
88
		int pc = codeStream.position;
89
		Label falseLabel, endLabel;
90
		if (constant != Constant.NotAConstant) {
89
		if (constant != Constant.NotAConstant) {
91
			if (valueRequired)
90
			if (valueRequired)
92
				codeStream.generateConstant(constant, implicitConversion);
91
				codeStream.generateConstant(constant, implicitConversion);
93
			codeStream.recordPositionsFrom(pc, this.sourceStart);
92
			codeStream.recordPositionsFrom(pc, this.sourceStart);
94
			return;
93
			return;
95
		}
94
		}
96
		bits |= OnlyValueRequired;
97
		switch ((bits & OperatorMASK) >> OperatorSHIFT) {
95
		switch ((bits & OperatorMASK) >> OperatorSHIFT) {
98
			case PLUS :
96
			case PLUS :
99
				switch (bits & ReturnTypeIDMASK) {
97
				switch (bits & ReturnTypeIDMASK) {
Lines 295-327 Link Here
295
						}
293
						}
296
						break;
294
						break;
297
					case T_boolean : // logical and
295
					case T_boolean : // logical and
298
						generateOptimizedLogicalAnd(
296
						generateLogicalAnd(currentScope, codeStream, valueRequired);
299
							currentScope,
297
						break;
300
							codeStream,
301
							null,
302
							(falseLabel = new Label(codeStream)),
303
							valueRequired);
304
						/* improving code gen for such a case: boolean b = i < 0 && false;
305
						 * since the label has never been used, we have the inlined value on the stack. */
306
						if (falseLabel.hasForwardReferences()) {
307
							if (valueRequired) {
308
								codeStream.iconst_1();
309
								if ((bits & IsReturnedValue) != 0) {
310
									codeStream.generateImplicitConversion(this.implicitConversion);
311
									codeStream.generateReturnBytecode(this);
312
									falseLabel.place();
313
									codeStream.iconst_0();
314
								} else {
315
									codeStream.goto_(endLabel = new Label(codeStream));
316
									codeStream.decrStackSize(1);
317
									falseLabel.place();
318
									codeStream.iconst_0();
319
									endLabel.place();
320
								}
321
							} else {
322
								falseLabel.place();
323
							}
324
						}
325
				}
298
				}
326
				break;
299
				break;
327
			case OR :
300
			case OR :
Lines 367-399 Link Here
367
						}
340
						}
368
						break;
341
						break;
369
					case T_boolean : // logical or
342
					case T_boolean : // logical or
370
						generateOptimizedLogicalOr(
343
						generateLogicalOr(currentScope, codeStream, valueRequired);
371
							currentScope,
344
						break;
372
							codeStream,
373
							null,
374
							(falseLabel = new Label(codeStream)),
375
							valueRequired);
376
						/* improving code gen for such a case: boolean b = i < 0 || true;
377
						 * since the label has never been used, we have the inlined value on the stack. */
378
						if (falseLabel.hasForwardReferences()) {
379
							if (valueRequired) {
380
								codeStream.iconst_1();
381
								if ((bits & IsReturnedValue) != 0) {
382
									codeStream.generateImplicitConversion(this.implicitConversion);
383
									codeStream.generateReturnBytecode(this);
384
									falseLabel.place();
385
									codeStream.iconst_0();
386
								} else {
387
									codeStream.goto_(endLabel = new Label(codeStream));
388
									codeStream.decrStackSize(1);
389
									falseLabel.place();
390
									codeStream.iconst_0();
391
									endLabel.place();
392
								}
393
							} else {
394
								falseLabel.place();
395
							}
396
						}
397
				}
345
				}
398
				break;
346
				break;
399
			case XOR :
347
			case XOR :
Lines 439-471 Link Here
439
						}
387
						}
440
						break;
388
						break;
441
					case T_boolean :
389
					case T_boolean :
442
						generateOptimizedLogicalXor(
390
						generateLogicalXor(currentScope, 	codeStream, valueRequired);
443
							currentScope,
391
						break;
444
							codeStream,
445
							null,
446
							(falseLabel = new Label(codeStream)),
447
							valueRequired);
448
						/* improving code gen for such a case: boolean b = i < 0 ^ bool;
449
						 * since the label has never been used, we have the inlined value on the stack. */
450
						if (falseLabel.hasForwardReferences()) {
451
							if (valueRequired) {
452
								codeStream.iconst_1();
453
								if ((bits & IsReturnedValue) != 0) {
454
									codeStream.generateImplicitConversion(this.implicitConversion);
455
									codeStream.generateReturnBytecode(this);
456
									falseLabel.place();
457
									codeStream.iconst_0();
458
								} else {
459
									codeStream.goto_(endLabel = new Label(codeStream));
460
									codeStream.decrStackSize(1);
461
									falseLabel.place();
462
									codeStream.iconst_0();
463
									endLabel.place();
464
								}
465
							} else {
466
								falseLabel.place();
467
							}
468
						}
469
				}
392
				}
470
				break;
393
				break;
471
			case LEFT_SHIFT :
394
			case LEFT_SHIFT :
Lines 514-519 Link Here
514
				}
437
				}
515
				break;
438
				break;
516
			case GREATER :
439
			case GREATER :
440
				Label falseLabel, endLabel;
517
				generateOptimizedGreaterThan(
441
				generateOptimizedGreaterThan(
518
					currentScope,
442
					currentScope,
519
					codeStream,
443
					codeStream,
Lines 1152-1157 Link Here
1152
	/**
1076
	/**
1153
	 * Boolean generation for &
1077
	 * Boolean generation for &
1154
	 */
1078
	 */
1079
	public void generateLogicalAnd(
1080
		BlockScope currentScope,
1081
		CodeStream codeStream,
1082
		boolean valueRequired) {
1083
			
1084
		Constant condConst;
1085
		if ((left.implicitConversion & COMPILE_TYPE_MASK) == T_boolean) {
1086
			if ((condConst = left.optimizedBooleanConstant()) != Constant.NotAConstant) {
1087
				if (condConst.booleanValue() == true) {
1088
					// <something equivalent to true> & x
1089
					left.generateCode(currentScope, codeStream, false);
1090
					right.generateCode(currentScope, codeStream, valueRequired);
1091
				} else {
1092
					// <something equivalent to false> & x
1093
					left.generateCode(currentScope, codeStream, false);
1094
					right.generateCode(currentScope, codeStream, false);
1095
					if (valueRequired) {
1096
						codeStream.iconst_0();
1097
					}
1098
					// reposition the endPC
1099
					codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
1100
				}
1101
				return;
1102
			} 
1103
			if ((condConst = right.optimizedBooleanConstant()) != Constant.NotAConstant) {
1104
				if (condConst.booleanValue() == true) {
1105
					// x & <something equivalent to true>
1106
					left.generateCode(currentScope, codeStream, valueRequired);
1107
					right.generateCode(currentScope, codeStream, false);
1108
				} else {
1109
					// x & <something equivalent to false>
1110
					left.generateCode(currentScope, codeStream, false);
1111
					right.generateCode(currentScope, codeStream, false);
1112
					if (valueRequired) {
1113
						codeStream.iconst_0();
1114
					}
1115
					// reposition the endPC
1116
					codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
1117
				}
1118
				return;
1119
			}
1120
		}
1121
		// default case
1122
		left.generateCode(currentScope, codeStream, valueRequired);
1123
		right.generateCode(currentScope, codeStream, valueRequired);
1124
		if (valueRequired) {
1125
			codeStream.iand();
1126
		}
1127
		// reposition the endPC
1128
		codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
1129
	}
1130
	
1131
	/**
1132
	 * Boolean generation for |
1133
	 */
1134
	public void generateLogicalOr(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
1135
			
1136
		Constant condConst;
1137
		if ((left.implicitConversion & COMPILE_TYPE_MASK) == T_boolean) {
1138
			if ((condConst = left.optimizedBooleanConstant()) != Constant.NotAConstant) {
1139
				if (condConst.booleanValue() == true) {
1140
					// <something equivalent to true> | x
1141
					left.generateCode(currentScope, codeStream, false);
1142
					right.generateCode(currentScope, codeStream, false);
1143
					if (valueRequired) {
1144
						codeStream.iconst_1();
1145
					}
1146
					// reposition the endPC
1147
					codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
1148
				} else {
1149
					// <something equivalent to false> | x
1150
					left.generateCode(currentScope, codeStream, false);
1151
					right.generateCode(currentScope, codeStream, valueRequired);
1152
				}
1153
				return;
1154
			}
1155
			if ((condConst = right.optimizedBooleanConstant()) != Constant.NotAConstant) {
1156
				if (condConst.booleanValue() == true) {
1157
					// x | <something equivalent to true>
1158
					left.generateCode(currentScope, codeStream, false);
1159
					right.generateCode(currentScope, codeStream, false);
1160
					if (valueRequired) {
1161
						codeStream.iconst_1();
1162
					}
1163
					// reposition the endPC
1164
					codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
1165
				} else {
1166
					// x | <something equivalent to false>
1167
					left.generateCode(currentScope, codeStream, valueRequired);
1168
					right.generateCode(currentScope, codeStream, false);
1169
				}
1170
				return;
1171
			}
1172
		}
1173
		// default case
1174
		left.generateCode(currentScope, codeStream, valueRequired);
1175
		right.generateCode(currentScope, codeStream, valueRequired);
1176
		if (valueRequired) {
1177
			codeStream.ior();
1178
		}
1179
		// reposition the endPC
1180
		codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
1181
	}
1182
	
1183
	/**
1184
	 * Boolean generation for ^
1185
	 */
1186
	public void generateLogicalXor(BlockScope currentScope,	CodeStream codeStream, boolean valueRequired) {
1187
			
1188
		Constant condConst;
1189
		if ((left.implicitConversion & COMPILE_TYPE_MASK) == T_boolean) {
1190
			if ((condConst = left.optimizedBooleanConstant()) != Constant.NotAConstant) {
1191
				if (condConst.booleanValue() == true) {
1192
					// <something equivalent to true> ^ x
1193
					left.generateCode(currentScope, codeStream, false);
1194
					if (valueRequired) {
1195
						codeStream.iconst_1();
1196
					}
1197
					right.generateCode(currentScope, codeStream, valueRequired);
1198
					if (valueRequired) {
1199
						codeStream.ixor(); // negate
1200
						codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
1201
					}
1202
				} else {
1203
					// <something equivalent to false> ^ x
1204
					left.generateCode(currentScope, codeStream, false);
1205
					right.generateCode(currentScope, codeStream, valueRequired);
1206
				}
1207
				return;
1208
			}
1209
			if ((condConst = right.optimizedBooleanConstant()) != Constant.NotAConstant) {
1210
				if (condConst.booleanValue() == true) {
1211
					// x ^ <something equivalent to true>
1212
					left.generateCode(currentScope, codeStream, valueRequired);
1213
					right.generateCode(currentScope, codeStream, false);
1214
					if (valueRequired) {
1215
						codeStream.iconst_1();
1216
						codeStream.ixor(); // negate
1217
						codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
1218
					}
1219
				} else {
1220
					// x ^ <something equivalent to false>
1221
					left.generateCode(currentScope, codeStream, valueRequired);
1222
					right.generateCode(currentScope, codeStream, false);
1223
				}
1224
				return;
1225
			}
1226
		}
1227
		// default case
1228
		left.generateCode(currentScope, codeStream, valueRequired);
1229
		right.generateCode(currentScope, codeStream, valueRequired);
1230
		if (valueRequired) {
1231
			codeStream.ixor();
1232
		}
1233
		// reposition the endPC
1234
		codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
1235
	}	
1236
	
1237
	/**
1238
	 * Boolean generation for &
1239
	 */
1155
	public void generateOptimizedLogicalAnd(
1240
	public void generateOptimizedLogicalAnd(
1156
		BlockScope currentScope,
1241
		BlockScope currentScope,
1157
		CodeStream codeStream,
1242
		CodeStream codeStream,
Lines 1170-1185 Link Here
1170
						trueLabel,
1255
						trueLabel,
1171
						falseLabel,
1256
						falseLabel,
1172
						false);
1257
						false);
1173
					if ((bits & OnlyValueRequired) != 0) {
1258
					right.generateOptimizedBoolean(
1174
						right.generateCode(currentScope, codeStream, valueRequired);
1259
						currentScope,
1175
					} else {
1260
						codeStream,
1176
						right.generateOptimizedBoolean(
1261
						trueLabel,
1177
							currentScope,
1262
						falseLabel,
1178
							codeStream,
1263
						valueRequired);
1179
							trueLabel,
1180
							falseLabel,
1181
							valueRequired);
1182
					}
1183
				} else {
1264
				} else {
1184
					// <something equivalent to false> & x
1265
					// <something equivalent to false> & x
1185
					left.generateOptimizedBoolean(
1266
					left.generateOptimizedBoolean(
Lines 1188-1209 Link Here
1188
						trueLabel,
1269
						trueLabel,
1189
						falseLabel,
1270
						falseLabel,
1190
						false);
1271
						false);
1191
					Label internalTrueLabel = new Label(codeStream);
1192
					right.generateOptimizedBoolean(
1272
					right.generateOptimizedBoolean(
1193
						currentScope,
1273
						currentScope,
1194
						codeStream,
1274
						codeStream,
1195
						trueLabel,
1275
						trueLabel,
1196
						falseLabel,
1276
						falseLabel,
1197
						false);
1277
						false);
1198
					internalTrueLabel.place();
1199
					if (valueRequired) {
1278
					if (valueRequired) {
1200
						if ((bits & OnlyValueRequired) != 0) {
1279
						if (falseLabel != null) {
1201
							codeStream.iconst_0();
1280
							// implicit falling through the TRUE case
1202
						} else {
1281
							codeStream.goto_(falseLabel);
1203
							if (falseLabel != null) {
1204
								// implicit falling through the TRUE case
1205
								codeStream.goto_(falseLabel);
1206
							}
1207
						}
1282
						}
1208
					}
1283
					}
1209
					// reposition the endPC
1284
					// reposition the endPC
Lines 1214-1229 Link Here
1214
			if ((condConst = right.optimizedBooleanConstant()) != Constant.NotAConstant) {
1289
			if ((condConst = right.optimizedBooleanConstant()) != Constant.NotAConstant) {
1215
				if (condConst.booleanValue() == true) {
1290
				if (condConst.booleanValue() == true) {
1216
					// x & <something equivalent to true>
1291
					// x & <something equivalent to true>
1217
					if ((bits & OnlyValueRequired) != 0) {
1292
					left.generateOptimizedBoolean(
1218
						left.generateCode(currentScope, codeStream, valueRequired);
1293
						currentScope,
1219
					} else {
1294
						codeStream,
1220
						left.generateOptimizedBoolean(
1295
						trueLabel,
1221
							currentScope,
1296
						falseLabel,
1222
							codeStream,
1297
						valueRequired);
1223
							trueLabel,
1224
							falseLabel,
1225
							valueRequired);
1226
					}
1227
					right.generateOptimizedBoolean(
1298
					right.generateOptimizedBoolean(
1228
						currentScope,
1299
						currentScope,
1229
						codeStream,
1300
						codeStream,
Lines 1247-1259 Link Here
1247
						falseLabel,
1318
						falseLabel,
1248
						false);
1319
						false);
1249
					if (valueRequired) {
1320
					if (valueRequired) {
1250
						if ((bits & OnlyValueRequired) != 0) {
1321
						if (falseLabel != null) {
1251
							codeStream.iconst_0();
1322
							// implicit falling through the TRUE case
1252
						} else {
1323
							codeStream.goto_(falseLabel);
1253
							if (falseLabel != null) {
1254
								// implicit falling through the TRUE case
1255
								codeStream.goto_(falseLabel);
1256
							}
1257
						}
1324
						}
1258
					}
1325
					}
1259
					// reposition the endPC
1326
					// reposition the endPC
Lines 1267-1285 Link Here
1267
		right.generateCode(currentScope, codeStream, valueRequired);
1334
		right.generateCode(currentScope, codeStream, valueRequired);
1268
		if (valueRequired) {
1335
		if (valueRequired) {
1269
			codeStream.iand();
1336
			codeStream.iand();
1270
			if ((bits & OnlyValueRequired) == 0) {
1337
			if (falseLabel == null) {
1271
				if (falseLabel == null) {
1338
				if (trueLabel != null) {
1272
					if (trueLabel != null) {
1339
					// implicit falling through the FALSE case
1273
						// implicit falling through the FALSE case
1340
					codeStream.ifne(trueLabel);
1274
						codeStream.ifne(trueLabel);
1341
				}
1275
					}
1342
			} else {
1343
				// implicit falling through the TRUE case
1344
				if (trueLabel == null) {
1345
					codeStream.ifeq(falseLabel);
1276
				} else {
1346
				} else {
1277
					// implicit falling through the TRUE case
1347
					// no implicit fall through TRUE/FALSE --> should never occur
1278
					if (trueLabel == null) {
1279
						codeStream.ifeq(falseLabel);
1280
					} else {
1281
						// no implicit fall through TRUE/FALSE --> should never occur
1282
					}
1283
				}
1348
				}
1284
			}
1349
			}
1285
		}
1350
		}
Lines 1317-1328 Link Here
1317
						false);
1382
						false);
1318
					internalFalseLabel.place();
1383
					internalFalseLabel.place();
1319
					if (valueRequired) {
1384
					if (valueRequired) {
1320
						if ((bits & OnlyValueRequired) != 0) {
1385
						if (trueLabel != null) {
1321
							codeStream.iconst_1();
1386
							codeStream.goto_(trueLabel);
1322
						} else {
1323
							if (trueLabel != null) {
1324
								codeStream.goto_(trueLabel);
1325
							}
1326
						}
1387
						}
1327
					}
1388
					}
1328
					// reposition the endPC
1389
					// reposition the endPC
Lines 1335-1350 Link Here
1335
						trueLabel,
1396
						trueLabel,
1336
						falseLabel,
1397
						falseLabel,
1337
						false);
1398
						false);
1338
					if ((bits & OnlyValueRequired) != 0) {
1399
					right.generateOptimizedBoolean(
1339
						right.generateCode(currentScope, codeStream, valueRequired);
1400
						currentScope,
1340
					} else {
1401
						codeStream,
1341
						right.generateOptimizedBoolean(
1402
						trueLabel,
1342
							currentScope,
1403
						falseLabel,
1343
							codeStream,
1404
						valueRequired);
1344
							trueLabel,
1345
							falseLabel,
1346
							valueRequired);
1347
					}
1348
				}
1405
				}
1349
				return;
1406
				return;
1350
			}
1407
			}
Lines 1366-1393 Link Here
1366
						falseLabel,
1423
						falseLabel,
1367
						false);
1424
						false);
1368
					if (valueRequired) {
1425
					if (valueRequired) {
1369
						if ((bits & OnlyValueRequired) != 0) {
1426
						if (trueLabel != null) {
1370
							codeStream.iconst_1();
1427
							codeStream.goto_(trueLabel);
1371
						} else {
1372
							if (trueLabel != null) {
1373
								codeStream.goto_(trueLabel);
1374
							}
1375
						}
1428
						}
1376
					}
1429
					}
1377
					// reposition the endPC
1430
					// reposition the endPC
1378
					codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
1431
					codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
1379
				} else {
1432
				} else {
1380
					// x | <something equivalent to false>
1433
					// x | <something equivalent to false>
1381
					if ((bits & OnlyValueRequired) != 0) {
1434
					left.generateOptimizedBoolean(
1382
						left.generateCode(currentScope, codeStream, valueRequired);
1435
						currentScope,
1383
					} else {
1436
						codeStream,
1384
						left.generateOptimizedBoolean(
1437
						trueLabel,
1385
							currentScope,
1438
						falseLabel,
1386
							codeStream,
1439
						valueRequired);
1387
							trueLabel,
1388
							falseLabel,
1389
							valueRequired);
1390
					}
1391
					right.generateOptimizedBoolean(
1440
					right.generateOptimizedBoolean(
1392
						currentScope,
1441
						currentScope,
1393
						codeStream,
1442
						codeStream,
Lines 1403-1421 Link Here
1403
		right.generateCode(currentScope, codeStream, valueRequired);
1452
		right.generateCode(currentScope, codeStream, valueRequired);
1404
		if (valueRequired) {
1453
		if (valueRequired) {
1405
			codeStream.ior();
1454
			codeStream.ior();
1406
			if ((bits & OnlyValueRequired) == 0) {
1455
			if (falseLabel == null) {
1407
				if (falseLabel == null) {
1456
				if (trueLabel != null) {
1408
					if (trueLabel != null) {
1457
					// implicit falling through the FALSE case
1409
						// implicit falling through the FALSE case
1458
					codeStream.ifne(trueLabel);
1410
						codeStream.ifne(trueLabel);
1459
				}
1411
					}
1460
			} else {
1461
				// implicit falling through the TRUE case
1462
				if (trueLabel == null) {
1463
					codeStream.ifeq(falseLabel);
1412
				} else {
1464
				} else {
1413
					// implicit falling through the TRUE case
1465
					// no implicit fall through TRUE/FALSE --> should never occur
1414
					if (trueLabel == null) {
1415
						codeStream.ifeq(falseLabel);
1416
					} else {
1417
						// no implicit fall through TRUE/FALSE --> should never occur
1418
					}
1419
				}
1466
				}
1420
			}
1467
			}
1421
		}
1468
		}
Lines 1447-1453 Link Here
1447
					right.generateOptimizedBoolean(
1494
					right.generateOptimizedBoolean(
1448
						currentScope,
1495
						currentScope,
1449
						codeStream,
1496
						codeStream,
1450
						falseLabel,
1497
						falseLabel, // negating
1451
						trueLabel,
1498
						trueLabel,
1452
						valueRequired);
1499
						valueRequired);
1453
				} else {
1500
				} else {
Lines 1458-1473 Link Here
1458
						trueLabel,
1505
						trueLabel,
1459
						falseLabel,
1506
						falseLabel,
1460
						false);
1507
						false);
1461
					if ((bits & OnlyValueRequired) != 0) {
1508
					right.generateOptimizedBoolean(
1462
						right.generateCode(currentScope, codeStream, valueRequired);
1509
						currentScope,
1463
					} else {
1510
						codeStream,
1464
						right.generateOptimizedBoolean(
1511
						trueLabel,
1465
							currentScope,
1512
						falseLabel,
1466
							codeStream,
1513
						valueRequired);
1467
							trueLabel,
1468
							falseLabel,
1469
							valueRequired);
1470
					}
1471
				}
1514
				}
1472
				return;
1515
				return;
1473
			}
1516
			}
Lines 1477-1483 Link Here
1477
					left.generateOptimizedBoolean(
1520
					left.generateOptimizedBoolean(
1478
						currentScope,
1521
						currentScope,
1479
						codeStream,
1522
						codeStream,
1480
						falseLabel,
1523
						falseLabel, // negating
1481
						trueLabel,
1524
						trueLabel,
1482
						valueRequired);
1525
						valueRequired);
1483
					right.generateOptimizedBoolean(
1526
					right.generateOptimizedBoolean(
Lines 1488-1503 Link Here
1488
						false);
1531
						false);
1489
				} else {
1532
				} else {
1490
					// x ^ <something equivalent to false>
1533
					// x ^ <something equivalent to false>
1491
					if ((bits & OnlyValueRequired) != 0) {
1534
					left.generateOptimizedBoolean(
1492
						left.generateCode(currentScope, codeStream, valueRequired);
1535
						currentScope,
1493
					} else {
1536
						codeStream,
1494
						left.generateOptimizedBoolean(
1537
						trueLabel,
1495
							currentScope,
1538
						falseLabel,
1496
							codeStream,
1539
						valueRequired);
1497
							trueLabel,
1498
							falseLabel,
1499
							valueRequired);
1500
					}
1501
					right.generateOptimizedBoolean(
1540
					right.generateOptimizedBoolean(
1502
						currentScope,
1541
						currentScope,
1503
						codeStream,
1542
						codeStream,
Lines 1513-1531 Link Here
1513
		right.generateCode(currentScope, codeStream, valueRequired);
1552
		right.generateCode(currentScope, codeStream, valueRequired);
1514
		if (valueRequired) {
1553
		if (valueRequired) {
1515
			codeStream.ixor();
1554
			codeStream.ixor();
1516
			if ((bits & OnlyValueRequired) == 0) {
1555
			if (falseLabel == null) {
1517
				if (falseLabel == null) {
1556
				if (trueLabel != null) {
1518
					if (trueLabel != null) {
1557
					// implicit falling through the FALSE case
1519
						// implicit falling through the FALSE case
1558
					codeStream.ifne(trueLabel);
1520
						codeStream.ifne(trueLabel);
1559
				}
1521
					}
1560
			} else {
1561
				// implicit falling through the TRUE case
1562
				if (trueLabel == null) {
1563
					codeStream.ifeq(falseLabel);
1522
				} else {
1564
				} else {
1523
					// implicit falling through the TRUE case
1565
					// no implicit fall through TRUE/FALSE --> should never occur
1524
					if (trueLabel == null) {
1525
						codeStream.ifeq(falseLabel);
1526
					} else {
1527
						// no implicit fall through TRUE/FALSE --> should never occur
1528
					}
1529
				}
1566
				}
1530
			}
1567
			}
1531
		}
1568
		}
(-)compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java (-45 / +345 lines)
Lines 126-170 Link Here
126
	 */
126
	 */
127
	public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
127
	public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
128
	
128
	
129
		int pc = codeStream.position;
129
		if (constant != Constant.NotAConstant) {
130
		if (constant != Constant.NotAConstant) {
130
			int pc = codeStream.position;
131
			if (valueRequired) 
131
			if (valueRequired) 
132
				codeStream.generateConstant(constant, implicitConversion);
132
				codeStream.generateConstant(constant, implicitConversion);
133
			codeStream.recordPositionsFrom(pc, this.sourceStart);
133
			codeStream.recordPositionsFrom(pc, this.sourceStart);
134
			return;
134
			return;
135
		}
135
		}
136
		Label falseLabel;
136
		
137
		bits |= OnlyValueRequired;
137
		if ((left.implicitConversion & COMPILE_TYPE_MASK) /*compile-time*/ == T_boolean) {
138
		generateOptimizedBoolean(
138
			generateBooleanEqual(currentScope, codeStream, valueRequired);
139
			currentScope, 
139
		} else {
140
			codeStream, 
140
			generateNonBooleanEqual(currentScope, codeStream, valueRequired);
141
			null, 
142
			falseLabel = new Label(codeStream), 
143
			valueRequired);
144
		if (falseLabel.hasForwardReferences()) {
145
			if (valueRequired){
146
				// comparison is TRUE 
147
				codeStream.iconst_1();
148
				if ((bits & IsReturnedValue) != 0){
149
					codeStream.generateImplicitConversion(this.implicitConversion);
150
					codeStream.generateReturnBytecode(this);
151
					// comparison is FALSE
152
					falseLabel.place();
153
					codeStream.iconst_0();
154
				} else {
155
					Label endLabel = new Label(codeStream);
156
					codeStream.goto_(endLabel);
157
					codeStream.decrStackSize(1);
158
					// comparison is FALSE
159
					falseLabel.place();
160
					codeStream.iconst_0();
161
					endLabel.place();
162
				}
163
				codeStream.generateImplicitConversion(implicitConversion);
164
			} else {
165
				falseLabel.place();
166
			}	
167
		}
141
		}
142
		if (valueRequired) {
143
			codeStream.generateImplicitConversion(implicitConversion);
144
		}
145
		codeStream.recordPositionsFrom(pc, this.sourceStart);
168
	}
146
	}
169
	/**
147
	/**
170
	 * Boolean operator code generation
148
	 * Boolean operator code generation
Lines 190-195 Link Here
190
			}
168
			}
191
		}
169
		}
192
	}
170
	}
171
172
	/**
173
	 * Boolean generation for == with boolean operands
174
	 *
175
	 * Note this code does not optimize conditional constants !!!!
176
	 */
177
	public void generateBooleanEqual(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
178
	
179
		// optimized cases: <something equivalent to true> == x, <something equivalent to false> == x, 
180
		// optimized cases: <something equivalent to false> != x, <something equivalent to true> != x, 
181
		Constant cst = left.optimizedBooleanConstant();
182
		if (cst != Constant.NotAConstant) {
183
			Constant rightCst = right.optimizedBooleanConstant();
184
			if (rightCst != Constant.NotAConstant) {
185
				// <something equivalent to true> == <something equivalent to true>, <something equivalent to false> != <something equivalent to true>
186
				// <something equivalent to true> == <something equivalent to false>, <something equivalent to false> != <something equivalent to false>
187
				left.generateCode(currentScope, codeStream, false);
188
				right.generateCode(currentScope, codeStream, false);
189
				if (valueRequired) {
190
					boolean leftBool = cst.booleanValue();
191
					boolean rightBool = rightCst.booleanValue();
192
					if (((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) {
193
						if (leftBool == rightBool) {
194
							codeStream.iconst_1();
195
						} else {
196
							codeStream.iconst_0();
197
						}
198
					} else {
199
						if (leftBool != rightBool) {
200
							codeStream.iconst_1();
201
						} else {
202
							codeStream.iconst_0();
203
						}
204
					}
205
				}
206
			} else if (cst.booleanValue() == (((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL)) {
207
				// <something equivalent to true> == x, <something equivalent to false> != x
208
				left.generateCode(currentScope, codeStream, false);
209
				right.generateCode(currentScope, codeStream, valueRequired);
210
			} else {
211
				// <something equivalent to false> == x, <something equivalent to true> != x
212
				if (valueRequired) {
213
					Label falseLabel = new Label(codeStream);
214
					left.generateCode(currentScope, codeStream, false);
215
					right.generateOptimizedBoolean(currentScope, codeStream, null, falseLabel, valueRequired);
216
					// comparison is TRUE 
217
					codeStream.iconst_0();
218
					if ((bits & IsReturnedValue) != 0){
219
						codeStream.generateImplicitConversion(this.implicitConversion);
220
						codeStream.generateReturnBytecode(this);
221
						// comparison is FALSE
222
						falseLabel.place();
223
						codeStream.iconst_1();
224
					} else {
225
						Label endLabel = new Label(codeStream);
226
						codeStream.goto_(endLabel);
227
						codeStream.decrStackSize(1);
228
						// comparison is FALSE
229
						falseLabel.place();
230
						codeStream.iconst_1();
231
						endLabel.place();
232
					}
233
				} else {
234
					left.generateCode(currentScope, codeStream, false);
235
					right.generateCode(currentScope, codeStream, false);
236
				}
237
//				left.generateCode(currentScope, codeStream, false);
238
//				right.generateCode(currentScope, codeStream, valueRequired);
239
//				if (valueRequired) {
240
//					codeStream.iconst_1();
241
//					codeStream.ixor(); // negate
242
//				}
243
			}
244
			return;
245
		} 
246
		cst = right.optimizedBooleanConstant();
247
		if (cst != Constant.NotAConstant) {
248
			if (cst.booleanValue() == (((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL)) {
249
				// x == <something equivalent to true>, x != <something equivalent to false>
250
				left.generateCode(currentScope, codeStream, valueRequired);
251
				right.generateCode(currentScope, codeStream, false);
252
			} else {
253
				// x == <something equivalent to false>, x != <something equivalent to true>
254
				if (valueRequired) {
255
					Label falseLabel = new Label(codeStream);
256
					left.generateOptimizedBoolean(currentScope, codeStream, null, falseLabel, valueRequired);
257
					right.generateCode(currentScope, codeStream, false);
258
					// comparison is TRUE 
259
					codeStream.iconst_0();
260
					if ((bits & IsReturnedValue) != 0){
261
						codeStream.generateImplicitConversion(this.implicitConversion);
262
						codeStream.generateReturnBytecode(this);
263
						// comparison is FALSE
264
						falseLabel.place();
265
						codeStream.iconst_1();
266
					} else {
267
						Label endLabel = new Label(codeStream);
268
						codeStream.goto_(endLabel);
269
						codeStream.decrStackSize(1);
270
						// comparison is FALSE
271
						falseLabel.place();
272
						codeStream.iconst_1();
273
						endLabel.place();
274
					}
275
				} else {
276
					left.generateCode(currentScope, codeStream, false);
277
					right.generateCode(currentScope, codeStream, false);
278
				}
279
//				left.generateCode(currentScope, codeStream, valueRequired);
280
//				right.generateCode(currentScope, codeStream, false);
281
//				if (valueRequired) {
282
//					codeStream.iconst_1();
283
//					codeStream.ixor(); // negate
284
//				}
285
			}
286
			return;
287
		} 
288
		// default case
289
		left.generateCode(currentScope, codeStream, valueRequired);
290
		right.generateCode(currentScope, codeStream, valueRequired);
291
292
		if (valueRequired) {
293
			Label falseLabel;
294
			codeStream.if_icmpne(falseLabel = new Label(codeStream));
295
			// comparison is TRUE 
296
			codeStream.iconst_1();
297
			if ((bits & IsReturnedValue) != 0){
298
				codeStream.generateImplicitConversion(this.implicitConversion);
299
				codeStream.generateReturnBytecode(this);
300
				// comparison is FALSE
301
				falseLabel.place();
302
				codeStream.iconst_0();
303
			} else {
304
				Label endLabel = new Label(codeStream);
305
				codeStream.goto_(endLabel);
306
				codeStream.decrStackSize(1);
307
				// comparison is FALSE
308
				falseLabel.place();
309
				codeStream.iconst_0();
310
				endLabel.place();
311
			}
312
		}
313
	}
314
	
193
	/**
315
	/**
194
	 * Boolean generation for == with boolean operands
316
	 * Boolean generation for == with boolean operands
195
	 *
317
	 *
Lines 233-238 Link Here
233
	 * Boolean generation for == with non-boolean operands
355
	 * Boolean generation for == with non-boolean operands
234
	 *
356
	 *
235
	 */
357
	 */
358
	public void generateNonBooleanEqual(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
359
	
360
		if (((left.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) == T_int) {
361
			Constant cst;
362
			if ((cst = left.constant) != Constant.NotAConstant && cst.intValue() == 0) {
363
				// optimized case: 0 == x, 0 != x
364
				right.generateCode(currentScope, codeStream, valueRequired);
365
				if (valueRequired) {
366
					Label falseLabel = new Label(codeStream);
367
					if (((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) {
368
						codeStream.ifne(falseLabel);
369
					} else {
370
						codeStream.ifeq(falseLabel);
371
					}
372
					// comparison is TRUE 
373
					codeStream.iconst_1();
374
					if ((bits & IsReturnedValue) != 0){
375
						codeStream.generateImplicitConversion(this.implicitConversion);
376
						codeStream.generateReturnBytecode(this);
377
						// comparison is FALSE
378
						falseLabel.place();
379
						codeStream.iconst_0();
380
					} else {
381
						Label endLabel = new Label(codeStream);
382
						codeStream.goto_(endLabel);
383
						codeStream.decrStackSize(1);
384
						// comparison is FALSE
385
						falseLabel.place();
386
						codeStream.iconst_0();
387
						endLabel.place();
388
					}
389
				}				
390
				return;
391
			}
392
			if ((cst = right.constant) != Constant.NotAConstant && cst.intValue() == 0) {
393
				// optimized case: x == 0, x != 0
394
				left.generateCode(currentScope, codeStream, valueRequired);
395
				if (valueRequired) {
396
					Label falseLabel = new Label(codeStream);
397
					if (((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) {
398
						codeStream.ifne(falseLabel);
399
					} else {
400
						codeStream.ifeq(falseLabel);
401
					}
402
					// comparison is TRUE 
403
					codeStream.iconst_1();
404
					if ((bits & IsReturnedValue) != 0){
405
						codeStream.generateImplicitConversion(this.implicitConversion);
406
						codeStream.generateReturnBytecode(this);
407
						// comparison is FALSE
408
						falseLabel.place();
409
						codeStream.iconst_0();
410
					} else {
411
						Label endLabel = new Label(codeStream);
412
						codeStream.goto_(endLabel);
413
						codeStream.decrStackSize(1);
414
						// comparison is FALSE
415
						falseLabel.place();
416
						codeStream.iconst_0();
417
						endLabel.place();
418
					}
419
				}				
420
				return;
421
			}			
422
		}
423
424
		// null cases
425
		if (right instanceof NullLiteral) {
426
			if (left instanceof NullLiteral) {
427
				// null == null, null != null
428
				if (valueRequired) {
429
					if (((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) {
430
						codeStream.iconst_1();
431
					} else {
432
						codeStream.iconst_0();
433
					}
434
				}
435
			} else {
436
				// x == null, x != null
437
				left.generateCode(currentScope, codeStream, valueRequired);
438
				if (valueRequired) {
439
					Label falseLabel = new Label(codeStream);
440
					if (((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) {
441
						codeStream.ifnonnull(falseLabel);
442
					} else {
443
						codeStream.ifnull(falseLabel);
444
					}
445
					// comparison is TRUE 
446
					codeStream.iconst_1();
447
					if ((bits & IsReturnedValue) != 0){
448
						codeStream.generateImplicitConversion(this.implicitConversion);
449
						codeStream.generateReturnBytecode(this);
450
						// comparison is FALSE
451
						falseLabel.place();
452
						codeStream.iconst_0();
453
					} else {
454
						Label endLabel = new Label(codeStream);
455
						codeStream.goto_(endLabel);
456
						codeStream.decrStackSize(1);
457
						// comparison is FALSE
458
						falseLabel.place();
459
						codeStream.iconst_0();
460
						endLabel.place();
461
					}
462
				}
463
			}
464
			return;
465
		} else if (left instanceof NullLiteral) {
466
			// null = x, null != x
467
			right.generateCode(currentScope, codeStream, valueRequired);
468
			if (valueRequired) {
469
				Label falseLabel = new Label(codeStream);
470
				if (((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) {
471
					codeStream.ifnonnull(falseLabel);
472
				} else {
473
					codeStream.ifnull(falseLabel);
474
				}
475
				// comparison is TRUE 
476
				codeStream.iconst_1();
477
				if ((bits & IsReturnedValue) != 0){
478
					codeStream.generateImplicitConversion(this.implicitConversion);
479
					codeStream.generateReturnBytecode(this);
480
					// comparison is FALSE
481
					falseLabel.place();
482
					codeStream.iconst_0();
483
				} else {
484
					Label endLabel = new Label(codeStream);
485
					codeStream.goto_(endLabel);
486
					codeStream.decrStackSize(1);
487
					// comparison is FALSE
488
					falseLabel.place();
489
					codeStream.iconst_0();
490
					endLabel.place();
491
				}
492
			}				
493
			return;
494
		}
495
	
496
		// default case
497
		left.generateCode(currentScope, codeStream, valueRequired);
498
		right.generateCode(currentScope, codeStream, valueRequired);
499
		if (valueRequired) {
500
			Label falseLabel = new Label(codeStream);
501
			switch ((left.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) { // operand runtime type
502
				case T_int :
503
					codeStream.if_icmpne(falseLabel);
504
					break;
505
				case T_float :
506
					codeStream.fcmpl();
507
					codeStream.ifne(falseLabel);
508
					break;
509
				case T_long :
510
					codeStream.lcmp();
511
					codeStream.ifne(falseLabel);
512
					break;
513
				case T_double :
514
					codeStream.dcmpl();
515
					codeStream.ifne(falseLabel);
516
					break;
517
				default :
518
					codeStream.if_acmpne(falseLabel);
519
			}
520
			// comparison is TRUE 
521
			codeStream.iconst_1();
522
			if ((bits & IsReturnedValue) != 0){
523
				codeStream.generateImplicitConversion(this.implicitConversion);
524
				codeStream.generateReturnBytecode(this);
525
				// comparison is FALSE
526
				falseLabel.place();
527
				codeStream.iconst_0();
528
			} else {
529
				Label endLabel = new Label(codeStream);
530
				codeStream.goto_(endLabel);
531
				codeStream.decrStackSize(1);
532
				// comparison is FALSE
533
				falseLabel.place();
534
				codeStream.iconst_0();
535
				endLabel.place();
536
			}			
537
		}
538
	}
539
	
540
	/**
541
	 * Boolean generation for == with non-boolean operands
542
	 *
543
	 */
236
	public void generateOptimizedNonBooleanEqual(BlockScope currentScope, CodeStream codeStream, Label trueLabel, Label falseLabel, boolean valueRequired) {
544
	public void generateOptimizedNonBooleanEqual(BlockScope currentScope, CodeStream codeStream, Label trueLabel, Label falseLabel, boolean valueRequired) {
237
	
545
	
238
		int pc = codeStream.position;
546
		int pc = codeStream.position;
Lines 290-308 Link Here
290
			if (left instanceof NullLiteral) {
598
			if (left instanceof NullLiteral) {
291
				// null == null
599
				// null == null
292
				if (valueRequired) {
600
				if (valueRequired) {
293
						if ((bits & OnlyValueRequired) != 0) {
601
					if (falseLabel == null) {
294
							if (((bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) {
602
						// implicit falling through the FALSE case
295
								codeStream.iconst_1();
603
						if (trueLabel != null) {
296
							} else {
604
							codeStream.goto_(trueLabel);
297
								codeStream.iconst_0();
605
						}
298
							}
299
						} else {
300
							if (falseLabel == null) {
301
								// implicit falling through the FALSE case
302
								if (trueLabel != null) {
303
									codeStream.goto_(trueLabel);
304
								}
305
							}
306
					}
606
					}
307
				}
607
				}
308
			} else {
608
			} else {
(-)compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java (-2 / +1 lines)
Lines 25-31 Link Here
25
	public final static int Bit3 = 0x4; 						// return type (operator) | name reference kind (name ref) | implicit this (this ref)
25
	public final static int Bit3 = 0x4; 						// return type (operator) | name reference kind (name ref) | implicit this (this ref)
26
	public final static int Bit4 = 0x8; 						// return type (operator) | first assignment to local (local decl) | undocumented empty block (block, type and method decl)
26
	public final static int Bit4 = 0x8; 						// return type (operator) | first assignment to local (local decl) | undocumented empty block (block, type and method decl)
27
	public final static int Bit5 = 0x10; 						// value for return (expression) | has all method bodies (unit) | supertype ref (type ref)
27
	public final static int Bit5 = 0x10; 						// value for return (expression) | has all method bodies (unit) | supertype ref (type ref)
28
	public final static int Bit6 = 0x20; 						// depth (name ref, msg) | only value required (binary expression) | ignore need cast check (cast expression)
28
	public final static int Bit6 = 0x20; 						// depth (name ref, msg) | ignore need cast check (cast expression)
29
	public final static int Bit7 = 0x40; 						// depth (name ref, msg) | operator (operator) | need runtime checkcast (cast expression) | label used (labelStatement)
29
	public final static int Bit7 = 0x40; 						// depth (name ref, msg) | operator (operator) | need runtime checkcast (cast expression) | label used (labelStatement)
30
	public final static int Bit8 = 0x80; 						// depth (name ref, msg) | operator (operator) | unsafe cast (cast expression)
30
	public final static int Bit8 = 0x80; 						// depth (name ref, msg) | operator (operator) | unsafe cast (cast expression)
31
	public final static int Bit9 = 0x100; 					// depth (name ref, msg) | operator (operator) | is local type (type decl)
31
	public final static int Bit9 = 0x100; 					// depth (name ref, msg) | operator (operator) | is local type (type decl)
Lines 88-94 Link Here
88
88
89
	// for binary expressions
89
	// for binary expressions
90
	public static final int IsReturnedValue = Bit5; 
90
	public static final int IsReturnedValue = Bit5; 
91
	public static final int OnlyValueRequired = Bit6; 
92
91
93
	// for cast expressions
92
	// for cast expressions
94
	public static final int UnnecessaryCast = Bit15;
93
	public static final int UnnecessaryCast = Bit15;
(-)compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java (-1 / +1 lines)
Lines 342-348 Link Here
342
							codeStream.generateConstant(fieldConstant, implicitConversion);
342
							codeStream.generateConstant(fieldConstant, implicitConversion);
343
						}
343
						}
344
					} else {
344
					} else {
345
						if (valueRequired || currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) {
345
						if (valueRequired) {
346
							boolean isStatic = fieldBinding.isStatic();
346
							boolean isStatic = fieldBinding.isStatic();
347
							if (!isStatic) {
347
							if (!isStatic) {
348
								if ((bits & DepthMASK) != 0) {
348
								if ((bits & DepthMASK) != 0) {

Return to bug 117120