1 // 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: --harmony-scoping --allow-natives-syntax 29 30 // TODO(ES6): properly activate extended mode 31 "use strict"; 32 33 // Check that the following functions are optimizable. 34 var functions = [ f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, 35 f15, f16, f17, f18, f19, f20, f21, f22, f23 ]; 36 37 for (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 assertTrue(%GetOptimizationStatus(func) != 2); 47 } 48 49 function f1() { } 50 51 function f2(x) { } 52 53 function f3() { 54 let x; 55 } 56 57 function f4() { 58 function foo() { 59 } 60 } 61 62 function f5() { 63 let x = 1; 64 } 65 66 function f6() { 67 const x = 1; 68 } 69 70 function f7(x) { 71 return x; 72 } 73 74 function f8() { 75 let x; 76 return x; 77 } 78 79 function f9() { 80 function x() { 81 } 82 return x; 83 } 84 85 function f10(x) { 86 x = 1; 87 } 88 89 function f11() { 90 let x; 91 x = 1; 92 } 93 94 function f12() { 95 function x() {}; 96 x = 1; 97 } 98 99 function f13(x) { 100 (function() { x; }); 101 } 102 103 function f14() { 104 let x; 105 (function() { x; }); 106 } 107 108 function f15() { 109 function x() { 110 } 111 (function() { x; }); 112 } 113 114 function f16() { 115 let x = 1; 116 (function() { x; }); 117 } 118 119 function f17() { 120 const x = 1; 121 (function() { x; }); 122 } 123 124 function f18(x) { 125 return x; 126 (function() { x; }); 127 } 128 129 function f19() { 130 let x; 131 return x; 132 (function() { x; }); 133 } 134 135 function f20() { 136 function x() { 137 } 138 return x; 139 (function() { x; }); 140 } 141 142 function f21(x) { 143 x = 1; 144 (function() { x; }); 145 } 146 147 function f22() { 148 let x; 149 x = 1; 150 (function() { x; }); 151 } 152 153 function f23() { 154 function x() { } 155 x = 1; 156 (function() { x; }); 157 } 158 159 160 // Test that temporal dead zone semantics for function and block scoped 161 // let bindings are handled by the optimizing compiler. 162 163 function TestFunctionLocal(s) { 164 'use strict'; 165 var func = eval("(function baz(){" + s + "; })"); 166 print("Testing:"); 167 print(func); 168 for (var i = 0; i < 5; ++i) { 169 try { 170 func(); 171 assertUnreachable(); 172 } catch (e) { 173 assertInstanceof(e, ReferenceError); 174 } 175 } 176 %OptimizeFunctionOnNextCall(func); 177 try { 178 func(); 179 assertUnreachable(); 180 } catch (e) { 181 assertInstanceof(e, ReferenceError); 182 } 183 } 184 185 function TestFunctionContext(s) { 186 'use strict'; 187 var func = eval("(function baz(){ " + s + "; (function() { x; }); })"); 188 print("Testing:"); 189 print(func); 190 for (var i = 0; i < 5; ++i) { 191 print(i); 192 try { 193 func(); 194 assertUnreachable(); 195 } catch (e) { 196 assertInstanceof(e, ReferenceError); 197 } 198 } 199 print("optimize"); 200 %OptimizeFunctionOnNextCall(func); 201 try { 202 print("call"); 203 func(); 204 assertUnreachable(); 205 } catch (e) { 206 print("catch"); 207 assertInstanceof(e, ReferenceError); 208 } 209 } 210 211 function TestAll(s) { 212 TestFunctionLocal(s); 213 TestFunctionContext(s); 214 } 215 216 // Use before initialization in declaration statement. 217 TestAll('let x = x + 1'); 218 TestAll('let x = x += 1'); 219 TestAll('let x = x++'); 220 TestAll('let x = ++x'); 221 TestAll('const x = x + 1'); 222 223 // Use before initialization in prior statement. 224 TestAll('x + 1; let x;'); 225 TestAll('x = 1; let x;'); 226 TestAll('x += 1; let x;'); 227 TestAll('++x; let x;'); 228 TestAll('x++; let x;'); 229 TestAll('let y = x; const x = 1;'); 230 231 232 function f(x, b) { 233 let y = (b ? y : x) + 42; 234 return y; 235 } 236 237 function g(x, b) { 238 { 239 let y = (b ? y : x) + 42; 240 return y; 241 } 242 } 243 244 for (var i=0; i<10; i++) { 245 f(i, false); 246 g(i, false); 247 } 248 249 %OptimizeFunctionOnNextCall(f); 250 %OptimizeFunctionOnNextCall(g); 251 252 try { 253 f(42, true); 254 } catch (e) { 255 assertInstanceof(e, ReferenceError); 256 } 257 258 try { 259 g(42, true); 260 } catch (e) { 261 assertInstanceof(e, ReferenceError); 262 } 263