Home | History | Annotate | Download | only in es6
      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 "use strict";
     29 
     30 // We want to test the context chain shape.  In each of the tests cases
     31 // below, the outer with is to force a runtime lookup of the identifier 'x'
     32 // to actually verify that the inner context has been discarded.  A static
     33 // lookup of 'x' might accidentally succeed.
     34 
     35 {
     36   let x = 2;
     37   L: {
     38     let x = 3;
     39     assertEquals(3, x);
     40     break L;
     41     assertTrue(false);
     42   }
     43   assertEquals(2, x);
     44 }
     45 
     46 do {
     47   let x = 4;
     48   assertEquals(4,x);
     49   {
     50     let x = 5;
     51     assertEquals(5, x);
     52     continue;
     53     assertTrue(false);
     54   }
     55 } while (false);
     56 
     57 var caught = false;
     58 try {
     59   {
     60     let xx = 18;
     61     throw 25;
     62     assertTrue(false);
     63   }
     64 } catch (e) {
     65   caught = true;
     66   assertEquals(25, e);
     67   (function () {
     68     try {
     69       // NOTE: This checks that the block scope containing xx has been
     70       // removed from the context chain.
     71       eval('xx');
     72       assertTrue(false);  // should not reach here
     73     } catch (e2) {
     74       assertTrue(e2 instanceof ReferenceError);
     75     }
     76   })();
     77 }
     78 assertTrue(caught);
     79 
     80 
     81 (function(x) {
     82   label: {
     83     let x = 'inner';
     84     break label;
     85   }
     86   assertEquals('outer', eval('x'));
     87 })('outer');
     88 
     89 
     90 (function(x) {
     91   label: {
     92     let x = 'middle';
     93     {
     94       let x = 'inner';
     95       break label;
     96     }
     97   }
     98   assertEquals('outer', eval('x'));
     99 })('outer');
    100 
    101 
    102 (function(x) {
    103   for (var i = 0; i < 10; ++i) {
    104     let x = 'inner' + i;
    105     continue;
    106   }
    107   assertEquals('outer', eval('x'));
    108 })('outer');
    109 
    110 
    111 (function(x) {
    112   label: for (var i = 0; i < 10; ++i) {
    113     let x = 'middle' + i;
    114     for (var j = 0; j < 10; ++j) {
    115       let x = 'inner' + j;
    116       continue label;
    117     }
    118   }
    119   assertEquals('outer', eval('x'));
    120 })('outer');
    121 
    122 
    123 (function(x) {
    124   try {
    125     let x = 'inner';
    126     throw 0;
    127   } catch (e) {
    128     assertEquals('outer', eval('x'));
    129   }
    130 })('outer');
    131 
    132 
    133 (function(x) {
    134   try {
    135     let x = 'middle';
    136     {
    137       let x = 'inner';
    138       throw 0;
    139     }
    140   } catch (e) {
    141     assertEquals('outer', eval('x'));
    142   }
    143 })('outer');
    144 
    145 
    146 try {
    147   (function(x) {
    148     try {
    149       let x = 'inner';
    150       throw 0;
    151     } finally {
    152       assertEquals('outer', eval('x'));
    153     }
    154   })('outer');
    155 } catch (e) {
    156   if (e instanceof MjsUnitAssertionError) throw e;
    157 }
    158 
    159 
    160 try {
    161   (function(x) {
    162     try {
    163       let x = 'middle';
    164       {
    165         let x = 'inner';
    166         throw 0;
    167       }
    168     } finally {
    169       assertEquals('outer', eval('x'));
    170     }
    171   })('outer');
    172 } catch (e) {
    173   if (e instanceof MjsUnitAssertionError) throw e;
    174 }
    175 
    176 
    177 // Verify that the context is correctly set in the stack frame after exiting
    178 // from eval.
    179 function f() {}
    180 
    181 (function(x) {
    182   label: {
    183     let x = 'inner';
    184     break label;
    185   }
    186   f();  // The context could be restored from the stack after the call.
    187   assertEquals('outer', eval('x'));
    188 })('outer');
    189 
    190 
    191 (function(x) {
    192   for (var i = 0; i < 10; ++i) {
    193     let x = 'inner';
    194     continue;
    195   }
    196   f();
    197   assertEquals('outer', eval('x'));
    198 })('outer');
    199 
    200 
    201 (function(x) {
    202   try {
    203     let x = 'inner';
    204     throw 0;
    205   } catch (e) {
    206     f();
    207     assertEquals('outer', eval('x'));
    208   }
    209 })('outer');
    210 
    211 
    212 try {
    213   (function(x) {
    214     try {
    215       let x = 'inner';
    216       throw 0;
    217     } finally {
    218       f();
    219       assertEquals('outer', eval('x'));
    220     }
    221   })('outer');
    222 } catch (e) {
    223   if (e instanceof MjsUnitAssertionError) throw e;
    224 }
    225