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