blob: 9cfdf847fcccf50aa54bdab3b6d590401c8ec0ed [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// Copyright 2011 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// Flags: --allow-natives-syntax
29
30"use strict";
31
32// Check that the following functions are optimizable.
33var functions = [ f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14,
34 f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26,
35 f27, f28, f29, f30, f31, f32, f33];
36
37for (var i = 0; i < functions.length; ++i) {
38 var func = functions[i];
39 print("Testing:");
40 print(func);
41 for (var j = 0; j < 10; ++j) {
42 func(12);
43 }
44 %OptimizeFunctionOnNextCall(func);
45 func(12);
46 assertOptimized(func);
47}
48
49function f1() { }
50
51function f2(x) { }
52
53function f3() {
54 let x;
55}
56
57function f4() {
58 function foo() {
59 }
60}
61
62function f5() {
63 let x = 1;
64}
65
66function f6() {
67 const x = 1;
68}
69
70function f7(x) {
71 return x;
72}
73
74function f8() {
75 let x;
76 return x;
77}
78
79function f9() {
80 function x() {
81 }
82 return x;
83}
84
85function f10(x) {
86 x = 1;
87}
88
89function f11() {
90 let x;
91 x = 1;
92}
93
94function f12() {
95 function x() {};
96 x = 1;
97}
98
99function f13(x) {
100 (function() { x; });
101}
102
103function f14() {
104 let x;
105 (function() { x; });
106}
107
108function f15() {
109 function x() {
110 }
111 (function() { x; });
112}
113
114function f16() {
115 let x = 1;
116 (function() { x; });
117}
118
119function f17() {
120 const x = 1;
121 (function() { x; });
122}
123
124function f18(x) {
125 return x;
126 (function() { x; });
127}
128
129function f19() {
130 let x;
131 return x;
132 (function() { x; });
133}
134
135function f20() {
136 function x() {
137 }
138 return x;
139 (function() { x; });
140}
141
142function f21(x) {
143 x = 1;
144 (function() { x; });
145}
146
147function f22() {
148 let x;
149 x = 1;
150 (function() { x; });
151}
152
153function f23() {
154 function x() { }
155 x = 1;
156 (function() { x; });
157}
158
159function f24() {
160 let x = 1;
161 {
162 let x = 2;
163 {
164 let x = 3;
165 assertEquals(3, x);
166 }
167 assertEquals(2, x);
168 }
169 assertEquals(1, x);
170}
171
172function f25() {
173 {
174 let x = 2;
175 L: {
176 let x = 3;
177 assertEquals(3, x);
178 break L;
179 assertTrue(false);
180 }
181 assertEquals(2, x);
182 }
183 assertTrue(true);
184}
185
186function f26() {
187 {
188 let x = 1;
189 L: {
190 let x = 2;
191 {
192 let x = 3;
193 assertEquals(3, x);
194 break L;
195 assertTrue(false);
196 }
197 assertTrue(false);
198 }
199 assertEquals(1, x);
200 }
201}
202
203
204function f27() {
205 do {
206 let x = 4;
207 assertEquals(4,x);
208 {
209 let x = 5;
210 assertEquals(5, x);
211 continue;
212 assertTrue(false);
213 }
214 } while (false);
215}
216
217function f28() {
218 label: for (var i = 0; i < 10; ++i) {
219 let x = 'middle' + i;
220 for (var j = 0; j < 10; ++j) {
221 let x = 'inner' + j;
222 continue label;
223 }
224 }
225}
226
227function f29() {
228 // Verify that the context is correctly set in the stack frame after exiting
229 // from with.
230
231 let x = 'outer';
232 label: {
233 let x = 'inner';
234 break label;
235 }
236 f(); // The context could be restored from the stack after the call.
237 assertEquals('outer', x);
238
239 function f() {
240 assertEquals('outer', x);
241 };
242}
243
244function f30() {
245 let x = 'outer';
246 for (var i = 0; i < 10; ++i) {
247 let x = 'inner';
248 continue;
249 }
250 f();
251 assertEquals('outer', x);
252
253 function f() {
254 assertEquals('outer', x);
255 };
256}
257
258function f31() {
259 {
260 let x = 'outer';
261 label: for (var i = 0; assertEquals('outer', x), i < 10; ++i) {
262 let x = 'middle' + i;
263 {
264 let x = 'inner' + j;
265 continue label;
266 }
267 }
268 assertEquals('outer', x);
269 }
270}
271
272var c = true;
273
274function f32() {
275 {
276 let x = 'outer';
277 L: {
278 {
279 let x = 'inner';
280 if (c) {
281 break L;
282 }
283 }
284 foo();
285 }
286 }
287
288 function foo() {
289 return 'bar';
290 }
291}
292
293function f33() {
294 {
295 let x = 'outer';
296 L: {
297 {
298 let x = 'inner';
299 if (c) {
300 break L;
301 }
302 foo();
303 }
304 }
305 }
306
307 function foo() {
308 return 'bar';
309 }
310}
311
312function TestThrow() {
313 function f() {
314 let x = 'outer';
315 {
316 let x = 'inner';
317 throw x;
318 }
319 }
320 for (var i = 0; i < 5; i++) {
321 try {
322 f();
323 } catch (e) {
324 assertEquals('inner', e);
325 }
326 }
327 %OptimizeFunctionOnNextCall(f);
328 try {
329 f();
330 } catch (e) {
331 assertEquals('inner', e);
332 }
333 assertOptimized(f);
334}
335
336TestThrow();
337
338// Test that temporal dead zone semantics for function and block scoped
339// let bindings are handled by the optimizing compiler.
340
341function TestFunctionLocal(s) {
342 'use strict';
343 var func = eval("(function baz(){" + s + "; })");
344 print("Testing:");
345 print(func);
346 for (var i = 0; i < 5; ++i) {
347 try {
348 func();
349 assertUnreachable();
350 } catch (e) {
351 assertInstanceof(e, ReferenceError);
352 }
353 }
354 %OptimizeFunctionOnNextCall(func);
355 try {
356 func();
357 assertUnreachable();
358 } catch (e) {
359 assertInstanceof(e, ReferenceError);
360 }
361}
362
363function TestFunctionContext(s) {
364 'use strict';
365 var func = eval("(function baz(){ " + s + "; (function() { x; }); })");
366 print("Testing:");
367 print(func);
368 for (var i = 0; i < 5; ++i) {
369 print(i);
370 try {
371 func();
372 assertUnreachable();
373 } catch (e) {
374 assertInstanceof(e, ReferenceError);
375 }
376 }
377 print("optimize");
378 %OptimizeFunctionOnNextCall(func);
379 try {
380 print("call");
381 func();
382 assertUnreachable();
383 } catch (e) {
384 print("catch");
385 assertInstanceof(e, ReferenceError);
386 }
387}
388
389function TestBlockLocal(s) {
390 'use strict';
391 var func = eval("(function baz(){ { " + s + "; } })");
392 print("Testing:");
393 print(func);
394 for (var i = 0; i < 5; ++i) {
395 try {
396 func();
397 assertUnreachable();
398 } catch (e) {
399 assertInstanceof(e, ReferenceError);
400 }
401 }
402 %OptimizeFunctionOnNextCall(func);
403 try {
404 func();
405 assertUnreachable();
406 } catch (e) {
407 assertInstanceof(e, ReferenceError);
408 }
409}
410
411function TestBlockContext(s) {
412 'use strict';
413 var func = eval("(function baz(){ { " + s + "; (function() { x; }); } })");
414 print("Testing:");
415 print(func);
416 for (var i = 0; i < 5; ++i) {
417 print(i);
418 try {
419 func();
420 assertUnreachable();
421 } catch (e) {
422 assertInstanceof(e, ReferenceError);
423 }
424 }
425 print("optimize");
426 %OptimizeFunctionOnNextCall(func);
427 try {
428 print("call");
429 func();
430 assertUnreachable();
431 } catch (e) {
432 print("catch");
433 assertInstanceof(e, ReferenceError);
434 }
435}
436
437function TestAll(s) {
438 TestFunctionLocal(s);
439 TestFunctionContext(s);
440 TestBlockLocal(s);
441 TestBlockContext(s);
442}
443
444// Use before initialization in declaration statement.
445TestAll('let x = x + 1');
446TestAll('let x = x += 1');
447TestAll('let x = x++');
448TestAll('let x = ++x');
449TestAll('const x = x + 1');
450
451// Use before initialization in prior statement.
452TestAll('x + 1; let x;');
453TestAll('x = 1; let x;');
454TestAll('x += 1; let x;');
455TestAll('++x; let x;');
456TestAll('x++; let x;');
457TestAll('let y = x; const x = 1;');
458
459
460function f(x) {
461 let y = x + 42;
462 return y;
463}
464
465function g(x) {
466 {
467 let y = x + 42;
468 return y;
469 }
470}
471
472for (var i=0; i<10; i++) {
473 f(i);
474 g(i);
475}
476
477%OptimizeFunctionOnNextCall(f);
478%OptimizeFunctionOnNextCall(g);
479
480f(12);
481g(12);
482
483assertTrue(%GetOptimizationStatus(f) != 2);
484assertTrue(%GetOptimizationStatus(g) != 2);