blob: 94de25e3ea7fa1690bea5535bdab0beb963c1be9 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
29
30
31// Helper.
32
33function TestWithProxies(test, x, y, z) {
34 test(Proxy.create, x, y, z)
35 test(function(h) {return Proxy.createFunction(h, function() {})}, x, y, z)
36}
37
38
39
40// Getting.
41
42function TestWithGet(handler) {
43 TestWithProxies(TestWithGet2, handler)
44}
45
46var c = "global"
47var key = ""
48
49function TestWithGet2(create, handler) {
50 var b = "local"
51
52 var p = create(handler)
53 with (p) {
54 assertEquals("onproxy", a)
55 assertEquals("local", b)
56 assertEquals("global", c)
57 }
58
59 var o = Object.create(p, {d: {value: "own"}})
60 with (o) {
61 assertEquals("onproxy", a)
62 assertEquals("local", b)
63 assertEquals("global", c)
64 assertEquals("own", d)
65 }
66}
67
68TestWithGet({
69 get: function(r, k) { key = k; return k === "a" ? "onproxy" : undefined },
70 getPropertyDescriptor: function(k) {
71 key = k;
72 return k === "a" ? {value: "onproxy", configurable: true} : undefined
73 }
74})
75
76TestWithGet({
77 get: function(r, k) { return this.get2(r, k) },
78 get2: function(r, k) { key = k; return k === "a" ? "onproxy" : undefined },
79 getPropertyDescriptor: function(k) {
80 key = k;
81 return k === "a" ? {value: "onproxy", configurable: true} : undefined
82 }
83})
84
85TestWithGet({
86 getPropertyDescriptor: function(k) {
87 key = k;
88 return k === "a" ? {value: "onproxy", configurable: true} : undefined
89 }
90})
91
92TestWithGet({
93 getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) },
94 getPropertyDescriptor2: function(k) {
95 key = k;
96 return k === "a" ? {value: "onproxy", configurable: true} : undefined
97 }
98})
99
100TestWithGet({
101 getPropertyDescriptor: function(k) {
102 key = k;
103 return k === "a" ?
104 {get value() { return "onproxy" }, configurable: true} : undefined
105 }
106})
107
108TestWithGet({
109 get: undefined,
110 getPropertyDescriptor: function(k) {
111 key = k;
112 return k === "a" ? {value: "onproxy", configurable: true} : undefined
113 }
114})
115
116
117
118// Invoking.
119
120function TestWithGetCall(handler) {
121 TestWithProxies(TestWithGetCall2, handler)
122}
123
124var receiver = null
125var c = function() { return "global" }
126
127function TestWithGetCall2(create, handler) {
128 var b = function() { return "local" }
129
130 var p = create(handler)
131 with (p) {
132 receiver = null
133 assertEquals("onproxy", a())
134 assertSame(p, receiver)
135 assertEquals("local", b())
136 assertEquals("global", c())
137 }
138
139 var o = Object.create(p, {d: {value: function() { return "own" }}})
140 with (o) {
141 receiver = null
142 assertEquals("onproxy", a())
143 assertSame(o, receiver)
144 assertEquals("local", b())
145 assertEquals("global", c())
146 assertEquals("own", d())
147 }
148}
149
150function onproxy() { receiver = this; return "onproxy" }
151
152TestWithGetCall({
153 get: function(r, k) { key = k; return k === "a" ? onproxy : undefined },
154 getPropertyDescriptor: function(k) {
155 key = k;
156 return k === "a" ? {value: onproxy, configurable: true} : undefined
157 }
158})
159
160TestWithGetCall({
161 get: function(r, k) { return this.get2(r, k) },
162 get2: function(r, k) { key = k; return k === "a" ? onproxy : undefined },
163 getPropertyDescriptor: function(k) {
164 key = k;
165 return k === "a" ? {value: onproxy, configurable: true} : undefined
166 }
167})
168
169TestWithGetCall({
170 getPropertyDescriptor: function(k) {
171 key = k;
172 return k === "a" ? {value: onproxy, configurable: true} : undefined
173 }
174})
175
176TestWithGetCall({
177 getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) },
178 getPropertyDescriptor2: function(k) {
179 key = k;
180 return k === "a" ? {value: onproxy, configurable: true} : undefined
181 }
182})
183
184TestWithGetCall({
185 getPropertyDescriptor: function(k) {
186 key = k;
187 return k === "a" ?
188 {get value() { return onproxy }, configurable: true} : undefined
189 }
190})
191
192TestWithGetCall({
193 get: undefined,
194 getPropertyDescriptor: function(k) {
195 key = k;
196 return k === "a" ? {value: onproxy, configurable: true} : undefined
197 }
198})
199
200
201function TestWithGetCallThrow(handler) {
202 TestWithProxies(TestWithGetCallThrow2, handler)
203}
204
205function TestWithGetCallThrow2(create, handler) {
206 var b = function() { return "local" }
207
208 var p = create(handler)
209 with (p) {
210 assertThrows(function(){ a() }, "myexn")
211 assertEquals("local", b())
212 assertEquals("global", c())
213 }
214
215 var o = Object.create(p, {d: {value: function() { return "own" }}})
216 with (o) {
217 assertThrows(function(){ a() }, "myexn")
218 assertEquals("local", b())
219 assertEquals("global", c())
220 assertEquals("own", d())
221 }
222}
223
224function onproxythrow() { throw "myexn" }
225
226TestWithGetCallThrow({
227 get: function(r, k) { key = k; return k === "a" ? onproxythrow : undefined },
228 getPropertyDescriptor: function(k) {
229 key = k;
230 return k === "a" ? {value: onproxythrow, configurable: true} : undefined
231 }
232})
233
234TestWithGetCallThrow({
235 get: function(r, k) { return this.get2(r, k) },
236 get2: function(r, k) { key = k; return k === "a" ? onproxythrow : undefined },
237 getPropertyDescriptor: function(k) {
238 key = k;
239 return k === "a" ? {value: onproxythrow, configurable: true} : undefined
240 }
241})
242
243TestWithGetCallThrow({
244 getPropertyDescriptor: function(k) {
245 key = k;
246 return k === "a" ? {value: onproxythrow, configurable: true} : undefined
247 }
248})
249
250TestWithGetCallThrow({
251 getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) },
252 getPropertyDescriptor2: function(k) {
253 key = k;
254 return k === "a" ? {value: onproxythrow, configurable: true} : undefined
255 }
256})
257
258TestWithGetCallThrow({
259 getPropertyDescriptor: function(k) {
260 key = k;
261 return k === "a" ?
262 {get value() { return onproxythrow }, configurable: true} : undefined
263 }
264})
265
266TestWithGetCallThrow({
267 get: undefined,
268 getPropertyDescriptor: function(k) {
269 key = k;
270 return k === "a" ? {value: onproxythrow, configurable: true} : undefined
271 }
272})
273
274
275
276// Setting.
277
278var key
279var val
280
281function TestWithSet(handler, hasSetter) {
282 TestWithProxies(TestWithSet2, handler, hasSetter)
283}
284
285var c = "global"
286
287function TestWithSet2(create, handler, hasSetter) {
288 var b = "local"
289
290 var p = create(handler)
291 key = val = undefined
292 with (p) {
293 a = "set"
294 assertEquals("a", key)
295 assertEquals("set", val)
296 assertEquals("local", b)
297 assertEquals("global", c)
298 b = "local"
299 c = "global"
300 assertEquals("a", key)
301 assertEquals("set", val)
302 }
303
304 if (!hasSetter) return
305
306 var o = Object.create(p, {d: {value: "own"}})
307 key = val = undefined
308 with (o) {
309 a = "set"
310 assertEquals("a", key)
311 assertEquals("set", val)
312 assertEquals("local", b)
313 assertEquals("global", c)
314 assertEquals("own", d)
315 b = "local"
316 c = "global"
317 d = "own"
318 assertEquals("a", key)
319 assertEquals("set", val)
320 }
321}
322
323TestWithSet({
324 set: function(r, k, v) { key = k; val = v; return true },
325 getPropertyDescriptor: function(k) {
326 return k === "a" ? {writable: true, configurable: true} : undefined
327 }
328})
329
330TestWithSet({
331 set: function(r, k, v) { return this.set2(r, k, v) },
332 set2: function(r, k, v) { key = k; val = v; return true },
333 getPropertyDescriptor: function(k) {
334 return k === "a" ? {writable: true, configurable: true} : undefined
335 }
336})
337
338TestWithSet({
339 getPropertyDescriptor: function(k) {
340 return this.getOwnPropertyDescriptor(k)
341 },
342 getOwnPropertyDescriptor: function(k) {
343 return k === "a" ? {writable: true, configurable: true} : undefined
344 },
345 defineProperty: function(k, desc) { key = k; val = desc.value }
346})
347
348TestWithSet({
349 getOwnPropertyDescriptor: function(k) {
350 return this.getPropertyDescriptor2(k)
351 },
352 getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) },
353 getPropertyDescriptor2: function(k) {
354 return k === "a" ? {writable: true, configurable: true} : undefined
355 },
356 defineProperty: function(k, desc) { this.defineProperty2(k, desc) },
357 defineProperty2: function(k, desc) { key = k; val = desc.value }
358})
359
360TestWithSet({
361 getOwnPropertyDescriptor: function(k) {
362 return this.getPropertyDescriptor(k)
363 },
364 getPropertyDescriptor: function(k) {
365 return k === "a" ?
366 {get writable() { return true }, configurable: true} : undefined
367 },
368 defineProperty: function(k, desc) { key = k; val = desc.value }
369})
370
371TestWithSet({
372 getOwnPropertyDescriptor: function(k) {
373 return this.getPropertyDescriptor(k)
374 },
375 getPropertyDescriptor: function(k) {
376 return k === "a" ?
377 {set: function(v) { key = k; val = v }, configurable: true} : undefined
378 }
379}, true)
380
381TestWithSet({
382 getOwnPropertyDescriptor: function(k) {
383 return this.getPropertyDescriptor(k)
384 },
385 getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) },
386 getPropertyDescriptor2: function(k) {
387 return k === "a" ?
388 {set: function(v) { key = k; val = v }, configurable: true} : undefined
389 }
390}, true)
391
392TestWithSet({
393 getOwnPropertyDescriptor: function(k) { return null },
394 getPropertyDescriptor: function(k) {
395 return k === "a" ? {writable: true, configurable: true} : undefined
396 },
397 defineProperty: function(k, desc) { key = k; val = desc.value }
398})
399
400
401function TestWithSetThrow(handler, hasSetter) {
402 TestWithProxies(TestWithSetThrow2, handler, hasSetter)
403}
404
405function TestWithSetThrow2(create, handler, hasSetter) {
406 var p = create(handler)
407 assertThrows(function(){
408 with (p) {
409 a = 1
410 }
411 }, "myexn")
412
413 if (!hasSetter) return
414
415 var o = Object.create(p, {})
416 assertThrows(function(){
417 with (o) {
418 a = 1
419 }
420 }, "myexn")
421}
422
423TestWithSetThrow({
424 set: function(r, k, v) { throw "myexn" },
425 getPropertyDescriptor: function(k) {
426 return k === "a" ? {writable: true, configurable: true} : undefined
427 }
428})
429
430TestWithSetThrow({
431 getPropertyDescriptor: function(k) { throw "myexn" },
432})
433
434TestWithSetThrow({
435 getPropertyDescriptor: function(k) {
436 return k === "a" ? {writable: true, configurable: true} : undefined
437 },
438 defineProperty: function(k, desc) { throw "myexn" }
439})
440
441TestWithSetThrow({
442 getPropertyDescriptor: function(k) {
443 return k === "a" ?
444 {set: function() { throw "myexn" }, configurable: true} : undefined
445 }
446}, true)