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