Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2014 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-unscopables | |
| 6 | |
| 7 var global = this; | |
| 8 var globalProto = Object.getPrototypeOf(global); | |
| 9 | |
| 10 | |
| 11 function runtTest(f) { | |
|
rossberg
2014/07/17 15:12:13
Nit: s/runtTest/runTest/
arv (Not doing code reviews)
2014/07/17 23:34:36
Done.
| |
| 12 function restoreGlobal() { | |
| 13 Object.setPrototypeOf(global, globalProto); | |
| 14 delete global[Symbol.unscopables]; | |
| 15 delete global.x; | |
| 16 delete global.x_; | |
| 17 delete global.y; | |
| 18 delete global.z; | |
| 19 } | |
| 20 | |
| 21 function getObject(i) { | |
| 22 switch (i) { | |
| 23 case 0: return {}; | |
|
rossberg
2014/07/17 15:12:13
Why not simply use an array? Then you don't need t
arv (Not doing code reviews)
2014/07/17 23:34:37
These needs to be new objects every time but I agr
| |
| 24 case 1: return []; | |
| 25 case 2: return function() {}; | |
| 26 case 3: return global; | |
| 27 } | |
| 28 } | |
| 29 | |
| 30 if (f.length === 1) { | |
| 31 for (var i = 0; i < 4; i++) { | |
| 32 f(getObject(i)); | |
| 33 restoreGlobal(); | |
| 34 } | |
| 35 } else { | |
| 36 for (var i = 0; i < 4; i++) { | |
| 37 for (var j = 0; j < 4; j++) { | |
| 38 var object = getObject(i); | |
| 39 var proto = getObject(i); | |
|
rossberg
2014/07/17 15:12:13
getObject(j) ? Otherwise, you don't execute anythi
arv (Not doing code reviews)
2014/07/17 23:34:37
wow. That refactoring just completely failed.
| |
| 40 if (object === proto) { | |
| 41 continue; | |
| 42 } | |
| 43 f(getObject(i), getObject(j)); | |
|
rossberg
2014/07/17 15:12:13
f(object, proto) ?
arv (Not doing code reviews)
2014/07/17 23:34:37
Done.
| |
| 44 restoreGlobal(); | |
| 45 } | |
| 46 } | |
| 47 } | |
| 48 } | |
| 49 | |
| 50 | |
| 51 function TestBasics(object) { | |
| 52 var x = 1; | |
| 53 var y = 2; | |
| 54 var z = 3; | |
| 55 object.x = 4; | |
| 56 object.y = 5; | |
| 57 | |
| 58 with (object) { | |
| 59 assertEquals(4, x); | |
| 60 assertEquals(5, y); | |
| 61 assertEquals(3, z); | |
| 62 } | |
| 63 | |
| 64 object[Symbol.unscopables] = {x: true}; | |
| 65 with (object) { | |
| 66 assertEquals(1, x); | |
| 67 assertEquals(5, y); | |
| 68 assertEquals(3, z); | |
| 69 } | |
| 70 | |
| 71 object[Symbol.unscopables] = {x: 0, y: true}; | |
| 72 with (object) { | |
| 73 assertEquals(1, x); | |
| 74 assertEquals(2, y); | |
| 75 assertEquals(3, z); | |
| 76 } | |
| 77 } | |
| 78 runtTest(TestBasics); | |
| 79 | |
| 80 | |
| 81 function TestBasicsSet(object) { | |
| 82 var x = 1; | |
| 83 object.x = 2; | |
| 84 | |
| 85 with (object) { | |
| 86 assertEquals(2, x); | |
| 87 } | |
| 88 | |
| 89 object[Symbol.unscopables] = {x: true}; | |
| 90 with (object) { | |
| 91 assertEquals(1, x); | |
| 92 x = 3; | |
| 93 assertEquals(3, x); | |
| 94 } | |
| 95 | |
| 96 assertEquals(3, x); | |
| 97 assertEquals(2, object.x); | |
| 98 } | |
| 99 runtTest(TestBasicsSet); | |
| 100 | |
| 101 | |
| 102 function TestOnProto(object, proto) { | |
| 103 var x = 1; | |
| 104 var y = 2; | |
| 105 var z = 3; | |
| 106 proto.x = 4; | |
| 107 | |
| 108 Object.setPrototypeOf(object, proto); | |
| 109 object.y = 5; | |
| 110 | |
| 111 with (object) { | |
| 112 assertEquals(4, x); | |
| 113 assertEquals(5, y); | |
| 114 assertEquals(3, z); | |
| 115 } | |
| 116 | |
| 117 proto[Symbol.unscopables] = {x: true}; | |
| 118 with (object) { | |
| 119 assertEquals(1, x); | |
| 120 assertEquals(5, y); | |
| 121 assertEquals(3, z); | |
| 122 } | |
| 123 | |
| 124 object[Symbol.unscopables] = {y: true}; | |
| 125 with (object) { | |
| 126 assertEquals(1, x); | |
| 127 assertEquals(2, y); | |
| 128 assertEquals(3, z); | |
| 129 } | |
| 130 | |
| 131 proto[Symbol.unscopables] = {y: true}; | |
| 132 object[Symbol.unscopables] = {x: true}; | |
| 133 with (object) { | |
| 134 assertEquals(4, x); | |
| 135 assertEquals(5, y); | |
| 136 assertEquals(3, z); | |
| 137 } | |
| 138 } | |
| 139 runtTest(TestOnProto); | |
| 140 | |
| 141 | |
| 142 function TestNonObject(object) { | |
| 143 var x = 1; | |
| 144 var y = 2; | |
| 145 object.x = 3; | |
| 146 object.y = 4; | |
| 147 | |
| 148 object[Symbol.unscopables] = 'xy'; | |
| 149 with (object) { | |
| 150 assertEquals(3, x); | |
| 151 assertEquals(4, y); | |
| 152 } | |
| 153 | |
| 154 object[Symbol.unscopables] = null; | |
| 155 with (object) { | |
| 156 assertEquals(3, x); | |
| 157 assertEquals(4, y); | |
| 158 } | |
| 159 } | |
| 160 runtTest(TestNonObject); | |
| 161 | |
| 162 | |
| 163 function TestChangeDuringWith(object) { | |
| 164 var x = 1; | |
| 165 var y = 2; | |
| 166 object.x = 3; | |
| 167 object.y = 4; | |
| 168 | |
| 169 with (object) { | |
| 170 assertEquals(3, x); | |
| 171 assertEquals(4, y); | |
| 172 object[Symbol.unscopables] = {x: true}; | |
| 173 assertEquals(1, x); | |
| 174 assertEquals(4, y); | |
| 175 } | |
| 176 } | |
| 177 runtTest(TestChangeDuringWith); | |
| 178 | |
| 179 | |
| 180 function TestChangeDuringWithWithPossibleOptimization(object) { | |
|
rossberg
2014/07/17 15:12:13
I had in mind a test like the following:
var x =
arv (Not doing code reviews)
2014/07/17 23:34:37
Thanks. Added.
| |
| 181 var x = 1; | |
| 182 object.x = 2; | |
| 183 | |
| 184 with (object) { | |
| 185 for (var i = 0; i < 1e3; i++) { | |
| 186 assertEquals(2, x); | |
| 187 } | |
| 188 object[Symbol.unscopables] = {x: true}; | |
| 189 for (var i = 0; i < 1e3; i++) { | |
| 190 assertEquals(1, x); | |
| 191 } | |
| 192 } | |
| 193 } | |
| 194 runtTest(TestChangeDuringWithWithPossibleOptimization); | |
| 195 | |
| 196 | |
| 197 var global = this; | |
| 198 (function TestGlobal() { | |
| 199 global.values = 'global.values'; | |
| 200 Array.prototype.values = 'Array.prototype.values'; | |
| 201 Array.prototype[Symbol.unscopables] = {values: true}; | |
| 202 Array.prototype.__proto__ = {values: 42}; | |
| 203 var array = []; | |
| 204 with (array) { | |
| 205 assertEquals(42, values); | |
| 206 } | |
| 207 })(); | |
| 208 | |
| 209 | |
| 210 function TestAccessorReceiver(object, proto) { | |
| 211 var x = 'local'; | |
| 212 | |
| 213 Object.defineProperty(proto, 'x', { | |
| 214 get: function() { | |
| 215 assertEquals(object, this); | |
| 216 return this.x_; | |
| 217 }, | |
| 218 configurable: true | |
| 219 }); | |
| 220 proto.x_ = 'proto'; | |
| 221 | |
| 222 Object.setPrototypeOf(object, proto); | |
| 223 proto.x_ = 'object'; | |
| 224 | |
| 225 with (object) { | |
| 226 assertEquals('object', x); | |
| 227 } | |
| 228 } | |
| 229 runtTest(TestAccessorReceiver); | |
| 230 | |
| 231 | |
| 232 function TestUnscopablesGetter(object) { | |
| 233 // This test gets really messy when object is the global since the assert | |
| 234 // functions are properties on the global object and the call count gets | |
| 235 // completely different. | |
| 236 if (object === global) return; | |
| 237 | |
| 238 var x = 'local'; | |
| 239 object.x = 'object'; | |
| 240 | |
| 241 var callCount = 0; | |
| 242 Object.defineProperty(object, Symbol.unscopables, { | |
| 243 get: function() { | |
| 244 callCount++; | |
| 245 return {}; | |
| 246 }, | |
| 247 configurable: true | |
| 248 }); | |
| 249 with (object) { | |
| 250 assertEquals('object', x); | |
| 251 } | |
| 252 // Once for HasBinding and once for GetBindingValue | |
| 253 assertEquals(2, callCount); | |
| 254 | |
| 255 callCount = 0; | |
| 256 Object.defineProperty(object, Symbol.unscopables, { | |
| 257 get: function() { | |
| 258 callCount++; | |
| 259 return {x: true}; | |
| 260 }, | |
| 261 configurable: true | |
| 262 }); | |
| 263 with (object) { | |
| 264 assertEquals('local', x); | |
| 265 } | |
| 266 // Once for HasBinding | |
| 267 assertEquals(1, callCount); | |
| 268 | |
| 269 callCount = 0; | |
| 270 Object.defineProperty(object, Symbol.unscopables, { | |
| 271 get: function() { | |
| 272 callCount++; | |
| 273 return callCount === 1 ? {} : {x: true}; | |
| 274 }, | |
| 275 configurable: true | |
| 276 }); | |
| 277 with (object) { | |
| 278 assertEquals(void 0, x); | |
| 279 } | |
| 280 // Once for HasBinding, once for GetBindingValue. | |
| 281 assertEquals(2, callCount); | |
| 282 | |
| 283 callCount = 0; | |
| 284 Object.defineProperty(object, Symbol.unscopables, { | |
| 285 get: function() { | |
| 286 callCount++; | |
| 287 return callCount === 1 ? {} : {x: true}; | |
| 288 }, | |
| 289 configurable: true | |
| 290 }); | |
| 291 with (object) { | |
| 292 x = 1; | |
| 293 } | |
| 294 // Once for HasBinding | |
| 295 assertEquals(1, callCount); | |
| 296 assertEquals(1, object.x); | |
| 297 assertEquals('local', x); | |
| 298 with (object) { | |
| 299 x = 2; | |
| 300 } | |
| 301 // One more HasBinding. | |
| 302 assertEquals(2, callCount); | |
| 303 assertEquals(1, object.x); | |
| 304 assertEquals(2, x); | |
| 305 } | |
| 306 runtTest(TestUnscopablesGetter); | |
| 307 | |
| 308 | |
| 309 var global = this; | |
| 310 (function TestUnscopablesGetter2() { | |
| 311 var x = 'local'; | |
| 312 | |
| 313 var protos = [{}, [], function() {}, global]; | |
| 314 var objects = [{}, [], function() {}]; | |
| 315 | |
| 316 protos.forEach(function(proto) { | |
| 317 objects.forEach(function(object) { | |
| 318 Object.defineProperty(proto, 'x', { | |
| 319 get: function() { | |
| 320 assertEquals(object, this); | |
| 321 return 'proto'; | |
| 322 }, | |
| 323 configurable: true | |
| 324 }); | |
| 325 | |
| 326 object.__proto__ = proto; | |
| 327 Object.defineProperty(object, 'x', { | |
| 328 get: function() { | |
| 329 assertEquals(object, this); | |
| 330 return 'object'; | |
| 331 }, | |
| 332 configurable: true | |
| 333 }); | |
| 334 | |
| 335 with (object) { | |
| 336 assertEquals('object', x); | |
| 337 } | |
| 338 | |
| 339 object[Symbol.unscopables] = {x: true}; | |
| 340 with (object) { | |
| 341 assertEquals('proto', x); | |
| 342 } | |
| 343 | |
| 344 delete proto[Symbol.unscopables]; | |
| 345 delete object[Symbol.unscopables]; | |
| 346 }); | |
| 347 }); | |
| 348 })(); | |
| 349 | |
| 350 | |
| 351 function TestSetterOnBlacklisted(object, proto) { | |
| 352 Object.defineProperty(proto, 'x', { | |
| 353 set: function(x) { | |
| 354 assertTrue(false); | |
|
rossberg
2014/07/17 15:12:13
assertUnreachable()
arv (Not doing code reviews)
2014/07/17 23:34:37
Done.
| |
| 355 }, | |
| 356 get: function() { | |
| 357 return 'proto'; | |
| 358 }, | |
| 359 configurable: true | |
| 360 }); | |
| 361 Object.setPrototypeOf(object, proto); | |
| 362 Object.defineProperty(object, 'x', { | |
| 363 get: function() { | |
| 364 return this.x_; | |
| 365 }, | |
| 366 set: function(x) { | |
| 367 this.x_ = x; | |
| 368 }, | |
| 369 configurable: true | |
| 370 }); | |
| 371 object.x_ = 1; | |
| 372 | |
| 373 with (object) { | |
| 374 x = 2; | |
| 375 assertEquals(2, x); | |
| 376 } | |
| 377 | |
| 378 assertEquals(2, object.x); | |
| 379 | |
| 380 object[Symbol.unscopables] = {x: true}; | |
| 381 | |
| 382 with (object) { | |
| 383 x = 3; | |
|
rossberg
2014/07/17 15:12:13
Yeah, what this does is really weird...
arv (Not doing code reviews)
2014/07/17 23:34:37
Acknowledged.
| |
| 384 assertEquals('proto', x); | |
| 385 } | |
| 386 | |
| 387 assertEquals(3, object.x); | |
| 388 } | |
| 389 runtTest(TestSetterOnBlacklisted); | |
| OLD | NEW |