 Chromium Code Reviews
 Chromium Code Reviews Issue 1332873003:
  Implement sloppy-mode block-defined functions (Annex B 3.3)  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master
    
  
    Issue 1332873003:
  Implement sloppy-mode block-defined functions (Annex B 3.3)  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master| Index: test/mjsunit/harmony/block-sloppy-function.js | 
| diff --git a/test/mjsunit/harmony/block-sloppy-function.js b/test/mjsunit/harmony/block-sloppy-function.js | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..19d6735e6fe483ef00a7f2481b7360d46bc28c3a | 
| --- /dev/null | 
| +++ b/test/mjsunit/harmony/block-sloppy-function.js | 
| @@ -0,0 +1,152 @@ | 
| +// Copyright 2015 the V8 project authors. All rights reserved. | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +// Flags: --no-legacy-const --harmony-sloppy --harmony-sloppy-let --harmony-sloppy-function | 
| 
adamk
2015/09/11 15:42:56
You can have multiple "Flags:" lines to keep this
 
Dan Ehrenberg
2015/09/17 17:44:10
Done
 | 
| + | 
| +// Test Annex B 3.3 semantics for functions declared in blocks in sloppy mode. | 
| 
adamk
2015/09/11 15:42:56
Can you add tests for shadowing function params, b
 
Dan Ehrenberg
2015/09/17 18:10:27
Added tests. As you predicted, one of them fails,
 | 
| +// http://www.ecma-international.org/ecma-262/6.0/#sec-block-level-function-declarations-web-legacy-compatibility-semantics | 
| + | 
| +(function overridingLocalFunction() { | 
| + var x = []; | 
| + assertEquals('function', typeof f); | 
| + function f() { | 
| + x.push(1); | 
| + } | 
| + f(); | 
| + { | 
| + f(); | 
| + function f() { | 
| + x.push(2); | 
| + } | 
| + f(); | 
| + } | 
| + f(); | 
| + { | 
| + f(); | 
| + function f() { | 
| + x.push(3); | 
| + } | 
| + f(); | 
| + } | 
| + f(); | 
| + assertArrayEquals([1, 2, 2, 2, 3, 3, 3], x); | 
| +})(); | 
| + | 
| +(function newFunctionBinding() { | 
| + var x = []; | 
| + assertEquals('undefined', typeof f); | 
| + { | 
| + f(); | 
| + function f() { | 
| + x.push(2); | 
| + } | 
| + f(); | 
| + } | 
| + f(); | 
| + { | 
| + f(); | 
| + function f() { | 
| + x.push(3); | 
| + } | 
| + f(); | 
| + } | 
| + f(); | 
| + assertArrayEquals([2, 2, 2, 3, 3, 3], x); | 
| +})(); | 
| + | 
| +(function shadowingLetDoesntBind() { | 
| + let f = 1; | 
| + assertEquals(1, f); | 
| + { | 
| + let y = 3; | 
| + function f() { | 
| + y = 2; | 
| + } | 
| + f(); | 
| + assertEquals(2, y); | 
| + } | 
| + assertEquals(1, f); | 
| +})(); | 
| + | 
| +(function shadowingClassDoesntBind() { | 
| + class f { } | 
| + assertEquals('class f { }', f.toString()); | 
| + { | 
| + let y = 3; | 
| + function f() { | 
| + y = 2; | 
| + } | 
| + f(); | 
| + assertEquals(2, y); | 
| + } | 
| + assertEquals('class f { }', f.toString()); | 
| +})(); | 
| + | 
| +(function shadowingConstDoesntBind() { | 
| + const f = 1; | 
| + assertEquals(1, f); | 
| + { | 
| + let y = 3; | 
| + function f() { | 
| + y = 2; | 
| + } | 
| + f(); | 
| + assertEquals(2, y); | 
| + } | 
| + assertEquals(1, f); | 
| +})(); | 
| + | 
| +(function shadowingVarBinds() { | 
| + var f = 1; | 
| + assertEquals(1, f); | 
| + { | 
| + let y = 3; | 
| + function f() { | 
| + y = 2; | 
| + } | 
| + f(); | 
| + assertEquals(2, y); | 
| + } | 
| + assertEquals('function', typeof f); | 
| +})(); | 
| + | 
| +(function conditional() { | 
| + if (true) { | 
| + function f() { return 1; } | 
| + } else { | 
| + function f() { return 2; } | 
| + } | 
| + assertEquals(1, f()); | 
| + | 
| + if (false) { | 
| + function g() { return 1; } | 
| + } else { | 
| + function g() { return 2; } | 
| + } | 
| + assertEquals(2, g()); | 
| +})(); | 
| + | 
| +(function skipExecution() { | 
| + { | 
| + function f() { return 1; } | 
| + } | 
| + assertEquals(1, f()); | 
| + { | 
| + function f() { return 2; } | 
| + } | 
| + assertEquals(2, f()); | 
| + L: { | 
| + assertEquals(3, f()); | 
| + break L; | 
| + function f() { return 3; } | 
| + } | 
| + assertEquals(2, f()); | 
| +})(); | 
| + | 
| +// Test that hoisting from blocks doesn't happen in global scope | 
| 
adamk
2015/09/11 15:42:56
How is this effect achieved?
 
Dan Ehrenberg
2015/09/17 17:44:10
By 'global' I meant 'not in a function'. This is t
 | 
| +function globalUnhoisted() { return 0; } | 
| +{ | 
| + function globalUnhoisted() { return 1; } | 
| +} | 
| +assertEquals(0, globalUnhoisted()); |