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 --harmony-scoping 29 // Test functionality of block scopes. 30 31 // TODO(ES6): properly activate extended mode 32 "use strict"; 33 34 // Hoisting of var declarations. 35 function f1() { 36 { 37 var x = 1; 38 var y; 39 } 40 assertEquals(1, x) 41 assertEquals(undefined, y) 42 } 43 f1(); 44 45 46 // Dynamic lookup in and through block contexts. 47 function f2(one) { 48 var x = one + 1; 49 let y = one + 2; 50 const u = one + 4; 51 { 52 let z = one + 3; 53 const v = one + 5; 54 assertEquals(1, eval('one')); 55 assertEquals(2, eval('x')); 56 assertEquals(3, eval('y')); 57 assertEquals(4, eval('z')); 58 assertEquals(5, eval('u')); 59 assertEquals(6, eval('v')); 60 } 61 } 62 f2(1); 63 64 65 // Lookup in and through block contexts. 66 function f3(one) { 67 var x = one + 1; 68 let y = one + 2; 69 const u = one + 4; 70 { 71 let z = one + 3; 72 const v = one + 5; 73 assertEquals(1, one); 74 assertEquals(2, x); 75 assertEquals(3, y); 76 assertEquals(4, z); 77 assertEquals(5, u); 78 assertEquals(6, v); 79 80 } 81 } 82 f3(1); 83 84 85 // Dynamic lookup from closure. 86 function f4(one) { 87 var x = one + 1; 88 let y = one + 2; 89 const u = one + 4; 90 { 91 let z = one + 3; 92 const v = one + 5; 93 function f() { 94 assertEquals(1, eval('one')); 95 assertEquals(2, eval('x')); 96 assertEquals(3, eval('y')); 97 assertEquals(4, eval('z')); 98 assertEquals(5, eval('u')); 99 assertEquals(6, eval('v')); 100 }; 101 } 102 } 103 f4(1); 104 105 106 // Lookup from closure. 107 function f5(one) { 108 var x = one + 1; 109 let y = one + 2; 110 const u = one + 4; 111 { 112 let z = one + 3; 113 const v = one + 5; 114 function f() { 115 assertEquals(1, one); 116 assertEquals(2, x); 117 assertEquals(3, y); 118 assertEquals(4, z); 119 assertEquals(5, u); 120 assertEquals(6, v); 121 }; 122 } 123 } 124 f5(1); 125 126 127 // Return from block. 128 function f6() { 129 let x = 1; 130 const u = 3; 131 { 132 let y = 2; 133 const v = 4; 134 return x + y; 135 } 136 } 137 assertEquals(3, f6(6)); 138 139 140 // Variable shadowing and lookup. 141 function f7(a) { 142 let b = 1; 143 var c = 1; 144 var d = 1; 145 const e = 1; 146 { // let variables shadowing argument, let, const and var variables 147 let a = 2; 148 let b = 2; 149 let c = 2; 150 let e = 2; 151 assertEquals(2,a); 152 assertEquals(2,b); 153 assertEquals(2,c); 154 assertEquals(2,e); 155 } 156 { // const variables shadowing argument, let, const and var variables 157 const a = 2; 158 const b = 2; 159 const c = 2; 160 const e = 2; 161 assertEquals(2,a); 162 assertEquals(2,b); 163 assertEquals(2,c); 164 assertEquals(2,e); 165 } 166 try { 167 throw 'stuff1'; 168 } catch (a) { 169 assertEquals('stuff1',a); 170 // catch variable shadowing argument 171 a = 2; 172 assertEquals(2,a); 173 { 174 // let variable shadowing catch variable 175 let a = 3; 176 assertEquals(3,a); 177 try { 178 throw 'stuff2'; 179 } catch (a) { 180 assertEquals('stuff2',a); 181 // catch variable shadowing let variable 182 a = 4; 183 assertEquals(4,a); 184 } 185 assertEquals(3,a); 186 } 187 assertEquals(2,a); 188 } 189 try { 190 throw 'stuff3'; 191 } catch (c) { 192 // catch variable shadowing var variable 193 assertEquals('stuff3',c); 194 { 195 // const variable shadowing catch variable 196 const c = 3; 197 assertEquals(3,c); 198 } 199 assertEquals('stuff3',c); 200 try { 201 throw 'stuff4'; 202 } catch(c) { 203 assertEquals('stuff4',c); 204 // catch variable shadowing catch variable 205 c = 3; 206 assertEquals(3,c); 207 } 208 (function(c) { 209 // argument shadowing catch variable 210 c = 3; 211 assertEquals(3,c); 212 })(); 213 assertEquals('stuff3', c); 214 (function() { 215 // var variable shadowing catch variable 216 var c = 3; 217 })(); 218 assertEquals('stuff3', c); 219 c = 2; 220 } 221 assertEquals(1,c); 222 (function(a,b,c,e) { 223 // arguments shadowing argument, let, const and var variable 224 a = 2; 225 b = 2; 226 c = 2; 227 e = 2; 228 assertEquals(2,a); 229 assertEquals(2,b); 230 assertEquals(2,c); 231 assertEquals(2,e); 232 // var variable shadowing var variable 233 var d = 2; 234 })(1,1); 235 assertEquals(1,a); 236 assertEquals(1,b); 237 assertEquals(1,c); 238 assertEquals(1,d); 239 assertEquals(1,e); 240 } 241 f7(1); 242 243 244 // Ensure let and const variables are block local 245 // and var variables function local. 246 function f8() { 247 var let_accessors = []; 248 var var_accessors = []; 249 var const_accessors = []; 250 for (var i = 0; i < 10; i++) { 251 let x = i; 252 var y = i; 253 const z = i; 254 let_accessors[i] = function() { return x; } 255 var_accessors[i] = function() { return y; } 256 const_accessors[i] = function() { return z; } 257 } 258 for (var j = 0; j < 10; j++) { 259 y = j + 10; 260 assertEquals(j, let_accessors[j]()); 261 assertEquals(y, var_accessors[j]()); 262 assertEquals(j, const_accessors[j]()); 263 } 264 } 265 f8(); 266