1// Copyright 2009 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6//     * Redistributions of source code must retain the above copyright
7//       notice, this list of conditions and the following disclaimer.
8//     * Redistributions in binary form must reproduce the above
9//       copyright notice, this list of conditions and the following
10//       disclaimer in the documentation and/or other materials provided
11//       with the distribution.
12//     * Neither the name of Google Inc. nor the names of its
13//       contributors may be used to endorse or promote products derived
14//       from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28// Test operations that involve one or more constants.
29// The code generator now handles compile-time constants specially.
30// Test the code generated when operands are known at compile time
31
32// Test count operations involving constants
33function test_count() {
34  var x = "foo";
35  var y = "3";
36
37  x += x++;  // ++ and -- apply ToNumber to their operand, even for postfix.
38  assertEquals(x, "fooNaN", "fooNaN test");
39  x = "luft";
40  x += ++x;
41  assertEquals(x, "luftNaN", "luftNaN test");
42
43  assertTrue(y++ === 3, "y++ === 3, where y = \"3\"");
44  y = 3;
45  assertEquals(y++, 3, "y++ == 3, where y = 3");
46  y = "7.1";
47  assertTrue(y++ === 7.1, "y++ === 7.1, where y = \"7.1\"");
48  var z = y = x = "9";
49  assertEquals( z++ + (++y) + x++, 28, "z++ + (++y) + x++ == 28");
50  z = y = x = 13;
51  assertEquals( z++ + (++y) + x++, 40, "z++ + (++y) + x++ == 40");
52  z = y = x = -5.5;
53  assertEquals( z++ + (++y) + x++, -15.5, "z++ + (++y) + x++ == -15.5");
54
55  assertEquals(y, -4.5);
56  z = y;
57  z++;
58  assertEquals(y, -4.5);
59  z = y;
60  y++;
61  assertEquals(z, -4.5);
62
63  y = 20;
64  z = y;
65  z++;
66  assertEquals(y, 20);
67  z = y;
68  y++;
69  assertEquals(z, 20);
70
71  const w = 30;
72  assertEquals(w++, 30);
73  assertEquals(++w, 31);
74  assertEquals(++w, 31);
75}
76
77test_count();
78
79// Test comparison operations that involve one or two constant smis.
80
81function test() {
82  var i = 5;
83  var j = 3;
84
85  assertTrue( j < i );
86  i = 5; j = 3;
87  assertTrue( j <= i );
88  i = 5; j = 3;
89  assertTrue( i > j );
90  i = 5; j = 3;
91  assertTrue( i >= j );
92  i = 5; j = 3;
93  assertTrue( i != j );
94  i = 5; j = 3;
95  assertTrue( i == i );
96  i = 5; j = 3;
97  assertFalse( i < j );
98  i = 5; j = 3;
99  assertFalse( i <= j );
100  i = 5; j = 3;
101  assertFalse( j > i );
102  i = 5; j = 3;
103  assertFalse(j >= i );
104  i = 5; j = 3;
105  assertFalse( j == i);
106  i = 5; j = 3;
107  assertFalse( i != i);
108
109  i = 10 * 10;
110  while ( i < 107 ) {
111    ++i;
112  }
113  j = 21;
114
115  assertTrue( j < i );
116  j = 21;
117  assertTrue( j <= i );
118  j = 21;
119  assertTrue( i > j );
120  j = 21;
121  assertTrue( i >= j );
122  j = 21;
123  assertTrue( i != j );
124  j = 21;
125  assertTrue( i == i );
126  j = 21;
127  assertFalse( i < j );
128  j = 21;
129  assertFalse( i <= j );
130  j = 21;
131  assertFalse( j > i );
132  j = 21;
133  assertFalse(j >= i );
134  j = 21;
135  assertFalse( j == i);
136  j = 21;
137  assertFalse( i != i);
138  j = 21;
139  assertTrue( j == j );
140  j = 21;
141  assertFalse( j != j );
142
143  assertTrue( 100 > 99 );
144  assertTrue( 101 >= 90 );
145  assertTrue( 11111 > -234 );
146  assertTrue( -888 <= -20 );
147
148  while ( 234 > 456 ) {
149    i = i + 1;
150  }
151
152  switch(3) {
153    case 5:
154      assertUnreachable();
155      break;
156    case 3:
157      j = 13;
158    default:
159      i = 2;
160    case 7:
161      j = 17;
162      break;
163    case 9:
164      j = 19;
165      assertUnreachable();
166      break;
167  }
168  assertEquals(17, j, "switch with constant value");
169}
170
171
172function TrueToString() {
173  return true.toString();
174}
175
176
177function FalseToString() {
178  return false.toString();
179}
180
181
182function BoolTest() {
183  assertEquals("true", TrueToString());
184  assertEquals("true", TrueToString());
185  assertEquals("true", TrueToString());
186  assertEquals("false", FalseToString());
187  assertEquals("false", FalseToString());
188  assertEquals("false", FalseToString());
189  Boolean.prototype.toString = function() { return "foo"; }
190  assertEquals("foo", TrueToString());
191  assertEquals("foo", FalseToString());
192}
193
194
195// Some tests of shifts that get into the corners in terms of coverage.
196// We generate different code for the case where the operand is a constant.
197function ShiftTest() {
198  var x = 123;
199  assertEquals(x, x >> 0);
200  assertEquals(x, x << 0);
201  assertEquals(x, x >>> 0);
202  assertEquals(61, x >> 1);
203  assertEquals(246, x << 1);
204  assertEquals(61, x >>> 1);
205  x = -123;
206  assertEquals(x, x >> 0);
207  assertEquals(x, x << 0);
208  assertEquals(0x10000 * 0x10000 + x, x >>> 0);
209  assertEquals(-62, x >> 1);
210  assertEquals(-246, x << 1);
211  assertEquals(0x10000 * 0x8000 - 62, x >>> 1);
212  // Answer is non-Smi so the subtraction is not folded in the code
213  // generator.
214  assertEquals(-0x40000001, -0x3fffffff - 2);
215
216  x = 123;
217  assertEquals(0, x & 0);
218
219  // Answer is non-smi and lhs of << is a temporary heap number that we can
220  // overwrite.
221  x = 123.0001;
222  assertEquals(1073741824, (x * x) << 30);
223  x = 123;
224  // Answer is non-smi and lhs of << is a temporary heap number that we think
225  // we can overwrite (but we can't because it's a Smi).
226  assertEquals(1073741824, (x * x) << 30);
227}
228
229
230test();
231BoolTest();
232ShiftTest();
233