blob: 6b8d098442f16fba27bf4647a8d1b2ddc7e4a377 [file] [log] [blame]
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001// Copyright 2011 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28// Flags: --harmony-proxies --allow-natives-syntax
29
30
31// Helper.
32
33function CreateFrozen(handler, callTrap, constructTrap) {
34 if (handler.fix === undefined) handler.fix = function() { return {} }
35 var f = Proxy.createFunction(handler, callTrap, constructTrap)
36 Object.freeze(f)
37 return f
38}
39
40
41// Ensures that checking the "length" property of a function proxy doesn't
42// crash due to lack of a [[Get]] method.
43var handler = {
44 get : function(r, n) { return n == "length" ? 2 : undefined }
45}
46
47
48// Calling (call, Function.prototype.call, Function.prototype.apply,
49// Function.prototype.bind).
50
51var global_object = this
52var receiver
53
54function TestCall(isStrict, callTrap) {
55 assertEquals(42, callTrap(5, 37))
56 // TODO(rossberg): strict mode seems to be broken on x64...
57 // assertSame(isStrict ? undefined : global_object, receiver)
58
59 var handler = {
60 get: function(r, k) {
61 return k == "length" ? 2 : Function.prototype[k]
62 }
63 }
64 var f = Proxy.createFunction(handler, callTrap)
65 var o = {f: f}
66 global_object.f = f
67
68 receiver = 333
69 assertEquals(42, f(11, 31))
70 // TODO(rossberg): strict mode seems to be broken on x64...
71 // assertSame(isStrict ? undefined : global_object, receiver)
72 receiver = 333
73 assertEquals(42, o.f(10, 32))
74 assertSame(o, receiver)
75 receiver = 333
76 assertEquals(42, o["f"](9, 33))
77 assertSame(o, receiver)
78 receiver = 333
79 assertEquals(42, (1, o).f(8, 34))
80 assertSame(o, receiver)
81 receiver = 333
82 assertEquals(42, (1, o)["f"](7, 35))
83 assertSame(o, receiver)
84 receiver = 333
85 assertEquals(42, f.call(o, 32, 10))
86 assertSame(o, receiver)
87 receiver = 333
88 assertEquals(42, f.call(undefined, 33, 9))
89 assertSame(isStrict ? undefined : global_object, receiver)
90 receiver = 333
91 assertEquals(42, f.call(null, 33, 9))
92 assertSame(isStrict ? null : global_object, receiver)
93 receiver = 333
94 assertEquals(44, f.call(2, 21, 23))
95 assertSame(2, receiver.valueOf())
96 receiver = 333
97 assertEquals(42, Function.prototype.call.call(f, o, 20, 22))
98 assertSame(o, receiver)
99 receiver = 333
100 assertEquals(43, Function.prototype.call.call(f, null, 20, 23))
101 assertSame(isStrict ? null : global_object, receiver)
102 assertEquals(44, Function.prototype.call.call(f, 2, 21, 23))
103 assertEquals(2, receiver.valueOf())
104 receiver = 333
105 assertEquals(32, f.apply(o, [16, 16]))
106 assertSame(o, receiver)
107 receiver = 333
108 assertEquals(32, Function.prototype.apply.call(f, o, [17, 15]))
109 assertSame(o, receiver)
110 receiver = 333
111 assertEquals(42, %Call(o, 11, 31, f))
112 assertSame(o, receiver)
113 receiver = 333
114 assertEquals(42, %Call(null, 11, 31, f))
115 assertSame(isStrict ? null : global_object, receiver)
116 receiver = 333
117 assertEquals(42, %Apply(f, o, [11, 31], 0, 2))
118 assertSame(o, receiver)
119 receiver = 333
120 assertEquals(42, %Apply(f, null, [11, 31], 0, 2))
121 assertSame(isStrict ? null : global_object, receiver)
122 receiver = 333
123 assertEquals(42, %_CallFunction(o, 11, 31, f))
124 assertSame(o, receiver)
125 receiver = 333
126 assertEquals(42, %_CallFunction(null, 11, 31, f))
127 assertSame(isStrict ? null : global_object, receiver)
128
129 var ff = Function.prototype.bind.call(f, o, 12)
130 assertTrue(ff.length <= 1) // TODO(rossberg): Not spec'ed yet, be lax.
131 receiver = 333
132 assertEquals(42, ff(30))
133 assertSame(o, receiver)
134 receiver = 333
135 assertEquals(33, Function.prototype.call.call(ff, {}, 21))
136 assertSame(o, receiver)
137 receiver = 333
138 assertEquals(32, Function.prototype.apply.call(ff, {}, [20]))
139 assertSame(o, receiver)
140 receiver = 333
141 assertEquals(23, %Call({}, 11, ff))
142 assertSame(o, receiver)
143 receiver = 333
144 assertEquals(23, %Call({}, 11, 3, ff))
145 assertSame(o, receiver)
146 receiver = 333
147 assertEquals(24, %Apply(ff, {}, [12, 13], 0, 1))
148 assertSame(o, receiver)
149 receiver = 333
150 assertEquals(24, %Apply(ff, {}, [12, 13], 0, 2))
151 assertSame(o, receiver)
152 receiver = 333
153 assertEquals(34, %_CallFunction({}, 22, ff))
154 assertSame(o, receiver)
155 receiver = 333
156 assertEquals(34, %_CallFunction({}, 22, 3, ff))
157 assertSame(o, receiver)
158
159 var fff = Function.prototype.bind.call(ff, o, 30)
160 assertEquals(0, fff.length)
161 receiver = 333
162 assertEquals(42, fff())
163 assertSame(o, receiver)
164 receiver = 333
165 assertEquals(42, Function.prototype.call.call(fff, {}))
166 assertSame(o, receiver)
167 receiver = 333
168 assertEquals(42, Function.prototype.apply.call(fff, {}))
169 assertSame(o, receiver)
170 receiver = 333
171 assertEquals(42, %Call({}, fff))
172 assertSame(o, receiver)
173 receiver = 333
174 assertEquals(42, %Call({}, 11, 3, fff))
175 assertSame(o, receiver)
176 receiver = 333
177 assertEquals(42, %Apply(fff, {}, [], 0, 0))
178 assertSame(o, receiver)
179 receiver = 333
180 assertEquals(42, %Apply(fff, {}, [12, 13], 0, 0))
181 assertSame(o, receiver)
182 receiver = 333
183 assertEquals(42, %Apply(fff, {}, [12, 13], 0, 2))
184 assertSame(o, receiver)
185 receiver = 333
186 assertEquals(42, %_CallFunction({}, fff))
187 assertSame(o, receiver)
188 receiver = 333
189 assertEquals(42, %_CallFunction({}, 3, 4, 5, fff))
190 assertSame(o, receiver)
191
192 var f = CreateFrozen({}, callTrap)
193 receiver = 333
194 assertEquals(42, f(11, 31))
195 assertSame(isStrict ? undefined : global_object, receiver)
196 var o = {f: f}
197 receiver = 333
198 assertEquals(42, o.f(10, 32))
199 assertSame(o, receiver)
200 receiver = 333
201 assertEquals(42, o["f"](9, 33))
202 assertSame(o, receiver)
203 receiver = 333
204 assertEquals(42, (1, o).f(8, 34))
205 assertSame(o, receiver)
206 receiver = 333
207 assertEquals(42, (1, o)["f"](7, 35))
208 assertSame(o, receiver)
209 receiver = 333
210 assertEquals(42, Function.prototype.call.call(f, o, 20, 22))
211 assertSame(o, receiver)
212 receiver = 333
213 assertEquals(32, Function.prototype.apply.call(f, o, [17, 15]))
214 assertSame(o, receiver)
215 receiver = 333
216 assertEquals(23, %Call(o, 11, 12, f))
217 assertSame(o, receiver)
218 receiver = 333
219 assertEquals(27, %Apply(f, o, [12, 13, 14], 1, 2))
220 assertSame(o, receiver)
221 receiver = 333
222 assertEquals(42, %_CallFunction(o, 18, 24, f))
223 assertSame(o, receiver)
224}
225
226TestCall(false, function(x, y) {
227 receiver = this
228 return x + y
229})
230
231TestCall(true, function(x, y) {
232 "use strict"
233 receiver = this
234 return x + y
235})
236
237TestCall(false, function() {
238 receiver = this
239 return arguments[0] + arguments[1]
240})
241
242TestCall(false, Proxy.createFunction(handler, function(x, y) {
243 receiver = this
244 return x + y
245}))
246
247TestCall(true, Proxy.createFunction(handler, function(x, y) {
248 "use strict"
249 receiver = this
250 return x + y
251}))
252
253TestCall(false, CreateFrozen(handler, function(x, y) {
254 receiver = this
255 return x + y
256}))
257
258
259
260// Using intrinsics as call traps.
261
262function TestCallIntrinsic(type, callTrap) {
263 var f = Proxy.createFunction({}, callTrap)
264 var x = f()
265 assertTrue(typeof x == type)
266}
267
268TestCallIntrinsic("boolean", Boolean)
269TestCallIntrinsic("number", Number)
270TestCallIntrinsic("string", String)
271TestCallIntrinsic("object", Object)
272TestCallIntrinsic("function", Function)
273
274
275
276// Throwing from call trap.
277
278function TestCallThrow(callTrap) {
279 var f = Proxy.createFunction({}, callTrap)
280 assertThrows(function(){ f(11) }, "myexn")
281 assertThrows(function(){ ({x: f}).x(11) }, "myexn")
282 assertThrows(function(){ ({x: f})["x"](11) }, "myexn")
283 assertThrows(function(){ Function.prototype.call.call(f, {}, 2) }, "myexn")
284 assertThrows(function(){ Function.prototype.apply.call(f, {}, [1]) }, "myexn")
285 assertThrows(function(){ %Call({}, f) }, "myexn")
286 assertThrows(function(){ %Call({}, 1, 2, f) }, "myexn")
287 assertThrows(function(){ %Apply({}, f, [], 3, 0) }, "myexn")
288 assertThrows(function(){ %Apply({}, f, [3, 4], 0, 1) }, "myexn")
289 assertThrows(function(){ %_CallFunction({}, f) }, "myexn")
290 assertThrows(function(){ %_CallFunction({}, 1, 2, f) }, "myexn")
291
292 var f = CreateFrozen({}, callTrap)
293 assertThrows(function(){ f(11) }, "myexn")
294 assertThrows(function(){ ({x: f}).x(11) }, "myexn")
295 assertThrows(function(){ ({x: f})["x"](11) }, "myexn")
296 assertThrows(function(){ Function.prototype.call.call(f, {}, 2) }, "myexn")
297 assertThrows(function(){ Function.prototype.apply.call(f, {}, [1]) }, "myexn")
298 assertThrows(function(){ %Call({}, f) }, "myexn")
299 assertThrows(function(){ %Call({}, 1, 2, f) }, "myexn")
300 assertThrows(function(){ %Apply({}, f, [], 3, 0) }, "myexn")
301 assertThrows(function(){ %Apply({}, f, [3, 4], 0, 1) }, "myexn")
302 assertThrows(function(){ %_CallFunction({}, f) }, "myexn")
303 assertThrows(function(){ %_CallFunction({}, 1, 2, f) }, "myexn")
304}
305
306TestCallThrow(function() { throw "myexn" })
307TestCallThrow(Proxy.createFunction({}, function() { throw "myexn" }))
308TestCallThrow(CreateFrozen({}, function() { throw "myexn" }))
309
310
311
312// Construction (new).
313
314var prototype = {myprop: 0}
315var receiver
316
317var handlerWithPrototype = {
318 fix: function() { return { prototype: { value: prototype } }; },
319 get: function(r, n) {
320 if (n == "length") return 2;
321 assertEquals("prototype", n);
322 return prototype;
323 }
324}
325
326var handlerSansPrototype = {
327 fix: function() { return { length: { value: 2 } } },
328 get: function(r, n) {
329 if (n == "length") return 2;
330 assertEquals("prototype", n);
331 return undefined;
332 }
333}
334
335function ReturnUndef(x, y) {
336 "use strict";
337 receiver = this;
338 this.sum = x + y;
339}
340
341function ReturnThis(x, y) {
342 "use strict";
343 receiver = this;
344 this.sum = x + y;
345 return this;
346}
347
348function ReturnNew(x, y) {
349 "use strict";
350 receiver = this;
351 return {sum: x + y};
352}
353
354function ReturnNewWithProto(x, y) {
355 "use strict";
356 receiver = this;
357 var result = Object.create(prototype);
358 result.sum = x + y;
359 return result;
360}
361
362function TestConstruct(proto, constructTrap) {
363 TestConstruct2(proto, constructTrap, handlerWithPrototype)
364 TestConstruct2(proto, constructTrap, handlerSansPrototype)
365}
366
367function TestConstruct2(proto, constructTrap, handler) {
368 var f = Proxy.createFunction(handler, function() {}, constructTrap)
369 var o = new f(11, 31)
370 assertEquals(undefined, receiver)
371 assertEquals(42, o.sum)
372 assertSame(proto, Object.getPrototypeOf(o))
373
374 var f = CreateFrozen(handler, function() {}, constructTrap)
375 var o = new f(11, 32)
376 assertEquals(undefined, receiver)
377 assertEquals(43, o.sum)
378 assertSame(proto, Object.getPrototypeOf(o))
379}
380
381TestConstruct(Object.prototype, ReturnNew)
382TestConstruct(prototype, ReturnNewWithProto)
383
384TestConstruct(Object.prototype, Proxy.createFunction(handler, ReturnNew))
385TestConstruct(prototype, Proxy.createFunction(handler, ReturnNewWithProto))
386
387TestConstruct(Object.prototype, CreateFrozen(handler, ReturnNew))
388TestConstruct(prototype, CreateFrozen(handler, ReturnNewWithProto))
389
390
391
392// Construction with derived construct trap.
393
394function TestConstructFromCall(proto, returnsThis, callTrap) {
395 TestConstructFromCall2(prototype, returnsThis, callTrap, handlerWithPrototype)
396 TestConstructFromCall2(proto, returnsThis, callTrap, handlerSansPrototype)
397}
398
399function TestConstructFromCall2(proto, returnsThis, callTrap, handler) {
400 // TODO(rossberg): handling of prototype for derived construct trap will be
401 // fixed in a separate change. Commenting out checks below for now.
402 var f = Proxy.createFunction(handler, callTrap)
403 var o = new f(11, 31)
404 if (returnsThis) assertEquals(o, receiver)
405 assertEquals(42, o.sum)
406 // assertSame(proto, Object.getPrototypeOf(o))
407
408 var g = CreateFrozen(handler, callTrap)
409 // assertSame(f.prototype, g.prototype)
410 var o = new g(11, 32)
411 if (returnsThis) assertEquals(o, receiver)
412 assertEquals(43, o.sum)
413 // assertSame(proto, Object.getPrototypeOf(o))
414}
415
416TestConstructFromCall(Object.prototype, true, ReturnUndef)
417TestConstructFromCall(Object.prototype, true, ReturnThis)
418TestConstructFromCall(Object.prototype, false, ReturnNew)
419TestConstructFromCall(prototype, false, ReturnNewWithProto)
420
421TestConstructFromCall(Object.prototype, true,
422 Proxy.createFunction(handler, ReturnUndef))
423TestConstructFromCall(Object.prototype, true,
424 Proxy.createFunction(handler, ReturnThis))
425TestConstructFromCall(Object.prototype, false,
426 Proxy.createFunction(handler, ReturnNew))
427TestConstructFromCall(prototype, false,
428 Proxy.createFunction(handler, ReturnNewWithProto))
429
430TestConstructFromCall(Object.prototype, true, CreateFrozen({}, ReturnUndef))
431TestConstructFromCall(Object.prototype, true, CreateFrozen({}, ReturnThis))
432TestConstructFromCall(Object.prototype, false, CreateFrozen({}, ReturnNew))
433TestConstructFromCall(prototype, false, CreateFrozen({}, ReturnNewWithProto))
434
435ReturnUndef.prototype = prototype
436ReturnThis.prototype = prototype
437ReturnNew.prototype = prototype
438ReturnNewWithProto.prototype = prototype
439
440TestConstructFromCall(prototype, true, ReturnUndef)
441TestConstructFromCall(prototype, true, ReturnThis)
442TestConstructFromCall(Object.prototype, false, ReturnNew)
443TestConstructFromCall(prototype, false, ReturnNewWithProto)
444
445TestConstructFromCall(Object.prototype, true,
446 Proxy.createFunction(handler, ReturnUndef))
447TestConstructFromCall(Object.prototype, true,
448 Proxy.createFunction(handler, ReturnThis))
449TestConstructFromCall(Object.prototype, false,
450 Proxy.createFunction(handler, ReturnNew))
451TestConstructFromCall(prototype, false,
452 Proxy.createFunction(handler, ReturnNewWithProto))
453
454TestConstructFromCall(prototype, true,
455 Proxy.createFunction(handlerWithPrototype, ReturnUndef))
456TestConstructFromCall(prototype, true,
457 Proxy.createFunction(handlerWithPrototype, ReturnThis))
458TestConstructFromCall(Object.prototype, false,
459 Proxy.createFunction(handlerWithPrototype, ReturnNew))
460TestConstructFromCall(prototype, false,
461 Proxy.createFunction(handlerWithPrototype,
462 ReturnNewWithProto))
463
464TestConstructFromCall(prototype, true,
465 CreateFrozen(handlerWithPrototype, ReturnUndef))
466TestConstructFromCall(prototype, true,
467 CreateFrozen(handlerWithPrototype, ReturnThis))
468TestConstructFromCall(Object.prototype, false,
469 CreateFrozen(handlerWithPrototype, ReturnNew))
470TestConstructFromCall(prototype, false,
471 CreateFrozen(handlerWithPrototype, ReturnNewWithProto))
472
473
474
475// Throwing from the construct trap.
476
477function TestConstructThrow(trap) {
478 TestConstructThrow2(Proxy.createFunction({ fix: function() {return {};} },
479 trap))
480 TestConstructThrow2(Proxy.createFunction({ fix: function() {return {};} },
481 function() {},
482 trap))
483}
484
485function TestConstructThrow2(f) {
486 assertThrows(function(){ new f(11) }, "myexn")
487 Object.freeze(f)
488 assertThrows(function(){ new f(11) }, "myexn")
489}
490
491TestConstructThrow(function() { throw "myexn" })
492TestConstructThrow(Proxy.createFunction({}, function() { throw "myexn" }))
493TestConstructThrow(CreateFrozen({}, function() { throw "myexn" }))
494
495
496
497// Using function proxies as getters and setters.
498
499var value
500var receiver
501
502function TestAccessorCall(getterCallTrap, setterCallTrap) {
503 var handler = { fix: function() { return {} } }
504 var pgetter = Proxy.createFunction(handler, getterCallTrap)
505 var psetter = Proxy.createFunction(handler, setterCallTrap)
506
507 var o = {}
508 var oo = Object.create(o)
509 Object.defineProperty(o, "a", {get: pgetter, set: psetter})
510 Object.defineProperty(o, "b", {get: pgetter})
511 Object.defineProperty(o, "c", {set: psetter})
512 Object.defineProperty(o, "3", {get: pgetter, set: psetter})
513 Object.defineProperty(oo, "a", {value: 43})
514
515 receiver = ""
516 assertEquals(42, o.a)
517 assertSame(o, receiver)
518 receiver = ""
519 assertEquals(42, o.b)
520 assertSame(o, receiver)
521 receiver = ""
522 assertEquals(undefined, o.c)
523 assertEquals("", receiver)
524 receiver = ""
525 assertEquals(42, o["a"])
526 assertSame(o, receiver)
527 receiver = ""
528 assertEquals(42, o[3])
529 assertSame(o, receiver)
530
531 receiver = ""
532 assertEquals(43, oo.a)
533 assertEquals("", receiver)
534 receiver = ""
535 assertEquals(42, oo.b)
536 assertSame(oo, receiver)
537 receiver = ""
538 assertEquals(undefined, oo.c)
539 assertEquals("", receiver)
540 receiver = ""
541 assertEquals(43, oo["a"])
542 assertEquals("", receiver)
543 receiver = ""
544 assertEquals(42, oo[3])
545 assertSame(oo, receiver)
546
547 receiver = ""
548 assertEquals(50, o.a = 50)
549 assertSame(o, receiver)
550 assertEquals(50, value)
551 receiver = ""
552 assertEquals(51, o.b = 51)
553 assertEquals("", receiver)
554 assertEquals(50, value) // no setter
555 assertThrows(function() { "use strict"; o.b = 51 }, TypeError)
556 receiver = ""
557 assertEquals(52, o.c = 52)
558 assertSame(o, receiver)
559 assertEquals(52, value)
560 receiver = ""
561 assertEquals(53, o["a"] = 53)
562 assertSame(o, receiver)
563 assertEquals(53, value)
564 receiver = ""
565 assertEquals(54, o[3] = 54)
566 assertSame(o, receiver)
567 assertEquals(54, value)
568
569 value = 0
570 receiver = ""
571 assertEquals(60, oo.a = 60)
572 assertEquals("", receiver)
573 assertEquals(0, value) // oo has own 'a'
574 assertEquals(61, oo.b = 61)
575 assertSame("", receiver)
576 assertEquals(0, value) // no setter
577 assertThrows(function() { "use strict"; oo.b = 61 }, TypeError)
578 receiver = ""
579 assertEquals(62, oo.c = 62)
580 assertSame(oo, receiver)
581 assertEquals(62, value)
582 receiver = ""
583 assertEquals(63, oo["c"] = 63)
584 assertSame(oo, receiver)
585 assertEquals(63, value)
586 receiver = ""
587 assertEquals(64, oo[3] = 64)
588 assertSame(oo, receiver)
589 assertEquals(64, value)
590}
591
592TestAccessorCall(
593 function() { receiver = this; return 42 },
594 function(x) { receiver = this; value = x }
595)
596
597TestAccessorCall(
598 function() { "use strict"; receiver = this; return 42 },
599 function(x) { "use strict"; receiver = this; value = x }
600)
601
602TestAccessorCall(
603 Proxy.createFunction({}, function() { receiver = this; return 42 }),
604 Proxy.createFunction({}, function(x) { receiver = this; value = x })
605)
606
607TestAccessorCall(
608 CreateFrozen({}, function() { receiver = this; return 42 }),
609 CreateFrozen({}, function(x) { receiver = this; value = x })
610)
611
612
613
614// Passing a proxy function to higher-order library functions.
615
616function TestHigherOrder(f) {
617 assertEquals(6, [6, 2].map(f)[0])
618 assertEquals(4, [5, 2].reduce(f, 4))
619 assertTrue([1, 2].some(f))
620 assertEquals("a.b.c", "a.b.c".replace(".", f))
621}
622
623TestHigherOrder(function(x) { return x })
624TestHigherOrder(function(x) { "use strict"; return x })
625TestHigherOrder(Proxy.createFunction({}, function(x) { return x }))
626TestHigherOrder(CreateFrozen({}, function(x) { return x }))
627
628
629
630// TODO(rossberg): Ultimately, I want to have the following test function
631// run through, but it currently fails on so many cases (some not even
632// involving proxies), that I leave that for later...
633/*
634function TestCalls() {
635 var handler = {
636 get: function(r, k) {
637 return k == "length" ? 2 : Function.prototype[k]
638 }
639 }
640 var bind = Function.prototype.bind
641 var o = {}
642
643 var traps = [
644 function(x, y) {
645 return {receiver: this, result: x + y, strict: false}
646 },
647 function(x, y) { "use strict";
648 return {receiver: this, result: x + y, strict: true}
649 },
650 function() {
651 var x = arguments[0], y = arguments[1]
652 return {receiver: this, result: x + y, strict: false}
653 },
654 Proxy.createFunction(handler, function(x, y) {
655 return {receiver: this, result: x + y, strict: false}
656 }),
657 Proxy.createFunction(handler, function() {
658 var x = arguments[0], y = arguments[1]
659 return {receiver: this, result: x + y, strict: false}
660 }),
661 Proxy.createFunction(handler, function(x, y) { "use strict"
662 return {receiver: this, result: x + y, strict: true}
663 }),
664 CreateFrozen(handler, function(x, y) {
665 return {receiver: this, result: x + y, strict: false}
666 }),
667 CreateFrozen(handler, function(x, y) { "use strict"
668 return {receiver: this, result: x + y, strict: true}
669 }),
670 ]
671 var creates = [
672 function(trap) { return trap },
673 function(trap) { return CreateFrozen({}, callTrap) },
674 function(trap) { return Proxy.createFunction(handler, callTrap) },
675 function(trap) {
676 return Proxy.createFunction(handler, CreateFrozen({}, callTrap))
677 },
678 function(trap) {
679 return Proxy.createFunction(handler, Proxy.createFunction(handler, callTrap))
680 },
681 ]
682 var binds = [
683 function(f, o, x, y) { return f },
684 function(f, o, x, y) { return bind.call(f, o) },
685 function(f, o, x, y) { return bind.call(f, o, x) },
686 function(f, o, x, y) { return bind.call(f, o, x, y) },
687 function(f, o, x, y) { return bind.call(f, o, x, y, 5) },
688 function(f, o, x, y) { return bind.call(bind.call(f, o), {}, x, y) },
689 function(f, o, x, y) { return bind.call(bind.call(f, o, x), {}, y) },
690 function(f, o, x, y) { return bind.call(bind.call(f, o, x, y), {}, 5) },
691 ]
692 var calls = [
693 function(f, x, y) { return f(x, y) },
694 function(f, x, y) { var g = f; return g(x, y) },
695 function(f, x, y) { with ({}) return f(x, y) },
696 function(f, x, y) { var g = f; with ({}) return g(x, y) },
697 function(f, x, y, o) { with (o) return f(x, y) },
698 function(f, x, y, o) { return f.call(o, x, y) },
699 function(f, x, y, o) { return f.apply(o, [x, y]) },
700 function(f, x, y, o) { return Function.prototype.call.call(f, o, x, y) },
701 function(f, x, y, o) { return Function.prototype.apply.call(f, o, [x, y]) },
702 function(f, x, y, o) { return %_CallFunction(o, x, y, f) },
703 function(f, x, y, o) { return %Call(o, x, y, f) },
704 function(f, x, y, o) { return %Apply(f, o, [null, x, y, null], 1, 2) },
705 function(f, x, y, o) { return %Apply(f, o, arguments, 2, 2) },
706 function(f, x, y, o) { if (typeof o == "object") return o.f(x, y) },
707 function(f, x, y, o) { if (typeof o == "object") return o["f"](x, y) },
708 function(f, x, y, o) { if (typeof o == "object") return (1, o).f(x, y) },
709 function(f, x, y, o) { if (typeof o == "object") return (1, o)["f"](x, y) },
710 ]
711 var receivers = [o, global_object, undefined, null, 2, "bla", true]
712 var expectedNonStricts = [o, global_object, global_object, global_object]
713
714 for (var t = 0; t < traps.length; ++t) {
715 for (var i = 0; i < creates.length; ++i) {
716 for (var j = 0; j < binds.length; ++j) {
717 for (var k = 0; k < calls.length; ++k) {
718 for (var m = 0; m < receivers.length; ++m) {
719 for (var n = 0; n < receivers.length; ++n) {
720 var bound = receivers[m]
721 var receiver = receivers[n]
722 var func = binds[j](creates[i](traps[t]), bound, 31, 11)
723 var expected = j > 0 ? bound : receiver
724 var expectedNonStrict = expectedNonStricts[j > 0 ? m : n]
725 o.f = func
726 global_object.f = func
727 var x = calls[k](func, 11, 31, receiver)
728 if (x !== undefined) {
729 assertEquals(42, x.result)
730 if (calls[k].length < 4)
731 assertSame(x.strict ? undefined : global_object, x.receiver)
732 else if (x.strict)
733 assertSame(expected, x.receiver)
734 else if (expectedNonStrict === undefined)
735 assertSame(expected, x.receiver.valueOf())
736 else
737 assertSame(expectedNonStrict, x.receiver)
738 }
739 }
740 }
741 }
742 }
743 }
744 }
745}
746
747TestCalls()
748*/