| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 // Helper. | 31 // Helper. |
| 32 | 32 |
| 33 function CreateFrozen(handler, callTrap, constructTrap) { | 33 function CreateFrozen(handler, callTrap, constructTrap) { |
| 34 if (handler.fix === undefined) handler.fix = function() { return {} } | 34 if (handler.fix === undefined) handler.fix = function() { return {} } |
| 35 var f = Proxy.createFunction(handler, callTrap, constructTrap) | 35 var f = Proxy.createFunction(handler, callTrap, constructTrap) |
| 36 Object.freeze(f) | 36 Object.freeze(f) |
| 37 return f | 37 return f |
| 38 } | 38 } |
| 39 | 39 |
| 40 | 40 |
| 41 // Ensures that checking the "length" property of a function proxy doesn't |
| 42 // crash due to lack of a [[Get]] method. |
| 43 var handler = { |
| 44 get : function(r, n) { return n == "length" ? 2 : undefined } |
| 45 } |
| 46 |
| 47 |
| 41 // Calling (call, Function.prototype.call, Function.prototype.apply, | 48 // Calling (call, Function.prototype.call, Function.prototype.apply, |
| 42 // Function.prototype.bind). | 49 // Function.prototype.bind). |
| 43 | 50 |
| 44 var global_object = this | 51 var global_object = this |
| 45 var receiver | 52 var receiver |
| 46 | 53 |
| 47 function TestCall(isStrict, callTrap) { | 54 function TestCall(isStrict, callTrap) { |
| 48 assertEquals(42, callTrap(5, 37)) | 55 assertEquals(42, callTrap(5, 37)) |
| 49 assertEquals(isStrict ? undefined : global_object, receiver) | 56 assertEquals(isStrict ? undefined : global_object, receiver) |
| 50 | 57 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 assertSame(o, receiver) | 145 assertSame(o, receiver) |
| 139 receiver = 333 | 146 receiver = 333 |
| 140 assertEquals(42, ff(30)) | 147 assertEquals(42, ff(30)) |
| 141 assertSame(o, receiver) | 148 assertSame(o, receiver) |
| 142 receiver = 333 | 149 receiver = 333 |
| 143 assertEquals(32, Function.prototype.apply.call(ff, {}, [20])) | 150 assertEquals(32, Function.prototype.apply.call(ff, {}, [20])) |
| 144 assertSame(o, receiver) | 151 assertSame(o, receiver) |
| 145 } | 152 } |
| 146 | 153 |
| 147 TestCall(false, function(x, y) { | 154 TestCall(false, function(x, y) { |
| 148 receiver = this; return x + y | 155 receiver = this |
| 156 return x + y |
| 149 }) | 157 }) |
| 150 | 158 |
| 151 TestCall(true, function(x, y) { | 159 TestCall(true, function(x, y) { |
| 152 "use strict"; | 160 "use strict" |
| 153 receiver = this; return x + y | 161 receiver = this |
| 162 return x + y |
| 154 }) | 163 }) |
| 155 | 164 |
| 156 TestCall(false, function() { | 165 TestCall(false, function() { |
| 157 receiver = this; return arguments[0] + arguments[1] | 166 receiver = this; return arguments[0] + arguments[1] |
| 158 }) | 167 }) |
| 159 | 168 |
| 160 TestCall(false, Proxy.createFunction({}, function(x, y) { | 169 TestCall(false, Proxy.createFunction(handler, function(x, y) { |
| 161 receiver = this; return x + y | 170 receiver = this |
| 171 return x + y |
| 162 })) | 172 })) |
| 163 | 173 |
| 164 TestCall(true, Proxy.createFunction({}, function(x, y) { | 174 TestCall(true, Proxy.createFunction(handler, function(x, y) { |
| 165 "use strict"; | 175 "use strict" |
| 166 receiver = this; return x + y | 176 receiver = this |
| 177 return x + y |
| 167 })) | 178 })) |
| 168 | 179 |
| 169 TestCall(false, CreateFrozen({}, function(x, y) { | 180 TestCall(false, CreateFrozen(handler, function(x, y) { |
| 170 receiver = this; return x + y | 181 receiver = this |
| 182 return x + y |
| 171 })) | 183 })) |
| 172 | 184 |
| 173 | 185 |
| 174 | 186 |
| 175 // Using intrinsics as call traps. | 187 // Using intrinsics as call traps. |
| 176 | 188 |
| 177 function TestCallIntrinsic(type, callTrap) { | 189 function TestCallIntrinsic(type, callTrap) { |
| 178 var f = Proxy.createFunction({}, callTrap) | 190 var f = Proxy.createFunction({}, callTrap) |
| 179 var x = f() | 191 var x = f() |
| 180 assertTrue(typeof x == type) | 192 assertTrue(typeof x == type) |
| (...skipping 30 matching lines...) Expand all Loading... |
| 211 TestCallThrow(CreateFrozen({}, function() { throw "myexn" })) | 223 TestCallThrow(CreateFrozen({}, function() { throw "myexn" })) |
| 212 | 224 |
| 213 | 225 |
| 214 | 226 |
| 215 // Construction (new). | 227 // Construction (new). |
| 216 | 228 |
| 217 var prototype = {} | 229 var prototype = {} |
| 218 var receiver | 230 var receiver |
| 219 | 231 |
| 220 var handlerWithPrototype = { | 232 var handlerWithPrototype = { |
| 221 fix: function() { return {prototype: prototype} }, | 233 fix: function() { return { prototype: { value: prototype } }; }, |
| 222 get: function(r, n) { assertEquals("prototype", n); return prototype } | 234 get: function(r, n) { |
| 235 if (n == "length") return 2; |
| 236 assertEquals("prototype", n); |
| 237 return prototype; |
| 238 } |
| 223 } | 239 } |
| 224 | 240 |
| 225 var handlerSansPrototype = { | 241 var handlerSansPrototype = { |
| 226 fix: function() { return {} }, | 242 fix: function() { return { length: { value: 2 } } }, |
| 227 get: function(r, n) { assertEquals("prototype", n); return undefined } | 243 get: function(r, n) { |
| 244 if (n == "length") return 2; |
| 245 assertEquals("prototype", n); |
| 246 return undefined; |
| 247 } |
| 228 } | 248 } |
| 229 | 249 |
| 230 function ReturnUndef(x, y) { "use strict"; receiver = this; this.sum = x + y } | 250 function ReturnUndef(x, y) { |
| 231 function ReturnThis(x, y) { "use strict"; receiver = this; this.sum = x + y; ret
urn this } | 251 "use strict"; |
| 232 function ReturnNew(x, y) { "use strict"; receiver = this; return {sum: x + y} } | 252 receiver = this; |
| 253 this.sum = x + y; |
| 254 } |
| 255 |
| 256 function ReturnThis(x, y) { |
| 257 "use strict"; |
| 258 receiver = this; |
| 259 this.sum = x + y; |
| 260 return this; |
| 261 } |
| 262 |
| 263 function ReturnNew(x, y) { |
| 264 "use strict"; |
| 265 receiver = this; |
| 266 return {sum: x + y}; |
| 267 } |
| 268 |
| 233 function ReturnNewWithProto(x, y) { | 269 function ReturnNewWithProto(x, y) { |
| 234 "use strict"; | 270 "use strict"; |
| 235 receiver = this; | 271 receiver = this; |
| 236 var result = Object.create(prototype) | 272 var result = Object.create(prototype); |
| 237 result.sum = x + y | 273 result.sum = x + y; |
| 238 return result | 274 return result; |
| 239 } | 275 } |
| 240 | 276 |
| 241 function TestConstruct(proto, constructTrap) { | 277 function TestConstruct(proto, constructTrap) { |
| 242 TestConstruct2(proto, constructTrap, handlerWithPrototype) | 278 TestConstruct2(proto, constructTrap, handlerWithPrototype) |
| 243 TestConstruct2(proto, constructTrap, handlerSansPrototype) | 279 TestConstruct2(proto, constructTrap, handlerSansPrototype) |
| 244 } | 280 } |
| 245 | 281 |
| 246 function TestConstruct2(proto, constructTrap, handler) { | 282 function TestConstruct2(proto, constructTrap, handler) { |
| 247 var f = Proxy.createFunction(handler, function() {}, constructTrap) | 283 var f = Proxy.createFunction(handler, function() {}, constructTrap) |
| 248 var o = new f(11, 31) | 284 var o = new f(11, 31) |
| (...skipping 17 matching lines...) Expand all Loading... |
| 266 var ff = Function.prototype.bind.call(f, o, 10) | 302 var ff = Function.prototype.bind.call(f, o, 10) |
| 267 var o = new ff(32) | 303 var o = new ff(32) |
| 268 assertEquals(undefined, receiver) | 304 assertEquals(undefined, receiver) |
| 269 assertEquals(42, o.sum) | 305 assertEquals(42, o.sum) |
| 270 assertSame(proto, Object.getPrototypeOf(o)) | 306 assertSame(proto, Object.getPrototypeOf(o)) |
| 271 } | 307 } |
| 272 | 308 |
| 273 TestConstruct(Object.prototype, ReturnNew) | 309 TestConstruct(Object.prototype, ReturnNew) |
| 274 TestConstruct(prototype, ReturnNewWithProto) | 310 TestConstruct(prototype, ReturnNewWithProto) |
| 275 | 311 |
| 276 TestConstruct(Object.prototype, Proxy.createFunction({}, ReturnNew)) | 312 TestConstruct(Object.prototype, Proxy.createFunction(handler, ReturnNew)) |
| 277 TestConstruct(prototype, Proxy.createFunction({}, ReturnNewWithProto)) | 313 TestConstruct(prototype, Proxy.createFunction(handler, ReturnNewWithProto)) |
| 278 | 314 |
| 279 TestConstruct(Object.prototype, CreateFrozen({}, ReturnNew)) | 315 TestConstruct(Object.prototype, CreateFrozen(handler, ReturnNew)) |
| 280 TestConstruct(prototype, CreateFrozen({}, ReturnNewWithProto)) | 316 TestConstruct(prototype, CreateFrozen(handler, ReturnNewWithProto)) |
| 281 | 317 |
| 282 | 318 |
| 283 | 319 |
| 284 // Construction with derived construct trap. | 320 // Construction with derived construct trap. |
| 285 | 321 |
| 286 function TestConstructFromCall(proto, returnsThis, callTrap) { | 322 function TestConstructFromCall(proto, returnsThis, callTrap) { |
| 287 TestConstructFromCall2(proto, returnsThis, callTrap, handlerWithPrototype) | 323 TestConstructFromCall2(proto, returnsThis, callTrap, handlerWithPrototype) |
| 288 TestConstructFromCall2(proto, returnsThis, callTrap, handlerSansPrototype) | 324 TestConstructFromCall2(proto, returnsThis, callTrap, handlerSansPrototype) |
| 289 } | 325 } |
| 290 | 326 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 314 // assertEquals(undefined, receiver) | 350 // assertEquals(undefined, receiver) |
| 315 // assertEquals(42, o.sum) | 351 // assertEquals(42, o.sum) |
| 316 // assertSame(proto, Object.getPrototypeOf(o)) | 352 // assertSame(proto, Object.getPrototypeOf(o)) |
| 317 } | 353 } |
| 318 | 354 |
| 319 TestConstructFromCall(Object.prototype, true, ReturnUndef) | 355 TestConstructFromCall(Object.prototype, true, ReturnUndef) |
| 320 TestConstructFromCall(Object.prototype, true, ReturnThis) | 356 TestConstructFromCall(Object.prototype, true, ReturnThis) |
| 321 TestConstructFromCall(Object.prototype, false, ReturnNew) | 357 TestConstructFromCall(Object.prototype, false, ReturnNew) |
| 322 TestConstructFromCall(prototype, false, ReturnNewWithProto) | 358 TestConstructFromCall(prototype, false, ReturnNewWithProto) |
| 323 | 359 |
| 324 TestConstructFromCall(Object.prototype, true, Proxy.createFunction({}, ReturnUnd
ef)) | 360 TestConstructFromCall(Object.prototype, true, |
| 325 TestConstructFromCall(Object.prototype, true, Proxy.createFunction({}, ReturnThi
s)) | 361 Proxy.createFunction(handler, ReturnUndef)) |
| 326 TestConstructFromCall(Object.prototype, false, Proxy.createFunction({}, ReturnNe
w)) | 362 TestConstructFromCall(Object.prototype, true, |
| 327 TestConstructFromCall(prototype, false, Proxy.createFunction({}, ReturnNewWithPr
oto)) | 363 Proxy.createFunction(handler, ReturnThis)) |
| 364 TestConstructFromCall(Object.prototype, false, |
| 365 Proxy.createFunction(handler, ReturnNew)) |
| 366 TestConstructFromCall(prototype, false, |
| 367 Proxy.createFunction(handler, ReturnNewWithProto)) |
| 328 | 368 |
| 329 TestConstructFromCall(Object.prototype, true, CreateFrozen({}, ReturnUndef)) | 369 TestConstructFromCall(Object.prototype, true, CreateFrozen({}, ReturnUndef)) |
| 330 TestConstructFromCall(Object.prototype, true, CreateFrozen({}, ReturnThis)) | 370 TestConstructFromCall(Object.prototype, true, CreateFrozen({}, ReturnThis)) |
| 331 TestConstructFromCall(Object.prototype, false, CreateFrozen({}, ReturnNew)) | 371 TestConstructFromCall(Object.prototype, false, CreateFrozen({}, ReturnNew)) |
| 332 TestConstructFromCall(prototype, false, CreateFrozen({}, ReturnNewWithProto)) | 372 TestConstructFromCall(prototype, false, CreateFrozen({}, ReturnNewWithProto)) |
| 333 | 373 |
| 334 ReturnUndef.prototype = prototype | 374 ReturnUndef.prototype = prototype |
| 335 ReturnThis.prototype = prototype | 375 ReturnThis.prototype = prototype |
| 336 ReturnNew.prototype = prototype | 376 ReturnNew.prototype = prototype |
| 337 ReturnNewWithProto.prototype = prototype | 377 ReturnNewWithProto.prototype = prototype |
| 338 | 378 |
| 339 TestConstructFromCall(prototype, true, ReturnUndef) | 379 TestConstructFromCall(prototype, true, ReturnUndef) |
| 340 TestConstructFromCall(prototype, true, ReturnThis) | 380 TestConstructFromCall(prototype, true, ReturnThis) |
| 341 TestConstructFromCall(Object.prototype, false, ReturnNew) | 381 TestConstructFromCall(Object.prototype, false, ReturnNew) |
| 342 TestConstructFromCall(prototype, false, ReturnNewWithProto) | 382 TestConstructFromCall(prototype, false, ReturnNewWithProto) |
| 343 | 383 |
| 344 TestConstructFromCall(Object.prototype, true, Proxy.createFunction({}, ReturnUnd
ef)) | 384 TestConstructFromCall(Object.prototype, true, |
| 345 TestConstructFromCall(Object.prototype, true, Proxy.createFunction({}, ReturnThi
s)) | 385 Proxy.createFunction(handler, ReturnUndef)) |
| 346 TestConstructFromCall(Object.prototype, false, Proxy.createFunction({}, ReturnNe
w)) | 386 TestConstructFromCall(Object.prototype, true, |
| 347 TestConstructFromCall(prototype, false, Proxy.createFunction({}, ReturnNewWithPr
oto)) | 387 Proxy.createFunction(handler, ReturnThis)) |
| 388 TestConstructFromCall(Object.prototype, false, |
| 389 Proxy.createFunction(handler, ReturnNew)) |
| 390 TestConstructFromCall(prototype, false, |
| 391 Proxy.createFunction(handler, ReturnNewWithProto)) |
| 348 | 392 |
| 349 TestConstructFromCall(prototype, true, Proxy.createFunction(handlerWithPrototype
, ReturnUndef)) | 393 TestConstructFromCall(prototype, true, |
| 350 TestConstructFromCall(prototype, true, Proxy.createFunction(handlerWithPrototype
, ReturnThis)) | 394 Proxy.createFunction(handlerWithPrototype, ReturnUndef)) |
| 351 TestConstructFromCall(Object.prototype, false, Proxy.createFunction(handlerWithP
rototype, ReturnNew)) | 395 TestConstructFromCall(prototype, true, |
| 352 TestConstructFromCall(prototype, false, Proxy.createFunction(handlerWithPrototyp
e, ReturnNewWithProto)) | 396 Proxy.createFunction(handlerWithPrototype, ReturnThis)) |
| 397 TestConstructFromCall(Object.prototype, false, |
| 398 Proxy.createFunction(handlerWithPrototype, ReturnNew)) |
| 399 TestConstructFromCall(prototype, false, |
| 400 Proxy.createFunction(handlerWithPrototype, |
| 401 ReturnNewWithProto)) |
| 353 | 402 |
| 354 TestConstructFromCall(prototype, true, CreateFrozen(handlerWithPrototype, Return
Undef)) | 403 TestConstructFromCall(prototype, true, |
| 355 TestConstructFromCall(prototype, true, CreateFrozen(handlerWithPrototype, Return
This)) | 404 CreateFrozen(handlerWithPrototype, ReturnUndef)) |
| 356 TestConstructFromCall(Object.prototype, false, CreateFrozen(handlerWithPrototype
, ReturnNew)) | 405 TestConstructFromCall(prototype, true, |
| 357 TestConstructFromCall(prototype, false, CreateFrozen(handlerWithPrototype, Retur
nNewWithProto)) | 406 CreateFrozen(handlerWithPrototype, ReturnThis)) |
| 407 TestConstructFromCall(Object.prototype, false, |
| 408 CreateFrozen(handlerWithPrototype, ReturnNew)) |
| 409 TestConstructFromCall(prototype, false, |
| 410 CreateFrozen(handlerWithPrototype, ReturnNewWithProto)) |
| 358 | 411 |
| 359 | 412 |
| 360 | 413 |
| 361 // Throwing from the construct trap. | 414 // Throwing from the construct trap. |
| 362 | 415 |
| 363 function TestConstructThrow(trap) { | 416 function TestConstructThrow(trap) { |
| 364 TestConstructThrow2(Proxy.createFunction({fix: function() {return {}}}, trap)) | 417 TestConstructThrow2(Proxy.createFunction({ fix: function() {return {};} }, |
| 365 TestConstructThrow2(Proxy.createFunction({fix: function() {return {}}}, | 418 trap)) |
| 366 function() {}, trap)) | 419 TestConstructThrow2(Proxy.createFunction({ fix: function() {return {};} }, |
| 420 function() {}, |
| 421 trap)) |
| 367 } | 422 } |
| 368 | 423 |
| 369 function TestConstructThrow2(f) { | 424 function TestConstructThrow2(f) { |
| 370 assertThrows(function(){ new f(11) }, "myexn") | 425 assertThrows(function(){ new f(11) }, "myexn") |
| 371 Object.freeze(f) | 426 Object.freeze(f) |
| 372 assertThrows(function(){ new f(11) }, "myexn") | 427 assertThrows(function(){ new f(11) }, "myexn") |
| 373 } | 428 } |
| 374 | 429 |
| 375 TestConstructThrow(function() { throw "myexn" }) | 430 TestConstructThrow(function() { throw "myexn" }) |
| 376 TestConstructThrow(Proxy.createFunction({}, function() { throw "myexn" })) | 431 TestConstructThrow(Proxy.createFunction({}, function() { throw "myexn" })) |
| 377 TestConstructThrow(CreateFrozen({}, function() { throw "myexn" })) | 432 TestConstructThrow(CreateFrozen({}, function() { throw "myexn" })) |
| 378 | 433 |
| 379 | 434 |
| 380 | 435 |
| 381 // Using function proxies as getters and setters. | 436 // Using function proxies as getters and setters. |
| 382 | 437 |
| 383 var value | 438 var value |
| 384 var receiver | 439 var receiver |
| 385 | 440 |
| 386 function TestAccessorCall(getterCallTrap, setterCallTrap) { | 441 function TestAccessorCall(getterCallTrap, setterCallTrap) { |
| 387 var handler = {fix: function() { return {} }} | 442 var handler = { fix: function() { return {} } } |
| 388 var pgetter = Proxy.createFunction(handler, getterCallTrap) | 443 var pgetter = Proxy.createFunction(handler, getterCallTrap) |
| 389 var psetter = Proxy.createFunction(handler, setterCallTrap) | 444 var psetter = Proxy.createFunction(handler, setterCallTrap) |
| 390 | 445 |
| 391 var o = {} | 446 var o = {} |
| 392 var oo = Object.create(o) | 447 var oo = Object.create(o) |
| 393 Object.defineProperty(o, "a", {get: pgetter, set: psetter}) | 448 Object.defineProperty(o, "a", {get: pgetter, set: psetter}) |
| 394 Object.defineProperty(o, "b", {get: pgetter}) | 449 Object.defineProperty(o, "b", {get: pgetter}) |
| 395 Object.defineProperty(o, "c", {set: psetter}) | 450 Object.defineProperty(o, "c", {set: psetter}) |
| 396 Object.defineProperty(o, "3", {get: pgetter, set: psetter}) | 451 Object.defineProperty(o, "3", {get: pgetter, set: psetter}) |
| 397 Object.defineProperty(oo, "a", {value: 43}) | 452 Object.defineProperty(oo, "a", {value: 43}) |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 485 | 540 |
| 486 TestAccessorCall( | 541 TestAccessorCall( |
| 487 Proxy.createFunction({}, function() { receiver = this; return 42 }), | 542 Proxy.createFunction({}, function() { receiver = this; return 42 }), |
| 488 Proxy.createFunction({}, function(x) { receiver = this; value = x }) | 543 Proxy.createFunction({}, function(x) { receiver = this; value = x }) |
| 489 ) | 544 ) |
| 490 | 545 |
| 491 TestAccessorCall( | 546 TestAccessorCall( |
| 492 CreateFrozen({}, function() { receiver = this; return 42 }), | 547 CreateFrozen({}, function() { receiver = this; return 42 }), |
| 493 CreateFrozen({}, function(x) { receiver = this; value = x }) | 548 CreateFrozen({}, function(x) { receiver = this; value = x }) |
| 494 ) | 549 ) |
| OLD | NEW |