OLD | NEW |
| (Empty) |
1 // Copyright 2015 the V8 project authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // Flags: --harmony-proxies --strong-mode | |
6 | |
7 // Forwarding proxies adapted from proposal definition | |
8 function handlerMaker1(obj) { | |
9 return { | |
10 getPropertyDescriptor: function(name) { | |
11 var desc; | |
12 var searchObj = obj; | |
13 while (desc === undefined && searchObj != null) { | |
14 desc = Object.getOwnPropertyDescriptor(searchObj, name); | |
15 searchObj = searchObj.__proto__; | |
16 } | |
17 // a trapping proxy's properties must always be configurable | |
18 if (desc !== undefined) { desc.configurable = true; } | |
19 return desc; | |
20 }, | |
21 fix: function() { | |
22 if (Object.isFrozen(obj)) { | |
23 var result = {}; | |
24 Object.getOwnPropertyNames(obj).forEach(function(name) { | |
25 result[name] = Object.getOwnPropertyDescriptor(obj, name); | |
26 }); | |
27 return result; | |
28 } | |
29 // As long as obj is not frozen, the proxy won't allow itself to be fixed | |
30 return undefined; // will cause a TypeError to be thrown | |
31 } | |
32 }; | |
33 } | |
34 function handlerMaker2(obj) { | |
35 return { | |
36 get: function(receiver, name) { | |
37 return obj[name]; | |
38 }, | |
39 fix: function() { | |
40 if (Object.isFrozen(obj)) { | |
41 var result = {}; | |
42 Object.getOwnPropertyNames(obj).forEach(function(name) { | |
43 result[name] = Object.getOwnPropertyDescriptor(obj, name); | |
44 }); | |
45 return result; | |
46 } | |
47 // As long as obj is not frozen, the proxy won't allow itself to be fixed | |
48 return undefined; // will cause a TypeError to be thrown | |
49 } | |
50 }; | |
51 } | |
52 var baseObj = {}; | |
53 var proxy1 = new Proxy({}, handlerMaker1(baseObj)); | |
54 var proxy2 = new Proxy({}, handlerMaker2(baseObj)); | |
55 var childObj1 = { __proto__: proxy1 }; | |
56 var childObj2 = { __proto__: proxy2 }; | |
57 var childObjAccessor1 = { set foo(_){}, set "1"(_){}, __proto__: proxy1 }; | |
58 var childObjAccessor2 = { set foo(_){}, set "1"(_){}, __proto__: proxy2 }; | |
59 | |
60 (function() { | |
61 "use strong"; | |
62 // TODO(conradw): These asserts are sanity checking V8's proxy implementation. | |
63 // Strong mode semantics for ES6 proxies still need to be explored. | |
64 assertDoesNotThrow(function(){proxy1.foo}); | |
65 assertDoesNotThrow(function(){proxy1[1]}); | |
66 assertDoesNotThrow(function(){proxy2.foo}); | |
67 assertDoesNotThrow(function(){proxy2[1]}); | |
68 assertDoesNotThrow(function(){childObj1.foo}); | |
69 assertDoesNotThrow(function(){childObj1[1]}); | |
70 assertDoesNotThrow(function(){childObj2.foo}); | |
71 assertDoesNotThrow(function(){childObj2[1]}); | |
72 assertThrows(function(){baseObj.foo}, TypeError); | |
73 assertThrows(function(){baseObj[1]}, TypeError); | |
74 assertThrows(function(){childObjAccessor1.foo}, TypeError); | |
75 assertThrows(function(){childObjAccessor1[1]}, TypeError); | |
76 assertThrows(function(){childObjAccessor2.foo}, TypeError); | |
77 assertThrows(function(){childObjAccessor2[1]}, TypeError); | |
78 | |
79 // Once the proxy is no longer trapping, property access should have strong | |
80 // semantics. | |
81 Object.freeze(baseObj); | |
82 | |
83 // TODO(neis): Reenable once proxies properly support freeze. | |
84 // | |
85 // Object.freeze(proxy1); | |
86 // assertThrows(function(){proxy1.foo}, TypeError); | |
87 // assertThrows(function(){proxy1[1]}, TypeError); | |
88 // assertThrows(function(){childObj1.foo}, TypeError); | |
89 // assertThrows(function(){childObj1[1]}, TypeError); | |
90 // assertThrows(function(){childObjAccessor1.foo}, TypeError); | |
91 // assertThrows(function(){childObjAccessor1[1]}, TypeError); | |
92 // | |
93 // Object.freeze(proxy2); | |
94 // assertThrows(function(){proxy2.foo}, TypeError); | |
95 // assertThrows(function(){proxy2[1]}, TypeError); | |
96 // assertThrows(function(){childObj2.foo}, TypeError); | |
97 // assertThrows(function(){childObj2[1]}, TypeError); | |
98 // assertThrows(function(){childObjAccessor2.foo}, TypeError); | |
99 // assertThrows(function(){childObjAccessor2[1]}, TypeError); | |
100 })(); | |
OLD | NEW |