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