| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 // Copyright 2015 the V8 project authors. All rights reserved. |  | 
| 2 // Use of this source code is governed by a BSD-style license that can be |  | 
| 3 // found in the LICENSE file. |  | 
| 4 |  | 
| 5 // Flags: --harmony-sloppy --harmony-sloppy-let |  | 
| 6 // Flags: --harmony-sloppy-function |  | 
| 7 |  | 
| 8 // Test Annex B 3.3 semantics for functions declared in blocks in sloppy mode. |  | 
| 9 // http://www.ecma-international.org/ecma-262/6.0/#sec-block-level-function-decl
     arations-web-legacy-compatibility-semantics |  | 
| 10 |  | 
| 11 (function overridingLocalFunction() { |  | 
| 12   var x = []; |  | 
| 13   assertEquals('function', typeof f); |  | 
| 14   function f() { |  | 
| 15     x.push(1); |  | 
| 16   } |  | 
| 17   f(); |  | 
| 18   { |  | 
| 19     f(); |  | 
| 20     function f() { |  | 
| 21       x.push(2); |  | 
| 22     } |  | 
| 23     f(); |  | 
| 24   } |  | 
| 25   f(); |  | 
| 26   { |  | 
| 27     f(); |  | 
| 28     function f() { |  | 
| 29       x.push(3); |  | 
| 30     } |  | 
| 31     f(); |  | 
| 32   } |  | 
| 33   f(); |  | 
| 34   assertArrayEquals([1, 2, 2, 2, 3, 3, 3], x); |  | 
| 35 })(); |  | 
| 36 |  | 
| 37 (function newFunctionBinding() { |  | 
| 38   var x = []; |  | 
| 39   assertEquals('undefined', typeof f); |  | 
| 40   { |  | 
| 41     f(); |  | 
| 42     function f() { |  | 
| 43       x.push(2); |  | 
| 44     } |  | 
| 45     f(); |  | 
| 46   } |  | 
| 47   f(); |  | 
| 48   { |  | 
| 49     f(); |  | 
| 50     function f() { |  | 
| 51       x.push(3); |  | 
| 52     } |  | 
| 53     f(); |  | 
| 54   } |  | 
| 55   f(); |  | 
| 56   assertArrayEquals([2, 2, 2, 3, 3, 3], x); |  | 
| 57 })(); |  | 
| 58 |  | 
| 59 (function shadowingLetDoesntBind() { |  | 
| 60   let f = 1; |  | 
| 61   assertEquals(1, f); |  | 
| 62   { |  | 
| 63     let y = 3; |  | 
| 64     function f() { |  | 
| 65       y = 2; |  | 
| 66     } |  | 
| 67     f(); |  | 
| 68     assertEquals(2, y); |  | 
| 69   } |  | 
| 70   assertEquals(1, f); |  | 
| 71 })(); |  | 
| 72 |  | 
| 73 (function shadowingClassDoesntBind() { |  | 
| 74   class f { } |  | 
| 75   assertEquals('class f { }', f.toString()); |  | 
| 76   { |  | 
| 77     let y = 3; |  | 
| 78     function f() { |  | 
| 79       y = 2; |  | 
| 80     } |  | 
| 81     f(); |  | 
| 82     assertEquals(2, y); |  | 
| 83   } |  | 
| 84   assertEquals('class f { }', f.toString()); |  | 
| 85 })(); |  | 
| 86 |  | 
| 87 (function shadowingConstDoesntBind() { |  | 
| 88   const f = 1; |  | 
| 89   assertEquals(1, f); |  | 
| 90   { |  | 
| 91     let y = 3; |  | 
| 92     function f() { |  | 
| 93       y = 2; |  | 
| 94     } |  | 
| 95     f(); |  | 
| 96     assertEquals(2, y); |  | 
| 97   } |  | 
| 98   assertEquals(1, f); |  | 
| 99 })(); |  | 
| 100 |  | 
| 101 (function shadowingVarBinds() { |  | 
| 102   var f = 1; |  | 
| 103   assertEquals(1, f); |  | 
| 104   { |  | 
| 105     let y = 3; |  | 
| 106     function f() { |  | 
| 107       y = 2; |  | 
| 108     } |  | 
| 109     f(); |  | 
| 110     assertEquals(2, y); |  | 
| 111   } |  | 
| 112   assertEquals('function', typeof f); |  | 
| 113 })(); |  | 
| 114 |  | 
| 115 (function conditional() { |  | 
| 116   if (true) { |  | 
| 117     function f() { return 1; } |  | 
| 118   } else { |  | 
| 119     function f() { return 2; } |  | 
| 120   } |  | 
| 121   assertEquals(1, f()); |  | 
| 122 |  | 
| 123   if (false) { |  | 
| 124     function g() { return 1; } |  | 
| 125   } else { |  | 
| 126     function g() { return 2; } |  | 
| 127   } |  | 
| 128   assertEquals(2, g()); |  | 
| 129 })(); |  | 
| 130 |  | 
| 131 (function skipExecution() { |  | 
| 132   { |  | 
| 133     function f() { return 1; } |  | 
| 134   } |  | 
| 135   assertEquals(1, f()); |  | 
| 136   { |  | 
| 137     function f() { return 2; } |  | 
| 138   } |  | 
| 139   assertEquals(2, f()); |  | 
| 140   L: { |  | 
| 141     assertEquals(3, f()); |  | 
| 142     break L; |  | 
| 143     function f() { return 3; } |  | 
| 144   } |  | 
| 145   assertEquals(2, f()); |  | 
| 146 })(); |  | 
| 147 |  | 
| 148 // Test that shadowing arguments is fine |  | 
| 149 (function shadowArguments(x) { |  | 
| 150   assertArrayEquals([1], arguments); |  | 
| 151   { |  | 
| 152     assertEquals('function', typeof arguments); |  | 
| 153     function arguments() {} |  | 
| 154     assertEquals('function', typeof arguments); |  | 
| 155   } |  | 
| 156   assertEquals('function', typeof arguments); |  | 
| 157 })(1); |  | 
| 158 |  | 
| 159 // Shadow function parameter |  | 
| 160 (function shadowParameter(x) { |  | 
| 161   assertEquals(1, x); |  | 
| 162   { |  | 
| 163     function x() {} |  | 
| 164   } |  | 
| 165   assertEquals('function', typeof x); |  | 
| 166 })(1); |  | 
| 167 |  | 
| 168 // Shadow function parameter |  | 
| 169 (function shadowDefaultParameter(x = 0) { |  | 
| 170   assertEquals(1, x); |  | 
| 171   { |  | 
| 172     function x() {} |  | 
| 173   } |  | 
| 174   // TODO(littledan): Once destructured parameters are no longer |  | 
| 175   // let-bound, enable this assertion. This is the core of the test. |  | 
| 176   // assertEquals('function', typeof x); |  | 
| 177 })(1); |  | 
| 178 |  | 
| 179 (function shadowRestParameter(...x) { |  | 
| 180   assertArrayEquals([1], x); |  | 
| 181   { |  | 
| 182     function x() {} |  | 
| 183   } |  | 
| 184   // TODO(littledan): Once destructured parameters are no longer |  | 
| 185   // let-bound, enable this assertion. This is the core of the test. |  | 
| 186   // assertEquals('function', typeof x); |  | 
| 187 })(1); |  | 
| 188 |  | 
| 189 assertThrows(function notInDefaultScope(x = y) { |  | 
| 190   { |  | 
| 191     function y() {} |  | 
| 192   } |  | 
| 193   assertEquals('function', typeof y); |  | 
| 194   assertEquals(x, undefined); |  | 
| 195 }, ReferenceError); |  | 
| 196 |  | 
| 197 // Test that hoisting from blocks does happen in global scope |  | 
| 198 function globalHoisted() { return 0; } |  | 
| 199 { |  | 
| 200   function globalHoisted() { return 1; } |  | 
| 201 } |  | 
| 202 assertEquals(1, globalHoisted()); |  | 
| 203 |  | 
| 204 // Also happens when not previously defined |  | 
| 205 assertEquals(undefined, globalUndefinedHoisted); |  | 
| 206 { |  | 
| 207   function globalUndefinedHoisted() { return 1; } |  | 
| 208 } |  | 
| 209 assertEquals(1, globalUndefinedHoisted()); |  | 
| 210 var globalUndefinedHoistedDescriptor = |  | 
| 211     Object.getOwnPropertyDescriptor(this, "globalUndefinedHoisted"); |  | 
| 212 assertFalse(globalUndefinedHoistedDescriptor.configurable); |  | 
| 213 assertTrue(globalUndefinedHoistedDescriptor.writable); |  | 
| 214 assertTrue(globalUndefinedHoistedDescriptor.enumerable); |  | 
| 215 assertEquals(1, globalUndefinedHoistedDescriptor.value()); |  | 
| 216 |  | 
| 217 // When a function property is hoisted, it should be |  | 
| 218 // made enumerable. |  | 
| 219 // BUG(v8:4451) |  | 
| 220 Object.defineProperty(this, "globalNonEnumerable", { |  | 
| 221   value: false, |  | 
| 222   configurable: true, |  | 
| 223   writable: true, |  | 
| 224   enumerable: false |  | 
| 225 }); |  | 
| 226 eval("{function globalNonEnumerable() { return 1; }}"); |  | 
| 227 var globalNonEnumerableDescriptor |  | 
| 228     = Object.getOwnPropertyDescriptor(this, "globalNonEnumerable"); |  | 
| 229 // BUG(v8:4451): Should be made non-configurable |  | 
| 230 assertTrue(globalNonEnumerableDescriptor.configurable); |  | 
| 231 assertTrue(globalNonEnumerableDescriptor.writable); |  | 
| 232 // BUG(v8:4451): Should be made enumerable |  | 
| 233 assertFalse(globalNonEnumerableDescriptor.enumerable); |  | 
| 234 assertEquals(1, globalNonEnumerableDescriptor.value()); |  | 
| 235 |  | 
| 236 // When a function property is hoisted, it should be overwritten and |  | 
| 237 // made writable and overwritten, even if the property was non-writable. |  | 
| 238 Object.defineProperty(this, "globalNonWritable", { |  | 
| 239   value: false, |  | 
| 240   configurable: true, |  | 
| 241   writable: false, |  | 
| 242   enumerable: true |  | 
| 243 }); |  | 
| 244 eval("{function globalNonWritable() { return 1; }}"); |  | 
| 245 var globalNonWritableDescriptor |  | 
| 246     = Object.getOwnPropertyDescriptor(this, "globalNonWritable"); |  | 
| 247 // BUG(v8:4451): Should be made non-configurable |  | 
| 248 assertTrue(globalNonWritableDescriptor.configurable); |  | 
| 249 // BUG(v8:4451): Should be made writable |  | 
| 250 assertFalse(globalNonWritableDescriptor.writable); |  | 
| 251 assertFalse(globalNonEnumerableDescriptor.enumerable); |  | 
| 252 // BUG(v8:4451): Should be overwritten |  | 
| 253 assertEquals(false, globalNonWritableDescriptor.value); |  | 
| 254 |  | 
| 255 // Test that hoisting from blocks does happen in an eval |  | 
| 256 eval(` |  | 
| 257   function evalHoisted() { return 0; } |  | 
| 258   { |  | 
| 259     function evalHoisted() { return 1; } |  | 
| 260   } |  | 
| 261   assertEquals(1, evalHoisted()); |  | 
| 262 `); |  | 
| 263 |  | 
| 264 // Test that hoisting from blocks happens from eval in a function |  | 
| 265 !function() { |  | 
| 266   eval(` |  | 
| 267     function evalInFunctionHoisted() { return 0; } |  | 
| 268     { |  | 
| 269       function evalInFunctionHoisted() { return 1; } |  | 
| 270     } |  | 
| 271     assertEquals(1, evalInFunctionHoisted()); |  | 
| 272   `); |  | 
| 273 }(); |  | 
| 274 |  | 
| 275 let dontHoistGlobal; |  | 
| 276 { function dontHoistGlobal() {} } |  | 
| 277 assertEquals(undefined, dontHoistGlobal); |  | 
| 278 |  | 
| 279 let dontHoistEval; |  | 
| 280 // BUG(v8:) This shouldn't hoist and shouldn't throw |  | 
| 281 var throws = false; |  | 
| 282 try { |  | 
| 283   eval("{ function dontHoistEval() {} }"); |  | 
| 284 } catch (e) { |  | 
| 285   throws = true; |  | 
| 286 } |  | 
| 287 assertTrue(throws); |  | 
| 288 |  | 
| 289 // When the global object is frozen, silently don't hoist |  | 
| 290 // Currently this actually throws BUG(v8:4452) |  | 
| 291 Object.freeze(this); |  | 
| 292 throws = false; |  | 
| 293 try { |  | 
| 294   eval('{ function hoistWhenFrozen() {} }'); |  | 
| 295 } catch (e) { |  | 
| 296   throws = true; |  | 
| 297 } |  | 
| 298 assertFalse(this.hasOwnProperty("hoistWhenFrozen")); |  | 
| 299 assertThrows(() => hoistWhenFrozen, ReferenceError); |  | 
| 300 // Should be assertFalse BUG(v8:4452) |  | 
| 301 assertTrue(throws); |  | 
| OLD | NEW | 
|---|