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 |
index a17a4c0799c7d9bced58941597f0b150f532ee7b..ff895d5b8a24d44b0bf7c8f53a82ffb960eb7c47 100644 |
--- a/test/mjsunit/harmony/block-sloppy-function.js |
+++ b/test/mjsunit/harmony/block-sloppy-function.js |
@@ -146,13 +146,6 @@ |
assertEquals(2, f()); |
})(); |
-// Test that hoisting from blocks doesn't happen in global scope |
-function globalUnhoisted() { return 0; } |
-{ |
- function globalUnhoisted() { return 1; } |
-} |
-assertEquals(0, globalUnhoisted()); |
- |
// Test that shadowing arguments is fine |
(function shadowArguments(x) { |
assertArrayEquals([1], arguments); |
@@ -201,3 +194,109 @@ assertThrows(function notInDefaultScope(x = y) { |
assertEquals('function', typeof y); |
assertEquals(x, undefined); |
}, ReferenceError); |
+ |
+// Test that hoisting from blocks does happen in global scope |
+function globalHoisted() { return 0; } |
+{ |
+ function globalHoisted() { return 1; } |
+} |
+assertEquals(1, globalHoisted()); |
+ |
+// Also happens when not previously defined |
+assertEquals(undefined, globalUndefinedHoisted); |
+{ |
+ function globalUndefinedHoisted() { return 1; } |
+} |
+assertEquals(1, globalUndefinedHoisted()); |
+var globalUndefinedHoistedDescriptor = |
+ Object.getOwnPropertyDescriptor(this, "globalUndefinedHoisted"); |
+assertFalse(globalUndefinedHoistedDescriptor.configurable); |
+assertTrue(globalUndefinedHoistedDescriptor.writable); |
+assertTrue(globalUndefinedHoistedDescriptor.enumerable); |
+assertEquals(1, globalUndefinedHoistedDescriptor.value()); |
+ |
+// When a function property is hoisted, it should be |
+// made enumerable. |
+// BUG(v8:4451) |
+Object.defineProperty(this, "globalNonEnumerable", { |
+ value: false, |
+ configurable: true, |
+ writable: true, |
+ enumerable: false |
+}); |
+eval("{function globalNonEnumerable() { return 1; }}"); |
+var globalNonEnumerableDescriptor |
+ = Object.getOwnPropertyDescriptor(this, "globalNonEnumerable"); |
+// BUG(v8:4451): Should be made non-configurable |
+assertTrue(globalNonEnumerableDescriptor.configurable); |
+assertTrue(globalNonEnumerableDescriptor.writable); |
+// BUG(v8:4451): Should be made enumerable |
+assertFalse(globalNonEnumerableDescriptor.enumerable); |
+assertEquals(1, globalNonEnumerableDescriptor.value()); |
+ |
+// When a function property is hoisted, it should be overwritten and |
+// made writable and overwritten, even if the property was non-writable. |
+Object.defineProperty(this, "globalNonWritable", { |
+ value: false, |
+ configurable: true, |
+ writable: false, |
+ enumerable: true |
+}); |
+eval("{function globalNonWritable() { return 1; }}"); |
+var globalNonWritableDescriptor |
+ = Object.getOwnPropertyDescriptor(this, "globalNonWritable"); |
+// BUG(v8:4451): Should be made non-configurable |
+assertTrue(globalNonWritableDescriptor.configurable); |
+// BUG(v8:4451): Should be made writable |
+assertFalse(globalNonWritableDescriptor.writable); |
+assertFalse(globalNonEnumerableDescriptor.enumerable); |
+// BUG(v8:4451): Should be overwritten |
+assertEquals(false, globalNonWritableDescriptor.value); |
+ |
+// Test that hoisting from blocks does happen in an eval |
+eval(` |
+ function evalHoisted() { return 0; } |
+ { |
+ function evalHoisted() { return 1; } |
+ } |
+ assertEquals(1, evalHoisted()); |
+`); |
+ |
+// Test that hoisting from blocks happens from eval in a function |
+!function() { |
+ eval(` |
+ function evalInFunctionHoisted() { return 0; } |
+ { |
+ function evalInFunctionHoisted() { return 1; } |
+ } |
+ assertEquals(1, evalInFunctionHoisted()); |
+ `); |
+}(); |
+ |
+let dontHoistGlobal; |
+{ function dontHoistGlobal() {} } |
+assertEquals(undefined, dontHoistGlobal); |
+ |
+let dontHoistEval; |
+// BUG(v8:) This shouldn't hoist and shouldn't throw |
+var throws = false; |
+try { |
+ eval("{ function dontHoistEval() {} }"); |
+} catch (e) { |
+ throws = true; |
+} |
+assertTrue(throws); |
+ |
+// When the global object is frozen, silently don't hoist |
+// Currently this actually throws BUG(v8:4452) |
+Object.freeze(this); |
+throws = false; |
+try { |
+ eval('{ function hoistWhenFrozen() {} }'); |
+} catch (e) { |
+ throws = true; |
+} |
+assertFalse(this.hasOwnProperty("hoistWhenFrozen")); |
+assertThrows(() => hoistWhenFrozen, ReferenceError); |
+// Should be assertFalse BUG(v8:4452) |
+assertTrue(throws); |