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