1// Copyright 2013 the V8 project authors. All rights reserved.
2// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions
6// are met:
7// 1.  Redistributions of source code must retain the above copyright
8//     notice, this list of conditions and the following disclaimer.
9// 2.  Redistributions in binary form must reproduce the above copyright
10//     notice, this list of conditions and the following disclaimer in the
11//     documentation and/or other materials provided with the distribution.
12//
13// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
24description(
25'Tests whether bytecode codegen properly handles temporaries.'
26);
27
28var a = true;
29a = false || a;
30shouldBeTrue("a");
31
32var b = false;
33b = true && b;
34shouldBeFalse("b");
35
36function TestObject() {
37    this.toString = function() { return this.test; }
38    this.test = "FAIL";
39    return this;
40}
41
42function assign_test1()
43{
44    var testObject = new TestObject;
45    var a = testObject;
46    a.test = "PASS";
47    return testObject.test;
48}
49
50shouldBe("assign_test1()", "'PASS'");
51
52function assign_test2()
53{
54    var testObject = new TestObject;
55    var a = testObject;
56    a = a.test = "PASS";
57    return testObject.test;
58}
59
60shouldBe("assign_test2()", "'PASS'");
61
62function assign_test3()
63{
64    var testObject = new TestObject;
65    var a = testObject;
66    a.test = a = "PASS";
67    return testObject.test;
68}
69
70shouldBe("assign_test3()", "'PASS'");
71
72var testObject4 = new TestObject;
73var a4 = testObject4;
74a4.test = this.a4 = "PASS";
75
76shouldBe("testObject4.test", "'PASS'");
77
78var testObject5 = new TestObject;
79var a5 = testObject5;
80a5 = this.a5.test = "PASS";
81
82shouldBe("testObject5.test", "'PASS'");
83
84function assign_test6()
85{
86    var testObject = new TestObject;
87    var a = testObject;
88    a["test"] = "PASS";
89    return testObject.test;
90}
91
92shouldBe("assign_test6()", "'PASS'");
93
94function assign_test7()
95{
96    var testObject = new TestObject;
97    var a = testObject;
98    a = a["test"] = "PASS";
99    return testObject.test;
100}
101
102shouldBe("assign_test7()", "'PASS'");
103
104function assign_test8()
105{
106    var testObject = new TestObject;
107    var a = testObject;
108    a["test"] = a = "PASS";
109    return testObject.test;
110}
111
112shouldBe("assign_test8()", "'PASS'");
113
114function assign_test9()
115{
116    var testObject = new TestObject;
117    var a = testObject;
118    a["test"] = this.a = "PASS";
119    return testObject.test;
120}
121
122shouldBe("assign_test9()", "'PASS'");
123
124var testObject10 = new TestObject;
125var a10 = testObject10;
126a10 = this.a10["test"] = "PASS";
127
128shouldBe("testObject10.test", "'PASS'");
129
130function assign_test11()
131{
132    var testObject = new TestObject;
133    var a = testObject;
134    a[a = "test"] = "PASS";
135    return testObject.test;
136}
137
138shouldBe("assign_test11()", "'PASS'");
139
140function assign_test12()
141{
142    var test = "test";
143    var testObject = new TestObject;
144    var a = testObject;
145    a[test] = "PASS";
146    return testObject.test;
147}
148
149shouldBe("assign_test12()", "'PASS'");
150
151function assign_test13()
152{
153    var testObject = new TestObject;
154    var a = testObject;
155    a.test = (a = "FAIL", "PASS");
156    return testObject.test;
157}
158
159shouldBe("assign_test13()", "'PASS'");
160
161function assign_test14()
162{
163    var testObject = new TestObject;
164    var a = testObject;
165    a["test"] = (a = "FAIL", "PASS");
166    return testObject.test;
167}
168
169shouldBe("assign_test14()", "'PASS'");
170
171function assign_test15()
172{
173    var test = "test";
174    var testObject = new TestObject;
175    var a = testObject;
176    a[test] = (test = "FAIL", "PASS");
177    return testObject.test;
178}
179
180shouldBe("assign_test15()", "'PASS'");
181
182function assign_test16()
183{
184    var a = 1;
185    a = (a = 2);
186    return a;
187}
188
189shouldBe("assign_test16()", "2");
190
191var a17 = 1;
192a17 += (a17 += 1);
193
194shouldBe("a17", "3");
195
196function assign_test18()
197{
198    var a = 1;
199    a += (a += 1);
200    return a;
201}
202
203shouldBe("assign_test18()", "3");
204
205var a19 = { b: 1 };
206a19.b += (a19.b += 1);
207
208shouldBe("a19.b", "3");
209
210function assign_test20()
211{
212    var a = { b: 1 };
213    a.b += (a.b += 1);
214    return a.b;
215}
216
217shouldBe("assign_test20()", "3");
218
219var a21 = { b: 1 };
220a21["b"] += (a21["b"] += 1);
221
222shouldBe("a21['b']", "3");
223
224function assign_test22()
225{
226    var a = { b: 1 };
227    a["b"] += (a["b"] += 1);
228    return a["b"];
229}
230
231shouldBe("assign_test22()", "3");
232
233function assign_test23()
234{
235    var o = { b: 1 };
236    var a = o;
237    a.b += a = 2;
238    return o.b;
239}
240
241shouldBe("assign_test23()", "3");
242
243function assign_test24()
244{
245    var o = { b: 1 };
246    var a = o;
247    a["b"] += a = 2;
248    return o["b"];
249}
250
251shouldBe("assign_test24()", "3");
252
253function assign_test25()
254{
255    var o = { b: 1 };
256    var a = o;
257    a[a = "b"] += a = 2;
258    return o["b"];
259}
260
261shouldBe("assign_test25()", "3");
262
263function assign_test26()
264{
265    var o = { b: 1 };
266    var a = o;
267    var b = "b";
268    a[b] += a = 2;
269    return o["b"];
270}
271
272shouldBe("assign_test26()", "3");
273
274function assign_test27()
275{
276    var o = { b: 1 };
277    var a = o;
278    a.b += (a = 100, 2);
279    return o.b;
280}
281
282shouldBe("assign_test27()", "3");
283
284function assign_test28()
285{
286    var o = { b: 1 };
287    var a = o;
288    a["b"] += (a = 100, 2);
289    return o["b"];
290}
291
292shouldBe("assign_test28()", "3");
293
294function assign_test29()
295{
296    var o = { b: 1 };
297    var a = o;
298    var b = "b";
299    a[b] += (a = 100, 2);
300    return o["b"];
301}
302
303shouldBe("assign_test29()", "3");
304
305function assign_test30()
306{
307    var a = "foo";
308    a += (a++);
309    return a;
310}
311
312shouldBe("assign_test30()", "'fooNaN'");
313
314function assign_test31()
315{
316    function result() { return "PASS"; }
317    return (globalVar = result)()
318}
319
320shouldBe("assign_test31()", "'PASS'");
321
322function bracket_test1()
323{
324    var o = [-1];
325    var a = o[++o];
326    return a;
327}
328
329shouldBe("bracket_test1()", "-1");
330
331function bracket_test2()
332{
333    var o = [1];
334    var a = o[--o];
335    return a;
336}
337
338shouldBe("bracket_test2()", "1");
339
340function bracket_test3()
341{
342    var o = [0];
343    var a = o[o++];
344    return a;
345}
346
347shouldBe("bracket_test3()", "0");
348
349function bracket_test4()
350{
351    var o = [0];
352    var a = o[o--];
353    return a;
354}
355
356shouldBe("bracket_test4()", "0");
357
358function bracket_test5()
359{
360    var o = [1];
361    var a = o[o ^= 1];
362    return a;
363}
364
365shouldBe("bracket_test5()", "1");
366
367function bracket_test6()
368{
369    var o = { b: 1 }
370    var b = o[o = { b: 2 }, "b"];
371    return b;
372}
373
374shouldBe("bracket_test6()", "1");
375
376function mult_test1()
377{
378    var a = 1;
379    return a * (a = 2);
380}
381
382shouldBe("mult_test1()", "2");
383
384function mult_test2()
385{
386    var a = 1;
387    return a * ++a;
388}
389
390shouldBe("mult_test2()", "2");
391
392function mult_test3()
393{
394    var a = 1;
395    return a * (a += 1);
396}
397
398shouldBe("mult_test3()", "2");
399
400function div_test1()
401{
402    var a = 1;
403    return a / (a = 2);
404}
405
406shouldBe("div_test1()", "0.5");
407
408function div_test2()
409{
410    var a = 1;
411    return a / ++a;
412}
413
414shouldBe("div_test2()", "0.5");
415
416function div_test3()
417{
418    var a = 1;
419    return a / (a += 1);
420}
421
422shouldBe("div_test3()", "0.5");
423
424function mod_test1()
425{
426    var a = 1;
427    return a % (a = 2);
428}
429
430shouldBe("mod_test1()", "1");
431
432function mod_test2()
433{
434    var a = 1;
435    return a % ++a;
436}
437
438shouldBe("mod_test2()", "1");
439
440function mod_test3()
441{
442    var a = 1;
443    return a % (a += 1);
444}
445
446shouldBe("mod_test3()", "1");
447
448function add_test1()
449{
450    var a = 1;
451    return a + (a = 2);
452}
453
454shouldBe("add_test1()", "3");
455
456function add_test2()
457{
458    var a = 1;
459    return a + ++a;
460}
461
462shouldBe("add_test2()", "3");
463
464function add_test3()
465{
466    var a = 1;
467    return a + (a += 1);
468}
469
470shouldBe("add_test3()", "3");
471
472function sub_test1()
473{
474    var a = 1;
475    return a - (a = 2);
476}
477
478shouldBe("sub_test1()", "-1");
479
480function sub_test2()
481{
482    var a = 1;
483    return a - ++a;
484}
485
486shouldBe("sub_test2()", "-1");
487
488function sub_test3()
489{
490    var a = 1;
491    return a - (a += 1);
492}
493
494shouldBe("sub_test3()", "-1");
495
496function lshift_test1()
497{
498    var a = 1;
499    return a << (a = 2);
500}
501
502shouldBe("lshift_test1()", "4");
503
504function lshift_test2()
505{
506    var a = 1;
507    return a << ++a;
508}
509
510shouldBe("lshift_test2()", "4");
511
512function lshift_test3()
513{
514    var a = 1;
515    return a << (a += 1);
516}
517
518shouldBe("lshift_test3()", "4");
519
520function rshift_test1()
521{
522    var a = 4;
523    return a >> (a = 2);
524}
525
526shouldBe("rshift_test1()", "1");
527
528function rshift_test2()
529{
530    var a = 2;
531    return a >> --a;
532}
533
534shouldBe("rshift_test2()", "1");
535
536function rshift_test3()
537{
538    var a = 2;
539    return a >> (a -= 1);
540}
541
542shouldBe("rshift_test3()", "1");
543
544function urshift_test1()
545{
546    var a = 4;
547    return a >>> (a = 2);
548}
549
550shouldBe("urshift_test1()", "1");
551
552function urshift_test2()
553{
554    var a = 2;
555    return a >>> --a;
556}
557
558shouldBe("urshift_test2()", "1");
559
560function urshift_test3()
561{
562    var a = 2;
563    return a >>> (a -= 1);
564}
565
566shouldBe("urshift_test3()", "1");
567
568function less_test1()
569{
570    var a = 1;
571    return a < (a = 2);
572}
573
574shouldBeTrue("less_test1()");
575
576function less_test2()
577{
578    var a = 1;
579    return a < ++a;
580}
581
582shouldBeTrue("less_test2()");
583
584function less_test3()
585{
586    var a = 1;
587    return a < (a += 1);
588}
589
590shouldBeTrue("less_test3()");
591
592function greater_test1()
593{
594    var a = 2;
595    return a > (a = 1);
596}
597
598shouldBeTrue("greater_test1()");
599
600function greater_test2()
601{
602    var a = 2;
603    return a > --a;
604}
605
606shouldBeTrue("greater_test2()");
607
608function greater_test3()
609{
610    var a = 2;
611    return a > (a -= 1);
612}
613
614shouldBeTrue("greater_test3()");
615
616function lesseq_test1()
617{
618    var a = 1;
619    return a <= (a = 3, 2);
620}
621
622shouldBeTrue("lesseq_test1()");
623
624function lesseq_test2()
625{
626    var a = 1;
627    return a <= (++a, 1);
628}
629
630shouldBeTrue("lesseq_test2()");
631
632function lesseq_test3()
633{
634    var a = 1;
635    return a <= (a += 1, 1);
636}
637
638shouldBeTrue("lesseq_test3()");
639
640function greatereq_test1()
641{
642    var a = 2;
643    return a >= (a = 1, 2);
644}
645
646shouldBeTrue("greatereq_test1()");
647
648function greatereq_test2()
649{
650    var a = 2;
651    return a >= (--a, 2);
652}
653
654shouldBeTrue("greatereq_test2()");
655
656function greatereq_test3()
657{
658    var a = 2;
659    return a >= (a -= 1, 2);
660}
661
662shouldBeTrue("greatereq_test3()");
663
664function instanceof_test1()
665{
666    var a = { };
667    return a instanceof (a = 1, Object);
668}
669
670shouldBeTrue("instanceof_test1()");
671
672function instanceof_test2()
673{
674    var a = { valueOf: function() { return 1; } };
675    return a instanceof (++a, Object);
676}
677
678shouldBeTrue("instanceof_test2()");
679
680function instanceof_test3()
681{
682    var a = { valueOf: function() { return 1; } };
683    return a instanceof (a += 1, Object);
684}
685
686shouldBeTrue("instanceof_test3()");
687
688function in_test1()
689{
690    var a = "a";
691    return a in (a = "b", { a: 1 });
692}
693
694shouldBeTrue("in_test1()");
695
696function in_test2()
697{
698    var a = { toString: function() { return "a"; }, valueOf: function() { return 1; } };
699    return a in (++a, { a: 1 });
700}
701
702shouldBeTrue("in_test2()");
703
704function in_test3()
705{
706    var a = { toString: function() { return "a"; }, valueOf: function() { return 1; } };
707    return a in (a += 1, { a: 1 });
708}
709
710shouldBeTrue("in_test3()");
711
712function eq_test1()
713{
714    var a = 1;
715    return a == (a = 2);
716}
717
718shouldBeFalse("eq_test1()");
719
720function eq_test2()
721{
722    var a = 1;
723    return a == ++a;
724}
725
726shouldBeFalse("eq_test2()");
727
728function eq_test3()
729{
730    var a = 1;
731    return a == (a += 1);
732}
733
734shouldBeFalse("eq_test3()");
735
736function neq_test1()
737{
738    var a = 1;
739    return a != (a = 2);
740}
741
742shouldBeTrue("neq_test1()");
743
744function neq_test2()
745{
746    var a = 1;
747    return a != ++a;
748}
749
750shouldBeTrue("neq_test2()");
751
752function neq_test3()
753{
754    var a = 1;
755    return a != (a += 1);
756}
757
758shouldBeTrue("neq_test3()");
759
760function stricteq_test1()
761{
762    var a = 1;
763    return a === (a = 2);
764}
765
766shouldBeFalse("stricteq_test1()");
767
768function stricteq_test2()
769{
770    var a = 1;
771    return a === ++a;
772}
773
774shouldBeFalse("stricteq_test2()");
775
776function stricteq_test3()
777{
778    var a = 1;
779    return a === (a += 1);
780}
781
782shouldBeFalse("stricteq_test3()");
783
784function nstricteq_test1()
785{
786    var a = 1;
787    return a !== (a = 2);
788}
789
790shouldBeTrue("nstricteq_test1()");
791
792function nstricteq_test2()
793{
794    var a = 1;
795    return a !== ++a;
796}
797
798shouldBeTrue("nstricteq_test2()");
799
800function nstricteq_test3()
801{
802    var a = 1;
803    return a !== (a += 1);
804}
805
806shouldBeTrue("nstricteq_test3()");
807
808function bitand_test1()
809{
810    var a = 1;
811    return a & (a = 2);
812}
813
814shouldBe("bitand_test1()", "0");
815
816function bitand_test2()
817{
818    var a = 1;
819    return a & ++a;
820}
821
822shouldBe("bitand_test2()", "0");
823
824function bitand_test3()
825{
826    var a = 1;
827    return a & (a += 1);
828}
829
830shouldBe("bitand_test3()", "0");
831
832function bitor_test1()
833{
834    var a = 1;
835    return a | (a = 2);
836}
837
838shouldBe("bitor_test1()", "3");
839
840function bitor_test2()
841{
842    var a = 1;
843    return a | ++a;
844}
845
846shouldBe("bitor_test2()", "3");
847
848function bitor_test3()
849{
850    var a = 1;
851    return a | (a += 1);
852}
853
854shouldBe("bitor_test3()", "3");
855
856function bitxor_test1()
857{
858    var a = 1;
859    return a ^ (a = 2);
860}
861
862shouldBe("bitxor_test1()", "3");
863
864function bitxor_test2()
865{
866    var a = 1;
867    return a ^ ++a;
868}
869
870shouldBe("bitxor_test2()", "3");
871
872function bitxor_test3()
873{
874    var a = 1;
875    return a ^ (a += 1);
876}
877
878shouldBe("bitxor_test3()", "3");
879
880function switch_test1_helper(a, b)
881{
882    switch (a) {
883    case b:
884        break;
885    default:
886        break;
887    }
888
889    return b;
890}
891
892function switch_test1()
893{
894    return switch_test1_helper(0, 1) == 1;
895}
896
897shouldBeTrue("switch_test1()");
898
899function switch_test2_helper(a, b)
900{
901    var c = b;
902    switch (a) {
903    case c:
904        break;
905    default:
906        break;
907    }
908
909    return c;
910}
911
912function switch_test2()
913{
914    return switch_test2_helper(0, 1) == 1;
915}
916
917shouldBeTrue("switch_test2()");
918
919function switch_test3_helper(a)
920{
921    switch (a) {
922    case this:
923        break;
924    default:
925        break;
926    }
927
928    return this;
929}
930
931function switch_test3()
932{
933    return this == switch_test3_helper.call(this, 0);
934}
935
936shouldBeTrue("switch_test3()");
937
938function construct_test()
939{
940    var c = [function(a) { this.a = a; }];
941
942    function f()
943    {
944        return new c[0](true);
945    }
946
947    return f().a;
948}
949
950shouldBeTrue("construct_test()");
951var testStr = "[";
952for (var i = 0; i < 64; i++)
953    testStr += "(0/0), ";
954testStr += "].length";
955shouldBe(testStr, "64");
956