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 11 matching lines...) Expand all Loading... | |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 // Flags: --harmony-proxies | 28 // Flags: --harmony-proxies |
29 | 29 |
30 | 30 |
31 // Helper. | 31 // Helper. |
32 | 32 |
Lasse Reichstein
2011/10/17 12:38:39
I'll undo the manual semicolon insertions so you w
| |
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) { |
35 handler.fix = function() { return { length: { value: 2 } }; }; | |
rossberg
2011/10/17 11:49:08
This shouldn't be necessary, because Object.freeze
Lasse Reichstein
2011/10/17 12:38:39
Ok, removing fix for fix.
| |
36 } | |
35 var f = Proxy.createFunction(handler, callTrap, constructTrap) | 37 var f = Proxy.createFunction(handler, callTrap, constructTrap) |
36 Object.freeze(f) | 38 Object.freeze(f) |
37 return f | 39 return f |
38 } | 40 } |
39 | 41 |
40 | 42 |
41 // Calling (call, Function.prototype.call, Function.prototype.apply, | 43 // Calling (call, Function.prototype.call, Function.prototype.apply, |
42 // Function.prototype.bind). | 44 // Function.prototype.bind). |
43 | 45 |
44 var global_object = this | 46 var global_object = this; |
45 var receiver | 47 var receiver; |
48 | |
49 // Ensures that checking the "length" property of a function proxy doesn't | |
50 // crash due to lack of a [[Get]] method. | |
51 var handler = { | |
rossberg
2011/10/17 11:49:08
Could you move this up to the helpers section?
Lasse Reichstein
2011/10/17 12:38:39
Done.
| |
52 get : function(r, n) { return n == "length" ? 2 : undefined; } | |
53 }; | |
54 | |
46 | 55 |
47 function TestCall(isStrict, callTrap) { | 56 function TestCall(isStrict, callTrap) { |
48 assertEquals(42, callTrap(5, 37)) | 57 assertEquals(42, callTrap(5, 37)); |
49 assertEquals(isStrict ? undefined : global_object, receiver) | 58 assertEquals(isStrict ? undefined : global_object, receiver); |
50 | 59 |
51 var handler = { | 60 var handler = { |
52 get: function(r, k) { | 61 get: function(r, k) { |
53 return k == "length" ? 2 : Function.prototype[k] | 62 return k == "length" ? 2 : Function.prototype[k]; |
54 } | 63 } |
55 } | 64 }; |
56 var f = Proxy.createFunction(handler, callTrap) | 65 var f = Proxy.createFunction(handler, callTrap); |
57 | 66 |
58 receiver = 333 | 67 receiver = 333; |
59 assertEquals(42, f(11, 31)) | 68 assertEquals(42, f(11, 31)); |
60 assertEquals(isStrict ? undefined : global_object, receiver) | 69 assertEquals(isStrict ? undefined : global_object, receiver); |
61 var o = {f: f} | 70 var o = {f: f}; |
62 receiver = 333 | 71 receiver = 333; |
63 assertEquals(42, o.f(10, 32)) | 72 assertEquals(42, o.f(10, 32)); |
64 assertSame(o, receiver) | 73 assertSame(o, receiver); |
65 receiver = 333 | 74 receiver = 333; |
66 assertEquals(42, o["f"](9, 33)) | 75 assertEquals(42, o["f"](9, 33)); |
67 assertSame(o, receiver) | 76 assertSame(o, receiver); |
68 receiver = 333 | 77 receiver = 333; |
69 assertEquals(42, (1, o).f(8, 34)) | 78 assertEquals(42, (1, o).f(8, 34)); |
70 assertSame(o, receiver) | 79 assertSame(o, receiver); |
71 receiver = 333 | 80 receiver = 333; |
72 assertEquals(42, (1, o)["f"](7, 35)) | 81 assertEquals(42, (1, o)["f"](7, 35)); |
73 assertSame(o, receiver) | 82 assertSame(o, receiver); |
74 receiver = 333 | 83 receiver = 333; |
75 assertEquals(42, f.call(o, 32, 10)) | 84 assertEquals(42, f.call(o, 32, 10)); |
76 assertSame(o, receiver) | 85 assertSame(o, receiver); |
77 receiver = 333 | 86 receiver = 333; |
78 assertEquals(42, f.call(null, 33, 9)) | 87 assertEquals(42, f.call(null, 33, 9)); |
79 assertSame(isStrict ? null : global_object, receiver) | 88 assertSame(isStrict ? null : global_object, receiver); |
80 receiver = 333 | 89 receiver = 333; |
81 assertEquals(44, f.call(2, 21, 23)) | 90 assertEquals(44, f.call(2, 21, 23)); |
82 assertSame(2, receiver.valueOf()) | 91 assertSame(2, receiver.valueOf()); |
83 receiver = 333 | 92 receiver = 333; |
84 assertEquals(42, Function.prototype.call.call(f, o, 20, 22)) | 93 assertEquals(42, Function.prototype.call.call(f, o, 20, 22)); |
85 assertSame(o, receiver) | 94 assertSame(o, receiver); |
86 receiver = 333 | 95 receiver = 333; |
87 assertEquals(43, Function.prototype.call.call(f, null, 20, 23)) | 96 assertEquals(43, Function.prototype.call.call(f, null, 20, 23)); |
88 assertSame(isStrict ? null : global_object, receiver) | 97 assertSame(isStrict ? null : global_object, receiver); |
89 assertEquals(44, Function.prototype.call.call(f, 2, 21, 23)) | 98 assertEquals(44, Function.prototype.call.call(f, 2, 21, 23)); |
90 assertEquals(2, receiver.valueOf()) | 99 assertEquals(2, receiver.valueOf()); |
91 receiver = 333 | 100 receiver = 333; |
92 assertEquals(32, f.apply(o, [16, 16])) | 101 assertEquals(32, f.apply(o, [16, 16])); |
93 assertSame(o, receiver) | 102 assertSame(o, receiver); |
94 receiver = 333 | 103 receiver = 333; |
95 assertEquals(32, Function.prototype.apply.call(f, o, [17, 15])) | 104 assertEquals(32, Function.prototype.apply.call(f, o, [17, 15])); |
96 assertSame(o, receiver) | 105 assertSame(o, receiver); |
97 | 106 |
98 var ff = Function.prototype.bind.call(f, o, 12) | 107 var ff = Function.prototype.bind.call(f, o, 12); |
99 assertTrue(ff.length <= 1) // TODO(rossberg): Not spec'ed yet, be lax. | 108 assertTrue(ff.length <= 1); // TODO(rossberg): Not spec'ed yet, be lax. |
100 receiver = 333 | 109 receiver = 333; |
101 assertEquals(42, ff(30)) | 110 assertEquals(42, ff(30)); |
102 assertSame(o, receiver) | 111 assertSame(o, receiver); |
103 receiver = 333 | 112 receiver = 333; |
104 assertEquals(32, Function.prototype.apply.call(ff, {}, [20])) | 113 assertEquals(32, Function.prototype.apply.call(ff, {}, [20])); |
105 assertSame(o, receiver) | 114 assertSame(o, receiver); |
106 | 115 |
107 var fff = Function.prototype.bind.call(ff, o, 30) | 116 var fff = Function.prototype.bind.call(ff, o, 30); |
108 assertEquals(0, fff.length) | 117 assertEquals(0, fff.length); |
109 receiver = 333 | 118 receiver = 333; |
110 assertEquals(42, fff()) | 119 assertEquals(42, fff()); |
111 assertSame(o, receiver) | 120 assertSame(o, receiver); |
112 receiver = 333 | 121 receiver = 333; |
113 assertEquals(42, Function.prototype.call.call(fff, {})) | 122 assertEquals(42, Function.prototype.call.call(fff, {})); |
114 assertSame(o, receiver) | 123 assertSame(o, receiver); |
115 | 124 |
116 var f = CreateFrozen({}, callTrap) | 125 var f = CreateFrozen({}, callTrap); |
117 receiver = 333 | 126 receiver = 333; |
118 assertEquals(42, f(11, 31)) | 127 assertEquals(42, f(11, 31)); |
119 assertSame(isStrict ? undefined : global_object, receiver) | 128 assertSame(isStrict ? undefined : global_object, receiver); |
120 var o = {f: f} | 129 var o = {f: f}; |
121 receiver = 333 | 130 receiver = 333; |
122 assertEquals(42, o.f(10, 32)) | 131 assertEquals(42, o.f(10, 32)); |
123 assertSame(o, receiver) | 132 assertSame(o, receiver); |
124 receiver = 333 | 133 receiver = 333; |
125 assertEquals(42, o["f"](9, 33)) | 134 assertEquals(42, o["f"](9, 33)); |
126 assertSame(o, receiver) | 135 assertSame(o, receiver); |
127 receiver = 333 | 136 receiver = 333; |
128 assertEquals(42, (1, o).f(8, 34)) | 137 assertEquals(42, (1, o).f(8, 34)); |
129 assertSame(o, receiver) | 138 assertSame(o, receiver); |
130 receiver = 333 | 139 receiver = 333; |
131 assertEquals(42, (1, o)["f"](7, 35)) | 140 assertEquals(42, (1, o)["f"](7, 35)); |
132 assertSame(o, receiver) | 141 assertSame(o, receiver); |
133 receiver = 333 | 142 receiver = 333; |
134 assertEquals(42, Function.prototype.call.call(f, o, 20, 22)) | 143 assertEquals(42, Function.prototype.call.call(f, o, 20, 22)); |
135 assertSame(o, receiver) | 144 assertSame(o, receiver); |
136 receiver = 333 | 145 receiver = 333; |
137 assertEquals(32, Function.prototype.apply.call(f, o, [17, 15])) | 146 assertEquals(32, Function.prototype.apply.call(f, o, [17, 15])); |
138 assertSame(o, receiver) | 147 assertSame(o, receiver); |
139 receiver = 333 | 148 receiver = 333; |
140 assertEquals(42, ff(30)) | 149 assertEquals(42, ff(30)); |
141 assertSame(o, receiver) | 150 assertSame(o, receiver); |
142 receiver = 333 | 151 receiver = 333; |
143 assertEquals(32, Function.prototype.apply.call(ff, {}, [20])) | 152 assertEquals(32, Function.prototype.apply.call(ff, {}, [20])); |
144 assertSame(o, receiver) | 153 assertSame(o, receiver); |
145 } | 154 } |
146 | 155 |
147 TestCall(false, function(x, y) { | 156 TestCall(false, function(x, y) { |
148 receiver = this; return x + y | 157 receiver = this; |
149 }) | 158 return x + y; |
159 }); | |
150 | 160 |
151 TestCall(true, function(x, y) { | 161 TestCall(true, function(x, y) { |
152 "use strict"; | 162 "use strict"; |
153 receiver = this; return x + y | 163 receiver = this; |
164 return x + y; | |
165 }); | |
166 | |
167 TestCall(false, function() { | |
168 receiver = this; return arguments[0] + arguments[1]; | |
154 }) | 169 }) |
155 | 170 |
156 TestCall(false, function() { | 171 TestCall(false, Proxy.createFunction(handler, function(x, y) { |
157 receiver = this; return arguments[0] + arguments[1] | 172 receiver = this; |
158 }) | 173 return x + y; |
174 })); | |
159 | 175 |
160 TestCall(false, Proxy.createFunction({}, function(x, y) { | 176 TestCall(true, Proxy.createFunction(handler, function(x, y) { |
161 receiver = this; return x + y | 177 "use strict"; |
162 })) | 178 receiver = this; |
179 return x + y; | |
180 })); | |
163 | 181 |
164 TestCall(true, Proxy.createFunction({}, function(x, y) { | 182 TestCall(false, CreateFrozen(handler, function(x, y) { |
165 "use strict"; | 183 receiver = this; |
166 receiver = this; return x + y | 184 return x + y; |
167 })) | 185 })); |
168 | |
169 TestCall(false, CreateFrozen({}, function(x, y) { | |
170 receiver = this; return x + y | |
171 })) | |
172 | 186 |
173 | 187 |
174 | 188 |
175 // Using intrinsics as call traps. | 189 // Using intrinsics as call traps. |
176 | 190 |
177 function TestCallIntrinsic(type, callTrap) { | 191 function TestCallIntrinsic(type, callTrap) { |
178 var f = Proxy.createFunction({}, callTrap) | 192 var f = Proxy.createFunction({}, callTrap) |
179 var x = f() | 193 var x = f() |
180 assertTrue(typeof x == type) | 194 assertTrue(typeof x == type) |
181 } | 195 } |
182 | 196 |
183 TestCallIntrinsic("boolean", Boolean) | 197 TestCallIntrinsic("boolean", Boolean) |
184 TestCallIntrinsic("number", Number) | 198 TestCallIntrinsic("number", Number) |
185 TestCallIntrinsic("string", String) | 199 TestCallIntrinsic("string", String) |
186 TestCallIntrinsic("object", Object) | 200 TestCallIntrinsic("object", Object) |
187 TestCallIntrinsic("function", Function) | 201 TestCallIntrinsic("function", Function) |
188 | 202 |
189 | 203 |
190 | 204 |
191 // Throwing from call trap. | 205 // Throwing from call trap. |
192 | 206 |
193 function TestCallThrow(callTrap) { | 207 function TestCallThrow(callTrap) { |
194 var f = Proxy.createFunction({}, callTrap) | 208 var f = Proxy.createFunction(handler, callTrap); |
rossberg
2011/10/17 11:49:08
None of this should actually need the length prope
Lasse Reichstein
2011/10/17 12:38:39
Right, no call to bind here. Undoing.
| |
195 assertThrows(function(){ f(11) }, "myexn") | 209 assertThrows(function(){ f(11) }, "myexn"); |
196 assertThrows(function(){ ({x: f}).x(11) }, "myexn") | 210 assertThrows(function(){ ({x: f}).x(11) }, "myexn"); |
197 assertThrows(function(){ ({x: f})["x"](11) }, "myexn") | 211 assertThrows(function(){ ({x: f})["x"](11) }, "myexn"); |
198 assertThrows(function(){ Function.prototype.call.call(f, {}, 2) }, "myexn") | 212 assertThrows(function(){ Function.prototype.call.call(f, {}, 2) }, "myexn"); |
199 assertThrows(function(){ Function.prototype.apply.call(f, {}, [1]) }, "myexn") | 213 assertThrows(function(){ Function.prototype.apply.call(f, {}, [1]) }, "myexn") ; |
200 | 214 |
201 var f = CreateFrozen({}, callTrap) | 215 var f = CreateFrozen(handler, callTrap); |
202 assertThrows(function(){ f(11) }, "myexn") | 216 assertThrows(function(){ f(11) }, "myexn"); |
203 assertThrows(function(){ ({x: f}).x(11) }, "myexn") | 217 assertThrows(function(){ ({x: f}).x(11) }, "myexn"); |
204 assertThrows(function(){ ({x: f})["x"](11) }, "myexn") | 218 assertThrows(function(){ ({x: f})["x"](11) }, "myexn"); |
205 assertThrows(function(){ Function.prototype.call.call(f, {}, 2) }, "myexn") | 219 assertThrows(function(){ Function.prototype.call.call(f, {}, 2) }, "myexn"); |
206 assertThrows(function(){ Function.prototype.apply.call(f, {}, [1]) }, "myexn") | 220 assertThrows(function(){ Function.prototype.apply.call(f, {}, [1]) }, "myexn") ; |
207 } | 221 } |
208 | 222 |
209 TestCallThrow(function() { throw "myexn" }) | 223 TestCallThrow(function() { throw "myexn"; }); |
210 TestCallThrow(Proxy.createFunction({}, function() { throw "myexn" })) | 224 TestCallThrow(Proxy.createFunction(handler, function() { throw "myexn"; })); |
211 TestCallThrow(CreateFrozen({}, function() { throw "myexn" })) | 225 TestCallThrow(CreateFrozen(handler, function() { throw "myexn"; })); |
212 | 226 |
213 | 227 |
214 | 228 |
215 // Construction (new). | 229 // Construction (new). |
216 | 230 |
217 var prototype = {} | 231 var prototype = {}; |
218 var receiver | 232 var receiver; |
219 | 233 |
220 var handlerWithPrototype = { | 234 var handlerWithPrototype = { |
221 fix: function() { return {prototype: prototype} }, | 235 fix: function() { |
222 get: function(r, n) { assertEquals("prototype", n); return prototype } | 236 return { length: {value: 2}, |
237 prototype: { value: prototype } } | |
238 }, | |
239 get: function(r, n) { | |
240 if (n == "length") return 2; | |
241 assertEquals("prototype", n); | |
242 return prototype; | |
243 } | |
244 }; | |
245 | |
246 var handlerSansPrototype = { | |
247 fix: function() { return { length: { value: 2 } }; }, | |
Lasse Reichstein
2011/10/17 12:38:39
Removing length from fix here too.
| |
248 get: function(r, n) { | |
249 if (n == "length") return 2; | |
250 assertEquals("prototype", n); | |
251 return undefined; | |
252 } | |
253 }; | |
254 | |
255 function ReturnUndef(x, y) { | |
256 "use strict"; | |
257 receiver = this; | |
258 this.sum = x + y; | |
223 } | 259 } |
224 | 260 |
225 var handlerSansPrototype = { | 261 function ReturnThis(x, y) { |
226 fix: function() { return {} }, | 262 "use strict"; |
227 get: function(r, n) { assertEquals("prototype", n); return undefined } | 263 receiver = this; |
264 this.sum = x + y; | |
265 return this; | |
228 } | 266 } |
229 | 267 |
230 function ReturnUndef(x, y) { "use strict"; receiver = this; this.sum = x + y } | 268 function ReturnNew(x, y) { |
231 function ReturnThis(x, y) { "use strict"; receiver = this; this.sum = x + y; ret urn this } | 269 "use strict"; |
232 function ReturnNew(x, y) { "use strict"; receiver = this; return {sum: x + y} } | 270 receiver = this; |
271 return {sum: x + y}; | |
272 } | |
273 | |
233 function ReturnNewWithProto(x, y) { | 274 function ReturnNewWithProto(x, y) { |
234 "use strict"; | 275 "use strict"; |
235 receiver = this; | 276 receiver = this; |
236 var result = Object.create(prototype) | 277 var result = Object.create(prototype) |
237 result.sum = x + y | 278 result.sum = x + y |
238 return result | 279 return result |
239 } | 280 } |
240 | 281 |
241 function TestConstruct(proto, constructTrap) { | 282 function TestConstruct(proto, constructTrap) { |
242 TestConstruct2(proto, constructTrap, handlerWithPrototype) | 283 TestConstruct2(proto, constructTrap, handlerWithPrototype); |
243 TestConstruct2(proto, constructTrap, handlerSansPrototype) | 284 TestConstruct2(proto, constructTrap, handlerSansPrototype); |
244 } | 285 } |
245 | 286 |
246 function TestConstruct2(proto, constructTrap, handler) { | 287 function TestConstruct2(proto, constructTrap, handler) { |
247 var f = Proxy.createFunction(handler, function() {}, constructTrap) | 288 var f = Proxy.createFunction(handler, function() {}, constructTrap); |
248 var o = new f(11, 31) | 289 var o = new f(11, 31); |
249 assertEquals(undefined, receiver) | 290 assertEquals(undefined, receiver); |
250 assertEquals(42, o.sum) | 291 assertEquals(42, o.sum); |
251 assertSame(proto, Object.getPrototypeOf(o)) | 292 assertSame(proto, Object.getPrototypeOf(o)); |
252 | 293 |
253 // TODO(rossberg): does not work yet. | 294 // TODO(rossberg): does not work yet. |
254 // var ff = Function.prototype.bind.call(f, o, 10) | 295 // var ff = Function.prototype.bind.call(f, o, 10) |
255 // var o = new ff(32) | 296 // var o = new ff(32) |
256 // assertEquals(undefined, receiver) | 297 // assertEquals(undefined, receiver) |
257 // assertEquals(42, o.sum) | 298 // assertEquals(42, o.sum) |
258 // assertSame(proto, Object.getPrototypeOf(o)) | 299 // assertSame(proto, Object.getPrototypeOf(o)) |
259 | 300 |
260 var f = CreateFrozen(handler, function() {}, constructTrap) | 301 var f = CreateFrozen(handler, function() {}, constructTrap); |
261 var o = new f(11, 32) | 302 var o = new f(11, 32); |
262 assertEquals(undefined, receiver) | 303 assertEquals(undefined, receiver); |
263 assertEquals(43, o.sum) | 304 assertEquals(43, o.sum); |
264 assertSame(proto, Object.getPrototypeOf(o)) | 305 assertSame(proto, Object.getPrototypeOf(o)); |
265 | 306 |
266 var ff = Function.prototype.bind.call(f, o, 10) | 307 var ff = Function.prototype.bind.call(f, o, 10); |
267 var o = new ff(32) | 308 var o = new ff(32); |
268 assertEquals(undefined, receiver) | 309 assertEquals(undefined, receiver); |
269 assertEquals(42, o.sum) | 310 assertEquals(42, o.sum); |
270 assertSame(proto, Object.getPrototypeOf(o)) | 311 assertSame(proto, Object.getPrototypeOf(o)); |
271 } | 312 } |
272 | 313 |
273 TestConstruct(Object.prototype, ReturnNew) | 314 TestConstruct(Object.prototype, ReturnNew); |
274 TestConstruct(prototype, ReturnNewWithProto) | 315 TestConstruct(prototype, ReturnNewWithProto); |
275 | 316 |
276 TestConstruct(Object.prototype, Proxy.createFunction({}, ReturnNew)) | 317 TestConstruct(Object.prototype, Proxy.createFunction(handler, ReturnNew)); |
277 TestConstruct(prototype, Proxy.createFunction({}, ReturnNewWithProto)) | 318 TestConstruct(prototype, Proxy.createFunction(handler, ReturnNewWithProto)); |
278 | 319 |
279 TestConstruct(Object.prototype, CreateFrozen({}, ReturnNew)) | 320 TestConstruct(Object.prototype, CreateFrozen(handler, ReturnNew)); |
280 TestConstruct(prototype, CreateFrozen({}, ReturnNewWithProto)) | 321 TestConstruct(prototype, CreateFrozen(handler, ReturnNewWithProto)); |
281 | 322 |
282 | 323 |
283 | 324 |
284 // Construction with derived construct trap. | 325 // Construction with derived construct trap. |
285 | 326 |
286 function TestConstructFromCall(proto, returnsThis, callTrap) { | 327 function TestConstructFromCall(proto, returnsThis, callTrap) { |
287 TestConstructFromCall2(proto, returnsThis, callTrap, handlerWithPrototype) | 328 TestConstructFromCall2(proto, returnsThis, callTrap, handlerWithPrototype); |
288 TestConstructFromCall2(proto, returnsThis, callTrap, handlerSansPrototype) | 329 TestConstructFromCall2(proto, returnsThis, callTrap, handlerSansPrototype); |
289 } | 330 } |
290 | 331 |
291 function TestConstructFromCall2(proto, returnsThis, callTrap, handler) { | 332 function TestConstructFromCall2(proto, returnsThis, callTrap, handler) { |
292 var f = Proxy.createFunction(handler, callTrap) | 333 var f = Proxy.createFunction(handler, callTrap); |
293 var o = new f(11, 31) | 334 var o = new f(11, 31); |
294 if (returnsThis) assertEquals(o, receiver) | 335 if (returnsThis) assertEquals(o, receiver); |
295 assertEquals(42, o.sum) | 336 assertEquals(42, o.sum); |
296 assertSame(proto, Object.getPrototypeOf(o)) | 337 assertSame(proto, Object.getPrototypeOf(o)); |
297 | 338 |
298 // TODO(rossberg): does not work yet. | 339 // TODO(rossberg): does not work yet. |
299 // var ff = Function.prototype.bind.call(f, o, 10) | 340 // var ff = Function.prototype.bind.call(f, o, 10) |
300 // var o = new ff(32) | 341 // var o = new ff(32) |
301 // assertEquals(undefined, receiver) | 342 // assertEquals(undefined, receiver) |
302 // assertEquals(42, o.sum) | 343 // assertEquals(42, o.sum) |
303 // assertSame(proto, Object.getPrototypeOf(o)) | 344 // assertSame(proto, Object.getPrototypeOf(o)) |
304 | 345 |
305 var f = CreateFrozen(handler, callTrap) | 346 var f = CreateFrozen(handler, callTrap); |
306 var o = new f(11, 32) | 347 var o = new f(11, 32); |
307 if (returnsThis) assertEquals(o, receiver) | 348 if (returnsThis) assertEquals(o, receiver); |
308 assertEquals(43, o.sum) | 349 assertEquals(43, o.sum); |
309 assertSame(proto, Object.getPrototypeOf(o)) | 350 assertSame(proto, Object.getPrototypeOf(o)); |
310 | 351 |
311 // TODO(rossberg): does not work yet. | 352 // TODO(rossberg): does not work yet. |
312 // var ff = Function.prototype.bind.call(f, o, 10) | 353 // var ff = Function.prototype.bind.call(f, o, 10) |
313 // var o = new ff(32) | 354 // var o = new ff(32) |
314 // assertEquals(undefined, receiver) | 355 // assertEquals(undefined, receiver) |
315 // assertEquals(42, o.sum) | 356 // assertEquals(42, o.sum) |
316 // assertSame(proto, Object.getPrototypeOf(o)) | 357 // assertSame(proto, Object.getPrototypeOf(o)) |
317 } | 358 } |
318 | 359 |
319 TestConstructFromCall(Object.prototype, true, ReturnUndef) | 360 TestConstructFromCall(Object.prototype, true, ReturnUndef); |
320 TestConstructFromCall(Object.prototype, true, ReturnThis) | 361 TestConstructFromCall(Object.prototype, true, ReturnThis); |
321 TestConstructFromCall(Object.prototype, false, ReturnNew) | 362 TestConstructFromCall(Object.prototype, false, ReturnNew); |
322 TestConstructFromCall(prototype, false, ReturnNewWithProto) | 363 TestConstructFromCall(prototype, false, ReturnNewWithProto); |
323 | 364 |
324 TestConstructFromCall(Object.prototype, true, Proxy.createFunction({}, ReturnUnd ef)) | 365 TestConstructFromCall(Object.prototype, true, |
325 TestConstructFromCall(Object.prototype, true, Proxy.createFunction({}, ReturnThi s)) | 366 Proxy.createFunction(handler, ReturnUndef)); |
326 TestConstructFromCall(Object.prototype, false, Proxy.createFunction({}, ReturnNe w)) | 367 TestConstructFromCall(Object.prototype, true, |
327 TestConstructFromCall(prototype, false, Proxy.createFunction({}, ReturnNewWithPr oto)) | 368 Proxy.createFunction(handler, ReturnThis)); |
369 TestConstructFromCall(Object.prototype, false, | |
370 Proxy.createFunction(handler, ReturnNew)); | |
371 TestConstructFromCall(prototype, false, | |
372 Proxy.createFunction(handler, ReturnNewWithProto)); | |
328 | 373 |
329 TestConstructFromCall(Object.prototype, true, CreateFrozen({}, ReturnUndef)) | 374 TestConstructFromCall(Object.prototype, true, CreateFrozen({}, ReturnUndef)); |
330 TestConstructFromCall(Object.prototype, true, CreateFrozen({}, ReturnThis)) | 375 TestConstructFromCall(Object.prototype, true, CreateFrozen({}, ReturnThis)); |
331 TestConstructFromCall(Object.prototype, false, CreateFrozen({}, ReturnNew)) | 376 TestConstructFromCall(Object.prototype, false, CreateFrozen({}, ReturnNew)); |
332 TestConstructFromCall(prototype, false, CreateFrozen({}, ReturnNewWithProto)) | 377 TestConstructFromCall(prototype, false, CreateFrozen({}, ReturnNewWithProto)); |
333 | 378 |
334 ReturnUndef.prototype = prototype | 379 ReturnUndef.prototype = prototype; |
335 ReturnThis.prototype = prototype | 380 ReturnThis.prototype = prototype; |
336 ReturnNew.prototype = prototype | 381 ReturnNew.prototype = prototype; |
337 ReturnNewWithProto.prototype = prototype | 382 ReturnNewWithProto.prototype = prototype; |
338 | 383 |
339 TestConstructFromCall(prototype, true, ReturnUndef) | 384 TestConstructFromCall(prototype, true, ReturnUndef); |
340 TestConstructFromCall(prototype, true, ReturnThis) | 385 TestConstructFromCall(prototype, true, ReturnThis); |
341 TestConstructFromCall(Object.prototype, false, ReturnNew) | 386 TestConstructFromCall(Object.prototype, false, ReturnNew); |
342 TestConstructFromCall(prototype, false, ReturnNewWithProto) | 387 TestConstructFromCall(prototype, false, ReturnNewWithProto); |
343 | 388 |
344 TestConstructFromCall(Object.prototype, true, Proxy.createFunction({}, ReturnUnd ef)) | 389 TestConstructFromCall(Object.prototype, true, |
345 TestConstructFromCall(Object.prototype, true, Proxy.createFunction({}, ReturnThi s)) | 390 Proxy.createFunction(handler, ReturnUndef)); |
346 TestConstructFromCall(Object.prototype, false, Proxy.createFunction({}, ReturnNe w)) | 391 TestConstructFromCall(Object.prototype, true, |
347 TestConstructFromCall(prototype, false, Proxy.createFunction({}, ReturnNewWithPr oto)) | 392 Proxy.createFunction(handler, ReturnThis)); |
393 TestConstructFromCall(Object.prototype, false, | |
394 Proxy.createFunction(handler, ReturnNew)); | |
395 TestConstructFromCall(prototype, false, | |
396 Proxy.createFunction(handler, ReturnNewWithProto)); | |
348 | 397 |
349 TestConstructFromCall(prototype, true, Proxy.createFunction(handlerWithPrototype , ReturnUndef)) | 398 TestConstructFromCall(prototype, true, |
350 TestConstructFromCall(prototype, true, Proxy.createFunction(handlerWithPrototype , ReturnThis)) | 399 Proxy.createFunction(handlerWithPrototype, ReturnUndef)); |
351 TestConstructFromCall(Object.prototype, false, Proxy.createFunction(handlerWithP rototype, ReturnNew)) | 400 TestConstructFromCall(prototype, true, |
352 TestConstructFromCall(prototype, false, Proxy.createFunction(handlerWithPrototyp e, ReturnNewWithProto)) | 401 Proxy.createFunction(handlerWithPrototype, ReturnThis)); |
402 TestConstructFromCall(Object.prototype, false, | |
403 Proxy.createFunction(handlerWithPrototype, ReturnNew)); | |
404 TestConstructFromCall(prototype, false, | |
405 Proxy.createFunction(handlerWithPrototype, | |
406 ReturnNewWithProto)); | |
353 | 407 |
354 TestConstructFromCall(prototype, true, CreateFrozen(handlerWithPrototype, Return Undef)) | 408 TestConstructFromCall(prototype, true, |
355 TestConstructFromCall(prototype, true, CreateFrozen(handlerWithPrototype, Return This)) | 409 CreateFrozen(handlerWithPrototype, ReturnUndef)); |
356 TestConstructFromCall(Object.prototype, false, CreateFrozen(handlerWithPrototype , ReturnNew)) | 410 TestConstructFromCall(prototype, true, |
357 TestConstructFromCall(prototype, false, CreateFrozen(handlerWithPrototype, Retur nNewWithProto)) | 411 CreateFrozen(handlerWithPrototype, ReturnThis)); |
412 TestConstructFromCall(Object.prototype, false, | |
413 CreateFrozen(handlerWithPrototype, ReturnNew)); | |
414 TestConstructFromCall(prototype, false, | |
415 CreateFrozen(handlerWithPrototype, ReturnNewWithProto)); | |
358 | 416 |
359 | 417 |
360 | 418 |
361 // Throwing from the construct trap. | 419 // Throwing from the construct trap. |
362 | 420 |
363 function TestConstructThrow(trap) { | 421 function TestConstructThrow(trap) { |
364 TestConstructThrow2(Proxy.createFunction({fix: function() {return {}}}, trap)) | 422 TestConstructThrow2(Proxy.createFunction({ fix: function() {return {};} }, |
365 TestConstructThrow2(Proxy.createFunction({fix: function() {return {}}}, | 423 trap)); |
366 function() {}, trap)) | 424 TestConstructThrow2(Proxy.createFunction({ fix: function() {return {};} }, |
425 function() {}, | |
426 trap)); | |
367 } | 427 } |
368 | 428 |
369 function TestConstructThrow2(f) { | 429 function TestConstructThrow2(f) { |
370 assertThrows(function(){ new f(11) }, "myexn") | 430 assertThrows(function(){ new f(11) }, "myexn"); |
371 Object.freeze(f) | 431 Object.freeze(f); |
372 assertThrows(function(){ new f(11) }, "myexn") | 432 assertThrows(function(){ new f(11) }, "myexn"); |
373 } | 433 } |
374 | 434 |
375 TestConstructThrow(function() { throw "myexn" }) | 435 TestConstructThrow(function() { throw "myexn"; }); |
376 TestConstructThrow(Proxy.createFunction({}, function() { throw "myexn" })) | 436 TestConstructThrow(Proxy.createFunction({}, function() { throw "myexn"; })); |
377 TestConstructThrow(CreateFrozen({}, function() { throw "myexn" })) | 437 TestConstructThrow(CreateFrozen({}, function() { throw "myexn"; })); |
378 | 438 |
379 | 439 |
380 | 440 |
381 // Using function proxies as getters and setters. | 441 // Using function proxies as getters and setters. |
382 | 442 |
383 var value | 443 var value; |
384 var receiver | 444 var receiver; |
385 | 445 |
386 function TestAccessorCall(getterCallTrap, setterCallTrap) { | 446 function TestAccessorCall(getterCallTrap, setterCallTrap) { |
387 var handler = {fix: function() { return {} }} | 447 var handler = { fix: function() { return {}; } }; |
388 var pgetter = Proxy.createFunction(handler, getterCallTrap) | 448 var pgetter = Proxy.createFunction(handler, getterCallTrap); |
389 var psetter = Proxy.createFunction(handler, setterCallTrap) | 449 var psetter = Proxy.createFunction(handler, setterCallTrap); |
390 | 450 |
391 var o = {} | 451 var o = {}; |
392 var oo = Object.create(o) | 452 var oo = Object.create(o); |
393 Object.defineProperty(o, "a", {get: pgetter, set: psetter}) | 453 Object.defineProperty(o, "a", {get: pgetter, set: psetter}); |
394 Object.defineProperty(o, "b", {get: pgetter}) | 454 Object.defineProperty(o, "b", {get: pgetter}); |
395 Object.defineProperty(o, "c", {set: psetter}) | 455 Object.defineProperty(o, "c", {set: psetter}); |
396 Object.defineProperty(o, "3", {get: pgetter, set: psetter}) | 456 Object.defineProperty(o, "3", {get: pgetter, set: psetter}); |
397 Object.defineProperty(oo, "a", {value: 43}) | 457 Object.defineProperty(oo, "a", {value: 43}); |
398 | 458 |
399 receiver = "" | 459 receiver = ""; |
400 assertEquals(42, o.a) | 460 assertEquals(42, o.a); |
401 assertSame(o, receiver) | 461 assertSame(o, receiver); |
402 receiver = "" | 462 receiver = ""; |
403 assertEquals(42, o.b) | 463 assertEquals(42, o.b); |
404 assertSame(o, receiver) | 464 assertSame(o, receiver); |
405 receiver = "" | 465 receiver = ""; |
406 assertEquals(undefined, o.c) | 466 assertEquals(undefined, o.c); |
407 assertEquals("", receiver) | 467 assertEquals("", receiver); |
408 receiver = "" | 468 receiver = ""; |
409 assertEquals(42, o["a"]) | 469 assertEquals(42, o["a"]); |
410 assertSame(o, receiver) | 470 assertSame(o, receiver); |
411 receiver = "" | 471 receiver = ""; |
412 assertEquals(42, o[3]) | 472 assertEquals(42, o[3]); |
413 assertSame(o, receiver) | 473 assertSame(o, receiver); |
414 | 474 |
415 receiver = "" | 475 receiver = ""; |
416 assertEquals(43, oo.a) | 476 assertEquals(43, oo.a); |
417 assertEquals("", receiver) | 477 assertEquals("", receiver); |
418 receiver = "" | 478 receiver = ""; |
419 assertEquals(42, oo.b) | 479 assertEquals(42, oo.b); |
420 assertSame(o, receiver) | 480 assertSame(o, receiver); |
421 receiver = "" | 481 receiver = ""; |
422 assertEquals(undefined, oo.c) | 482 assertEquals(undefined, oo.c); |
423 assertEquals("", receiver) | 483 assertEquals("", receiver); |
424 receiver = "" | 484 receiver = ""; |
425 assertEquals(43, oo["a"]) | 485 assertEquals(43, oo["a"]); |
426 assertEquals("", receiver) | 486 assertEquals("", receiver); |
427 receiver = "" | 487 receiver = ""; |
428 assertEquals(42, oo[3]) | 488 assertEquals(42, oo[3]); |
429 assertSame(o, receiver) | 489 assertSame(o, receiver); |
430 | 490 |
431 receiver = "" | 491 receiver = ""; |
432 assertEquals(50, o.a = 50) | 492 assertEquals(50, o.a = 50); |
433 assertSame(o, receiver) | 493 assertSame(o, receiver); |
434 assertEquals(50, value) | 494 assertEquals(50, value); |
435 receiver = "" | 495 receiver = ""; |
436 assertEquals(51, o.b = 51) | 496 assertEquals(51, o.b = 51); |
437 assertEquals("", receiver) | 497 assertEquals("", receiver); |
438 assertEquals(50, value) // no setter | 498 assertEquals(50, value); // no setter |
439 assertThrows(function() { "use strict"; o.b = 51 }, TypeError) | 499 assertThrows(function() { "use strict"; o.b = 51 }, TypeError); |
440 receiver = "" | 500 receiver = ""; |
441 assertEquals(52, o.c = 52) | 501 assertEquals(52, o.c = 52); |
442 assertSame(o, receiver) | 502 assertSame(o, receiver); |
443 assertEquals(52, value) | 503 assertEquals(52, value); |
444 receiver = "" | 504 receiver = ""; |
445 assertEquals(53, o["a"] = 53) | 505 assertEquals(53, o["a"] = 53); |
446 assertSame(o, receiver) | 506 assertSame(o, receiver); |
447 assertEquals(53, value) | 507 assertEquals(53, value); |
448 receiver = "" | 508 receiver = ""; |
449 assertEquals(54, o[3] = 54) | 509 assertEquals(54, o[3] = 54); |
450 assertSame(o, receiver) | 510 assertSame(o, receiver); |
451 assertEquals(54, value) | 511 assertEquals(54, value); |
452 | 512 |
453 value = 0 | 513 value = 0; |
454 receiver = "" | 514 receiver = ""; |
455 assertEquals(60, oo.a = 60) | 515 assertEquals(60, oo.a = 60); |
456 assertEquals("", receiver) | 516 assertEquals("", receiver); |
457 assertEquals(0, value) // oo has own 'a' | 517 assertEquals(0, value); // oo has own 'a' |
458 assertEquals(61, oo.b = 61) | 518 assertEquals(61, oo.b = 61); |
459 assertSame("", receiver) | 519 assertSame("", receiver); |
460 assertEquals(0, value) // no setter | 520 assertEquals(0, value); // no setter |
461 assertThrows(function() { "use strict"; oo.b = 61 }, TypeError) | 521 assertThrows(function() { "use strict"; oo.b = 61; }, TypeError); |
462 receiver = "" | 522 receiver = ""; |
463 assertEquals(62, oo.c = 62) | 523 assertEquals(62, oo.c = 62); |
464 assertSame(oo, receiver) | 524 assertSame(oo, receiver); |
465 assertEquals(62, value) | 525 assertEquals(62, value); |
466 receiver = "" | 526 receiver = ""; |
467 assertEquals(63, oo["c"] = 63) | 527 assertEquals(63, oo["c"] = 63); |
468 assertSame(oo, receiver) | 528 assertSame(oo, receiver); |
469 assertEquals(63, value) | 529 assertEquals(63, value); |
470 receiver = "" | 530 receiver = ""; |
471 assertEquals(64, oo[3] = 64) | 531 assertEquals(64, oo[3] = 64); |
472 assertSame(oo, receiver) | 532 assertSame(oo, receiver); |
473 assertEquals(64, value) | 533 assertEquals(64, value); |
474 } | 534 } |
475 | 535 |
476 TestAccessorCall( | 536 TestAccessorCall( |
477 function() { receiver = this; return 42 }, | 537 function() { receiver = this; return 42; }, |
478 function(x) { receiver = this; value = x } | 538 function(x) { receiver = this; value = x; } |
479 ) | 539 ); |
480 | 540 |
481 TestAccessorCall( | 541 TestAccessorCall( |
482 function() { "use strict"; receiver = this; return 42 }, | 542 function() { "use strict"; receiver = this; return 42; }, |
483 function(x) { "use strict"; receiver = this; value = x } | 543 function(x) { "use strict"; receiver = this; value = x; } |
484 ) | 544 ); |
485 | 545 |
486 TestAccessorCall( | 546 TestAccessorCall( |
487 Proxy.createFunction({}, function() { receiver = this; return 42 }), | 547 Proxy.createFunction({}, function() { receiver = this; return 42; }), |
488 Proxy.createFunction({}, function(x) { receiver = this; value = x }) | 548 Proxy.createFunction({}, function(x) { receiver = this; value = x; }) |
489 ) | 549 ); |
490 | 550 |
491 TestAccessorCall( | 551 TestAccessorCall( |
492 CreateFrozen({}, function() { receiver = this; return 42 }), | 552 CreateFrozen({}, function() { receiver = this; return 42; }), |
493 CreateFrozen({}, function(x) { receiver = this; value = x }) | 553 CreateFrozen({}, function(x) { receiver = this; value = x; }) |
494 ) | 554 ); |
OLD | NEW |