169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// Copyright 2011 the V8 project authors. All rights reserved. 269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// Redistribution and use in source and binary forms, with or without 369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// modification, are permitted provided that the following conditions are 469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// met: 569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// 669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// * Redistributions of source code must retain the above copyright 769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// notice, this list of conditions and the following disclaimer. 869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// * Redistributions in binary form must reproduce the above 969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// copyright notice, this list of conditions and the following 1069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// disclaimer in the documentation and/or other materials provided 1169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// with the distribution. 1269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// * Neither the name of Google Inc. nor the names of its 1369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// contributors may be used to endorse or promote products derived 1469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// from this software without specific prior written permission. 1569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// 1669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Flags: --harmony-scoping 293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// TODO(ES6): properly activate extended mode 313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch"use strict"; 3269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 3369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// Test temporal dead zone semantics of let bound variables in 3469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// function and block scopes. 3569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 3669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochfunction TestFunctionLocal(s) { 3769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch try { 3869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch eval("(function(){" + s + "; })")(); 3969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } catch (e) { 4069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch assertInstanceof(e, ReferenceError); 4169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return; 4269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 4369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch assertUnreachable(); 4469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 4569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 4669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochfunction TestBlockLocal(s,e) { 4769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch try { 4869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch eval("(function(){ {" + s + ";} })")(); 4969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } catch (e) { 5069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch assertInstanceof(e, ReferenceError); 5169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return; 5269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 5369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch assertUnreachable(); 5469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 5569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 5669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 5769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochfunction TestAll(s) { 5869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch TestBlockLocal(s); 5969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch TestFunctionLocal(s); 6069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 6169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 6269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// Use before initialization in declaration statement. 6369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTestAll('let x = x + 1'); 6469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTestAll('let x = x += 1'); 6569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTestAll('let x = x++'); 6669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTestAll('let x = ++x'); 673ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTestAll('const x = x + 1'); 6869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 6969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// Use before initialization in prior statement. 7069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTestAll('x + 1; let x;'); 7169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTestAll('x = 1; let x;'); 7269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTestAll('x += 1; let x;'); 7369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTestAll('++x; let x;'); 7469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTestAll('x++; let x;'); 753ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTestAll('let y = x; const x = 1;'); 7669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 7769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTestAll('f(); let x; function f() { return x + 1; }'); 7869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTestAll('f(); let x; function f() { x = 1; }'); 7969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTestAll('f(); let x; function f() { x += 1; }'); 8069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTestAll('f(); let x; function f() { ++x; }'); 8169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTestAll('f(); let x; function f() { x++; }'); 823ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTestAll('f(); const x = 1; function f() { return x; }'); 8369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 8469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTestAll('f()(); let x; function f() { return function() { return x + 1; } }'); 8569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTestAll('f()(); let x; function f() { return function() { x = 1; } }'); 8669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTestAll('f()(); let x; function f() { return function() { x += 1; } }'); 8769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTestAll('f()(); let x; function f() { return function() { ++x; } }'); 8869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTestAll('f()(); let x; function f() { return function() { x++; } }'); 893ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTestAll('f()(); const x = 1; function f() { return function() { return x; } }'); 9069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Use before initialization with a dynamic lookup. 9269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTestAll('eval("x + 1;"); let x;'); 9369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTestAll('eval("x = 1;"); let x;'); 9469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTestAll('eval("x += 1;"); let x;'); 9569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTestAll('eval("++x;"); let x;'); 9669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTestAll('eval("x++;"); let x;'); 973ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTestAll('eval("x"); const x = 1;'); 983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Use before initialization with check for eval-shadowed bindings. 1003ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTestAll('function f() { eval("var y = 2;"); x + 1; }; f(); let x;'); 1013ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTestAll('function f() { eval("var y = 2;"); x = 1; }; f(); let x;'); 1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTestAll('function f() { eval("var y = 2;"); x += 1; }; f(); let x;'); 1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTestAll('function f() { eval("var y = 2;"); ++x; }; f(); let x;'); 1043ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTestAll('function f() { eval("var y = 2;"); x++; }; f(); let x;'); 10569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 10669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// Test that variables introduced by function declarations are created and 10769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// initialized upon entering a function / block scope. 10869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochfunction f() { 10969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch { 11069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch assertEquals(2, g1()); 11169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch assertEquals(2, eval("g1()")); 11269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 11369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // block scoped function declaration 11469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch function g1() { 11569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return 2; 11669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 11769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 11869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 11969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch assertEquals(3, g2()); 12069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch assertEquals(3, eval("g2()")); 12169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // function scoped function declaration 12269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch function g2() { 12369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return 3; 12469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 12569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 12669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochf(); 12769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 12869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// Test that a function declaration introduces a block scoped variable. 12969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTestAll('{ function k() { return 0; } }; k(); '); 13069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 13169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// Test that a function declaration sees the scope it resides in. 13269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochfunction f2() { 1333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch let m, n, o, p; 13469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch { 13569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch m = g; 13669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch function g() { 13769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return a; 13869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 13969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch let a = 1; 14069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 14169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch assertEquals(1, m()); 14269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 14369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch try { 14469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch throw 2; 14569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } catch(b) { 14669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch n = h; 14769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch function h() { 14869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return b + c; 14969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 1503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch let c = 3; 15169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 15269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch assertEquals(5, n()); 1533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { 1553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch o = i; 1563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch function i() { 1573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return d; 1583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch let d = 4; 1603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch assertEquals(4, o()); 1623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch try { 1643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch throw 5; 1653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } catch(e) { 1663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p = j; 1673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch function j() { 1683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return e + f; 1693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch let f = 6; 1713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch assertEquals(11, p()); 1733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 1743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochf2(); 1753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Test that resolution of let bound variables works with scopes that call eval. 1773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction outer() { 1783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch function middle() { 1793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch function inner() { 1803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return x; 1813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch eval("1 + 1"); 1833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return x + inner(); 1843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch let x = 1; 1873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return middle(); 18869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 1893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1903ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochassertEquals(2, outer()); 191