| // Copyright 2011 the V8 project authors. All rights reserved. |
| // Redistribution and use in source and binary forms, with or without |
| // modification, are permitted provided that the following conditions are |
| // met: |
| // |
| // * Redistributions of source code must retain the above copyright |
| // notice, this list of conditions and the following disclaimer. |
| // * Redistributions in binary form must reproduce the above |
| // copyright notice, this list of conditions and the following |
| // disclaimer in the documentation and/or other materials provided |
| // with the distribution. |
| // * Neither the name of Google Inc. nor the names of its |
| // contributors may be used to endorse or promote products derived |
| // from this software without specific prior written permission. |
| // |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| // Flags: --harmony-scoping --allow-natives-syntax |
| |
| // TODO(ES6): properly activate extended mode |
| "use strict"; |
| |
| // Check that the following functions are optimizable. |
| var functions = [ f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, |
| f15, f16, f17, f18, f19, f20, f21, f22, f23 ]; |
| |
| for (var i = 0; i < functions.length; ++i) { |
| var func = functions[i]; |
| print("Testing:"); |
| print(func); |
| for (var j = 0; j < 10; ++j) { |
| func(12); |
| } |
| %OptimizeFunctionOnNextCall(func); |
| func(12); |
| assertTrue(%GetOptimizationStatus(func) != 2); |
| } |
| |
| function f1() { } |
| |
| function f2(x) { } |
| |
| function f3() { |
| let x; |
| } |
| |
| function f4() { |
| function foo() { |
| } |
| } |
| |
| function f5() { |
| let x = 1; |
| } |
| |
| function f6() { |
| const x = 1; |
| } |
| |
| function f7(x) { |
| return x; |
| } |
| |
| function f8() { |
| let x; |
| return x; |
| } |
| |
| function f9() { |
| function x() { |
| } |
| return x; |
| } |
| |
| function f10(x) { |
| x = 1; |
| } |
| |
| function f11() { |
| let x; |
| x = 1; |
| } |
| |
| function f12() { |
| function x() {}; |
| x = 1; |
| } |
| |
| function f13(x) { |
| (function() { x; }); |
| } |
| |
| function f14() { |
| let x; |
| (function() { x; }); |
| } |
| |
| function f15() { |
| function x() { |
| } |
| (function() { x; }); |
| } |
| |
| function f16() { |
| let x = 1; |
| (function() { x; }); |
| } |
| |
| function f17() { |
| const x = 1; |
| (function() { x; }); |
| } |
| |
| function f18(x) { |
| return x; |
| (function() { x; }); |
| } |
| |
| function f19() { |
| let x; |
| return x; |
| (function() { x; }); |
| } |
| |
| function f20() { |
| function x() { |
| } |
| return x; |
| (function() { x; }); |
| } |
| |
| function f21(x) { |
| x = 1; |
| (function() { x; }); |
| } |
| |
| function f22() { |
| let x; |
| x = 1; |
| (function() { x; }); |
| } |
| |
| function f23() { |
| function x() { } |
| x = 1; |
| (function() { x; }); |
| } |
| |
| |
| // Test that temporal dead zone semantics for function and block scoped |
| // let bindings are handled by the optimizing compiler. |
| |
| function TestFunctionLocal(s) { |
| 'use strict'; |
| var func = eval("(function baz(){" + s + "; })"); |
| print("Testing:"); |
| print(func); |
| for (var i = 0; i < 5; ++i) { |
| try { |
| func(); |
| assertUnreachable(); |
| } catch (e) { |
| assertInstanceof(e, ReferenceError); |
| } |
| } |
| %OptimizeFunctionOnNextCall(func); |
| try { |
| func(); |
| assertUnreachable(); |
| } catch (e) { |
| assertInstanceof(e, ReferenceError); |
| } |
| } |
| |
| function TestFunctionContext(s) { |
| 'use strict'; |
| var func = eval("(function baz(){ " + s + "; (function() { x; }); })"); |
| print("Testing:"); |
| print(func); |
| for (var i = 0; i < 5; ++i) { |
| print(i); |
| try { |
| func(); |
| assertUnreachable(); |
| } catch (e) { |
| assertInstanceof(e, ReferenceError); |
| } |
| } |
| print("optimize"); |
| %OptimizeFunctionOnNextCall(func); |
| try { |
| print("call"); |
| func(); |
| assertUnreachable(); |
| } catch (e) { |
| print("catch"); |
| assertInstanceof(e, ReferenceError); |
| } |
| } |
| |
| function TestAll(s) { |
| TestFunctionLocal(s); |
| TestFunctionContext(s); |
| } |
| |
| // Use before initialization in declaration statement. |
| TestAll('let x = x + 1'); |
| TestAll('let x = x += 1'); |
| TestAll('let x = x++'); |
| TestAll('let x = ++x'); |
| TestAll('const x = x + 1'); |
| |
| // Use before initialization in prior statement. |
| TestAll('x + 1; let x;'); |
| TestAll('x = 1; let x;'); |
| TestAll('x += 1; let x;'); |
| TestAll('++x; let x;'); |
| TestAll('x++; let x;'); |
| TestAll('let y = x; const x = 1;'); |
| |
| |
| function f(x, b) { |
| let y = (b ? y : x) + 42; |
| return y; |
| } |
| |
| function g(x, b) { |
| { |
| let y = (b ? y : x) + 42; |
| return y; |
| } |
| } |
| |
| for (var i=0; i<10; i++) { |
| f(i, false); |
| g(i, false); |
| } |
| |
| %OptimizeFunctionOnNextCall(f); |
| %OptimizeFunctionOnNextCall(g); |
| |
| try { |
| f(42, true); |
| } catch (e) { |
| assertInstanceof(e, ReferenceError); |
| } |
| |
| try { |
| g(42, true); |
| } catch (e) { |
| assertInstanceof(e, ReferenceError); |
| } |