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