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