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 |