Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(284)

Side by Side Diff: test/mjsunit/harmony/proxies-example-membrane.js

Issue 1784203003: Adapt membrane example to ES6 proxies. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | test/mjsunit/mjsunit.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 10 matching lines...) Expand all
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
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 --harmony-proxies 28 // Flags: --harmony --harmony-proxies
29 29
30 30
31 // A simple no-op handler. Adapted from:
32 // http://wiki.ecmascript.org/doku.php?id=harmony:proxies#examplea_no-op_forward ing_proxy
33
34 function createHandler(obj) {
35 return {
36 getOwnPropertyDescriptor: function(name) {
37 var desc = Object.getOwnPropertyDescriptor(obj, name);
38 if (desc !== undefined) desc.configurable = true;
39 return desc;
40 },
41 getPropertyDescriptor: function(name) {
42 var desc = Object.getOwnPropertyDescriptor(obj, name);
43 //var desc = Object.getPropertyDescriptor(obj, name); // not in ES5
44 if (desc !== undefined) desc.configurable = true;
45 return desc;
46 },
47 getOwnPropertyNames: function() {
48 return Object.getOwnPropertyNames(obj);
49 },
50 getPropertyNames: function() {
51 return Object.getOwnPropertyNames(obj);
52 //return Object.getPropertyNames(obj); // not in ES5
53 },
54 defineProperty: function(name, desc) {
55 Object.defineProperty(obj, name, desc);
56 },
57 delete: function(name) {
58 return delete obj[name];
59 },
60 fix: function() {
61 if (Object.isFrozen(obj)) {
62 var result = {};
63 Object.getOwnPropertyNames(obj).forEach(function(name) {
64 result[name] = Object.getOwnPropertyDescriptor(obj, name);
65 });
66 return result;
67 }
68 // As long as obj is not frozen, the proxy won't allow itself to be fixed
69 return undefined; // will cause a TypeError to be thrown
70 },
71 has: function(name) { return name in obj; },
72 hasOwn: function(name) { return ({}).hasOwnProperty.call(obj, name); },
73 get: function(receiver, name) { return obj[name]; },
74 set: function(receiver, name, val) {
75 obj[name] = val; // bad behavior when set fails in sloppy mode
76 return true;
77 },
78 keys: function() { return Object.keys(obj); }
79 };
80 }
81
82
83
84 // Auxiliary definitions enabling tracking of object identity in output.
85
86 var objectMap = new WeakMap;
87 var objectCounter = 0;
88
89 function registerObject(x, s) {
90 if (x === Object(x) && !objectMap.has(x))
91 objectMap.set(x, ++objectCounter + (s == undefined ? "" : ":" + s));
92 }
93
94 registerObject(this, "global");
95 registerObject(Object.prototype, "Object.prototype");
96
97 function str(x) {
98 if (x === Object(x)) return "[" + typeof x + " " + objectMap.get(x) + "]";
99 if (typeof x == "string") return "\"" + x + "\"";
100 return "" + x;
101 }
102
103
104 31
105 // A simple membrane. Adapted from: 32 // A simple membrane. Adapted from:
106 // http://wiki.ecmascript.org/doku.php?id=harmony:proxies#a_simple_membrane 33 // http://wiki.ecmascript.org/doku.php?id=harmony:proxies#a_simple_membrane
107 34
108 function createSimpleMembrane(target) { 35 function createSimpleMembrane(target) {
109 var enabled = true; 36 let enabled = true;
110 37
111 function wrap(obj) { 38 function wrap(obj) {
112 registerObject(obj); 39 if (obj !== Object(obj)) return obj;
113 print("wrap enter", str(obj)); 40
114 try { 41 let handler = new Proxy({}, {get: function(_, key) {
115 var x = wrap2(obj); 42 if (!enabled) throw new Error("disabled");
116 registerObject(x, "wrapped"); 43 switch (key) {
117 print("wrap exit", str(obj), "as", str(x)); 44 case "apply":
118 return x; 45 return (_, that, args) => {
119 } catch(e) { 46 try {
120 print("wrap exception", str(e)); 47 return wrap(Reflect.apply(
121 throw e; 48 obj, wrap(that), args.map((x) => wrap(x))));
122 } 49 } catch(e) {
50 throw wrap(e);
51 }
52 }
53 case "construct":
54 return (_, args, newt) => {
55 try {
56 return wrap(Reflect.construct(
57 obj, args.map((x) => wrap(x)), wrap(newt)));
58 } catch(e) {
59 throw wrap(e);
60 }
61 }
62 default:
63 return (_, ...args) => {
64 try {
65 return wrap(Reflect[key](obj, ...(args.map(wrap))));
66 } catch(e) {
67 throw wrap(e);
68 }
69 }
70 }
71 }});
72
73 return new Proxy(obj, handler);
123 } 74 }
124 75
125 function wrap2(obj) { 76 const gate = Object.freeze({
126 if (obj !== Object(obj)) { 77 enable: () => enabled = true,
127 return obj; 78 disable: () => enabled = false
128 }
129
130 function wrapCall(fun, that, args) {
131 registerObject(that);
132 print("wrapCall enter", fun, str(that));
133 try {
134 var x = wrapCall2(fun, that, args);
135 print("wrapCall exit", fun, str(that), "returning", str(x));
136 return x;
137 } catch(e) {
138 print("wrapCall exception", fun, str(that), str(e));
139 throw e;
140 }
141 }
142
143 function wrapCall2(fun, that, args) {
144 if (!enabled) { throw new Error("disabled"); }
145 try {
146 return wrap(fun.apply(that, Array.prototype.map.call(args, wrap)));
147 } catch (e) {
148 throw wrap(e);
149 }
150 }
151
152 var baseHandler = createHandler(obj);
153 var handler = new Proxy({}, Object.freeze({
154 get: function(receiver, name) {
155 return function() {
156 var arg = (name === "get" || name == "set") ? arguments[1] : "";
157 print("handler enter", name, arg);
158 var x = wrapCall(baseHandler[name], baseHandler, arguments);
159 print("handler exit", name, arg, "returning", str(x));
160 return x;
161 }
162 }
163 }));
164 registerObject(baseHandler, "basehandler");
165 registerObject(handler, "handler");
166
167 if (typeof obj === "function") {
168 function callTrap() {
169 print("call trap enter", str(obj), str(this));
170 var x = wrapCall(obj, wrap(this), arguments);
171 print("call trap exit", str(obj), str(this), "returning", str(x));
172 return x;
173 }
174 function constructTrap() {
175 if (!enabled) { throw new Error("disabled"); }
176 try {
177 function forward(args) { return obj.apply(this, args) }
178 return wrap(new forward(Array.prototype.map.call(arguments, wrap)));
179 } catch (e) {
180 throw wrap(e);
181 }
182 }
183 return Proxy.createFunction(handler, callTrap, constructTrap);
184 } else {
185 var prototype = wrap(Object.getPrototypeOf(obj));
186 return new Proxy(prototype, handler);
187 }
188 }
189
190 var gate = Object.freeze({
191 enable: function() { enabled = true; },
192 disable: function() { enabled = false; }
193 }); 79 });
194 80
195 return Object.freeze({ 81 return Object.freeze({
196 wrapper: wrap(target), 82 wrapper: wrap(target),
197 gate: gate 83 gate: gate
198 }); 84 });
199 } 85 }
200 86
201 87
202 var o = { 88 // Test the simple membrane.
203 a: 6, 89 {
204 b: {bb: 8}, 90 var o = {
205 f: function(x) { return x }, 91 a: 6,
206 g: function(x) { return x.a }, 92 b: {bb: 8},
207 h: function(x) { this.q = x } 93 f: function(x) { return x },
208 }; 94 g: function(x) { return x.a },
209 o[2] = {c: 7}; 95 h: function(x) { this.q = x }
210 var m = createSimpleMembrane(o); 96 };
211 var w = m.wrapper; 97 o[2] = {c: 7};
212 print("o =", str(o)) 98 var m = createSimpleMembrane(o);
213 print("w =", str(w)); 99 var w = m.wrapper;
214 100 var f = w.f;
215 var f = w.f; 101 var x = f(66);
216 var x = f(66); 102 var x = f({a: 1});
217 var x = f({a: 1}); 103 var x = w.f({a: 1});
218 var x = w.f({a: 1}); 104 var a = x.a;
219 var a = x.a; 105 assertEquals(6, w.a);
220 assertEquals(6, w.a); 106 assertEquals(8, w.b.bb);
221 assertEquals(8, w.b.bb); 107 assertEquals(7, w[2]["c"]);
222 assertEquals(7, w[2]["c"]); 108 assertEquals(undefined, w.c);
223 assertEquals(undefined, w.c); 109 assertEquals(1, w.f(1));
224 assertEquals(1, w.f(1)); 110 assertEquals(1, w.f({a: 1}).a);
225 assertEquals(1, w.f({a: 1}).a); 111 assertEquals(2, w.g({a: 2}));
226 assertEquals(2, w.g({a: 2})); 112 assertEquals(3, (w.r = {a: 3}).a);
227 assertEquals(3, (w.r = {a: 3}).a); 113 assertEquals(3, w.r.a);
228 assertEquals(3, w.r.a); 114 assertEquals(3, o.r.a);
229 assertEquals(3, o.r.a); 115 w.h(3);
230 w.h(3); 116 assertEquals(3, w.q);
231 assertEquals(3, w.q); 117 assertEquals(3, o.q);
232 assertEquals(3, o.q); 118 assertEquals(4, (new w.h(4)).q);
233 assertEquals(4, (new w.h(4)).q); 119
234 120 var wb = w.b;
235 var wb = w.b; 121 var wr = w.r;
236 var wr = w.r; 122 var wf = w.f;
237 var wf = w.f; 123 var wf3 = w.f(3);
238 var wf3 = w.f(3); 124 var wfx = w.f({a: 6});
239 var wfx = w.f({a: 6}); 125 var wgx = w.g({a: {aa: 7}});
240 var wgx = w.g({a: {aa: 7}}); 126 var wh4 = new w.h(4);
241 var wh4 = new w.h(4); 127 m.gate.disable();
242 m.gate.disable(); 128 assertEquals(3, wf3);
243 assertEquals(3, wf3); 129 assertThrows(function() { w.a }, Error);
244 assertThrows(function() { w.a }, Error); 130 assertThrows(function() { w.r }, Error);
245 assertThrows(function() { w.r }, Error); 131 assertThrows(function() { w.r = {a: 4} }, Error);
246 assertThrows(function() { w.r = {a: 4} }, Error); 132 assertThrows(function() { o.r.a }, Error);
247 assertThrows(function() { o.r.a }, Error); 133 assertEquals("object", typeof o.r);
248 assertEquals("object", typeof o.r); 134 assertEquals(5, (o.r = {a: 5}).a);
249 assertEquals(5, (o.r = {a: 5}).a); 135 assertEquals(5, o.r.a);
250 assertEquals(5, o.r.a); 136 assertThrows(function() { w[1] }, Error);
251 assertThrows(function() { w[1] }, Error); 137 assertThrows(function() { w.c }, Error);
252 assertThrows(function() { w.c }, Error); 138 assertThrows(function() { wb.bb }, Error);
253 assertThrows(function() { wb.bb }, Error); 139 assertThrows(function() { wr.a }, Error);
254 assertThrows(function() { wr.a }, Error); 140 assertThrows(function() { wf(4) }, Error);
255 assertThrows(function() { wf(4) }, Error); 141 assertThrows(function() { wfx.a }, Error);
256 assertThrows(function() { wfx.a }, Error); 142 assertThrows(function() { wgx.aa }, Error);
257 assertThrows(function() { wgx.aa }, Error); 143 assertThrows(function() { wh4.q }, Error);
258 assertThrows(function() { wh4.q }, Error); 144
259 145 m.gate.enable();
260 m.gate.enable(); 146 assertEquals(6, w.a);
261 assertEquals(6, w.a); 147 assertEquals(5, w.r.a);
262 assertEquals(5, w.r.a); 148 assertEquals(5, o.r.a);
263 assertEquals(5, o.r.a); 149 assertEquals(7, w.r = 7);
264 assertEquals(7, w.r = 7); 150 assertEquals(7, w.r);
265 assertEquals(7, w.r); 151 assertEquals(7, o.r);
266 assertEquals(7, o.r); 152 assertEquals(8, w.b.bb);
267 assertEquals(8, w.b.bb); 153 assertEquals(7, w[2]["c"]);
268 assertEquals(7, w[2]["c"]); 154 assertEquals(undefined, w.c);
269 assertEquals(undefined, w.c); 155 assertEquals(8, wb.bb);
270 assertEquals(8, wb.bb); 156 assertEquals(3, wr.a);
271 assertEquals(3, wr.a); 157 assertEquals(4, wf(4));
272 assertEquals(4, wf(4)); 158 assertEquals(3, wf3);
273 assertEquals(3, wf3); 159 assertEquals(6, wfx.a);
274 assertEquals(6, wfx.a); 160 assertEquals(7, wgx.aa);
275 assertEquals(7, wgx.aa); 161 assertEquals(4, wh4.q);
276 assertEquals(4, wh4.q); 162 }
163
277 164
278 165
279 // An identity-preserving membrane. Adapted from: 166 // An identity-preserving membrane. Adapted from:
280 // http://wiki.ecmascript.org/doku.php?id=harmony:proxies#an_identity-preserving _membrane 167 // http://wiki.ecmascript.org/doku.php?id=harmony:proxies#an_identity-preserving _membrane
281 168
282 function createMembrane(wetTarget) { 169 function createMembrane(target) {
283 var wet2dry = new WeakMap(); 170 const wet2dry = 0;
284 var dry2wet = new WeakMap(); 171 const dry2wet = 1;
285 172
286 function asDry(obj) { 173 function flip(dir) { return (dir + 1) % 2 }
287 registerObject(obj) 174
288 print("asDry enter", str(obj)) 175 let maps = [new WeakMap(), new WeakMap()];
289 try { 176
290 var x = asDry2(obj); 177 let revoked = false;
291 registerObject(x, "dry"); 178
292 print("asDry exit", str(obj), "as", str(x)); 179 function wrap(dir, obj) {
293 return x; 180 if (obj !== Object(obj)) return obj;
294 } catch(e) { 181
295 print("asDry exception", str(e)); 182 let wrapper = maps[dir].get(obj);
296 throw e; 183 if (wrapper) return wrapper;
297 } 184
185 let handler = new Proxy({}, {get: function(_, key) {
186 if (revoked) throw new Error("revoked");
187 switch (key) {
188 case "apply":
189 return (_, that, args) => {
190 try {
191 return wrap(dir, Reflect.apply(
192 obj, wrap(flip(dir), that),
193 args.map((x) => wrap(flip(dir), x))));
194 } catch(e) {
195 throw wrap(dir, e);
196 }
197 }
198 case "construct":
199 return (_, args, newt) => {
200 try {
201 return wrap(dir, Reflect.construct(
202 obj, args.map((x) => wrap(flip(dir), x)),
203 wrap(flip(dir), newt)));
204 } catch(e) {
205 throw wrap(dir, e);
206 }
207 }
208 default:
209 return (_, ...args) => {
210 try {
211 return wrap(dir, Reflect[key](
212 obj, ...(args.map((x) => wrap(flip(dir), x)))))
213 } catch(e) {
214 throw wrap(dir, e);
215 }
216 }
217 }
218 }});
219
220 wrapper = new Proxy(obj, handler);
221 maps[dir].set(obj, wrapper);
222 maps[flip(dir)].set(wrapper, obj);
223 return wrapper;
298 } 224 }
299 function asDry2(wet) { 225
300 if (wet !== Object(wet)) { 226 const gate = Object.freeze({
301 // primitives provide only irrevocable knowledge, so don't 227 revoke: () => revoked = true
302 // bother wrapping it. 228 });
303 return wet; 229
304 } 230 return Object.freeze({
305 var dryResult = wet2dry.get(wet); 231 wrapper: wrap(wet2dry, target),
306 if (dryResult) { return dryResult; } 232 gate: gate
307 233 });
308 var wetHandler = createHandler(wet); 234 }
309 var dryRevokeHandler = new Proxy({}, Object.freeze({ 235
310 get: function(receiver, name) { 236
311 return function() { 237 // Test the identity-preserving membrane.
312 var arg = (name === "get" || name == "set") ? arguments[1] : ""; 238 {
313 print("dry handler enter", name, arg); 239 var receiver
314 var optWetHandler = dry2wet.get(dryRevokeHandler); 240 var argument
315 try { 241 var o = {
316 var x = asDry(optWetHandler[name].apply( 242 a: 6,
317 optWetHandler, Array.prototype.map.call(arguments, asWet))); 243 b: {bb: 8},
318 print("dry handler exit", name, arg, "returning", str(x)); 244 f: function(x) {receiver = this; argument = x; return x},
319 return x; 245 g: function(x) {receiver = this; argument = x; return x.a},
320 } catch (eWet) { 246 h: function(x) {receiver = this; argument = x; this.q = x},
321 var x = asDry(eWet); 247 s: function(x) {receiver = this; argument = x; this.x = {y: x}; return this}
322 print("dry handler exception", name, arg, "throwing", str(x));
323 throw x;
324 }
325 };
326 }
327 }));
328 dry2wet.set(dryRevokeHandler, wetHandler);
329
330 if (typeof wet === "function") {
331 function callTrap() {
332 print("dry call trap enter", str(this));
333 var x = asDry(wet.apply(
334 asWet(this), Array.prototype.map.call(arguments, asWet)));
335 print("dry call trap exit", str(this), "returning", str(x));
336 return x;
337 }
338 function constructTrap() {
339 function forward(args) { return wet.apply(this, args) }
340 return asDry(new forward(Array.prototype.map.call(arguments, asWet)));
341 }
342 dryResult =
343 Proxy.createFunction(dryRevokeHandler, callTrap, constructTrap);
344 } else {
345 dryResult =
346 new Proxy(asDry(Object.getPrototypeOf(wet)), dryRevokeHandler);
347 }
348 wet2dry.set(wet, dryResult);
349 dry2wet.set(dryResult, wet);
350 return dryResult;
351 } 248 }
352 249 o[2] = {c: 7}
353 function asWet(obj) { 250 var m = createMembrane(o)
354 registerObject(obj) 251 var w = m.wrapper
355 print("asWet enter", str(obj)) 252 var f = w.f
356 try { 253 var x = f(66)
357 var x = asWet2(obj) 254 var x = f({a: 1})
358 registerObject(x, "wet") 255 var x = w.f({a: 1})
359 print("asWet exit", str(obj), "as", str(x)) 256 var a = x.a
360 return x 257 assertEquals(6, w.a)
361 } catch(e) { 258 assertEquals(8, w.b.bb)
362 print("asWet exception", str(e)) 259 assertEquals(7, w[2]["c"])
363 throw e 260 assertEquals(undefined, w.c)
364 } 261 assertEquals(1, w.f(1))
365 } 262 assertSame(o, receiver)
366 function asWet2(dry) { 263 assertEquals(1, w.f({a: 1}).a)
367 if (dry !== Object(dry)) { 264 assertSame(o, receiver)
368 // primitives provide only irrevocable knowledge, so don't 265 assertEquals(2, w.g({a: 2}))
369 // bother wrapping it. 266 assertSame(o, receiver)
370 return dry; 267 assertSame(w, w.f(w))
371 } 268 assertSame(o, receiver)
372 var wetResult = dry2wet.get(dry); 269 assertSame(o, argument)
373 if (wetResult) { return wetResult; } 270 assertSame(o, w.f(o))
374 271 assertSame(o, receiver)
375 var dryHandler = createHandler(dry); 272 // Note that argument !== o, since o isn't dry, so gets wrapped wet again.
376 var wetRevokeHandler = new Proxy({}, Object.freeze({ 273 assertEquals(3, (w.r = {a: 3}).a)
377 get: function(receiver, name) { 274 assertEquals(3, w.r.a)
378 return function() { 275 assertEquals(3, o.r.a)
379 var arg = (name === "get" || name == "set") ? arguments[1] : ""; 276 w.h(3)
380 print("wet handler enter", name, arg); 277 assertEquals(3, w.q)
381 var optDryHandler = wet2dry.get(wetRevokeHandler); 278 assertEquals(3, o.q)
382 try { 279 assertEquals(4, (new w.h(4)).q)
383 var x = asWet(optDryHandler[name].apply( 280 assertEquals(5, w.s(5).x.y)
384 optDryHandler, Array.prototype.map.call(arguments, asDry))); 281 assertSame(o, receiver)
385 print("wet handler exit", name, arg, "returning", str(x)); 282
386 return x; 283 var wb = w.b
387 } catch (eDry) { 284 var wr = w.r
388 var x = asWet(eDry); 285 var wf = w.f
389 print("wet handler exception", name, arg, "throwing", str(x)); 286 var wf3 = w.f(3)
390 throw x; 287 var wfx = w.f({a: 6})
391 } 288 var wgx = w.g({a: {aa: 7}})
392 }; 289 var wh4 = new w.h(4)
393 } 290 var ws5 = w.s(5)
394 })); 291 var ws5x = ws5.x
395 wet2dry.set(wetRevokeHandler, dryHandler); 292 m.gate.revoke()
396 293 assertEquals(3, wf3)
397 if (typeof dry === "function") { 294 assertThrows(function() { w.a }, Error)
398 function callTrap() { 295 assertThrows(function() { w.r }, Error)
399 print("wet call trap enter", str(this)); 296 assertThrows(function() { w.r = {a: 4} }, Error)
400 var x = asWet(dry.apply( 297 assertThrows(function() { o.r.a }, Error)
401 asDry(this), Array.prototype.map.call(arguments, asDry))); 298 assertEquals("object", typeof o.r)
402 print("wet call trap exit", str(this), "returning", str(x)); 299 assertEquals(5, (o.r = {a: 5}).a)
403 return x; 300 assertEquals(5, o.r.a)
404 } 301 assertThrows(function() { w[1] }, Error)
405 function constructTrap() { 302 assertThrows(function() { w.c }, Error)
406 function forward(args) { return dry.apply(this, args) } 303 assertThrows(function() { wb.bb }, Error)
407 return asWet(new forward(Array.prototype.map.call(arguments, asDry))); 304 assertEquals(3, wr.a)
408 } 305 assertThrows(function() { wf(4) }, Error)
409 wetResult = 306 assertEquals(6, wfx.a)
410 Proxy.createFunction(wetRevokeHandler, callTrap, constructTrap); 307 assertEquals(7, wgx.aa)
411 } else { 308 assertThrows(function() { wh4.q }, Error)
412 wetResult = 309 assertThrows(function() { ws5.x }, Error)
413 new Proxy(asWet(Object.getPrototypeOf(dry)), wetRevokeHandler); 310 assertThrows(function() { ws5x.y }, Error)
414 } 311 }
415 dry2wet.set(dry, wetResult);
416 wet2dry.set(wetResult, dry);
417 return wetResult;
418 }
419
420 var gate = Object.freeze({
421 revoke: function() {
422 dry2wet = wet2dry = Object.freeze({
423 get: function(key) { throw new Error("revoked"); },
424 set: function(key, val) { throw new Error("revoked"); }
425 });
426 }
427 });
428
429 return Object.freeze({ wrapper: asDry(wetTarget), gate: gate });
430 }
431
432
433 var receiver
434 var argument
435 var o = {
436 a: 6,
437 b: {bb: 8},
438 f: function(x) { receiver = this; argument = x; return x },
439 g: function(x) { receiver = this; argument = x; return x.a },
440 h: function(x) { receiver = this; argument = x; this.q = x },
441 s: function(x) { receiver = this; argument = x; this.x = {y: x}; return this }
442 }
443 o[2] = {c: 7}
444 var m = createMembrane(o)
445 var w = m.wrapper
446 print("o =", str(o))
447 print("w =", str(w))
448
449 var f = w.f
450 var x = f(66)
451 var x = f({a: 1})
452 var x = w.f({a: 1})
453 var a = x.a
454 assertEquals(6, w.a)
455 assertEquals(8, w.b.bb)
456 assertEquals(7, w[2]["c"])
457 assertEquals(undefined, w.c)
458 assertEquals(1, w.f(1))
459 assertSame(o, receiver)
460 assertEquals(1, w.f({a: 1}).a)
461 assertSame(o, receiver)
462 assertEquals(2, w.g({a: 2}))
463 assertSame(o, receiver)
464 assertSame(w, w.f(w))
465 assertSame(o, receiver)
466 assertSame(o, argument)
467 assertSame(o, w.f(o))
468 assertSame(o, receiver)
469 // Note that argument !== o, since o isn't dry, so gets wrapped wet again.
470 assertEquals(3, (w.r = {a: 3}).a)
471 assertEquals(3, w.r.a)
472 assertEquals(3, o.r.a)
473 w.h(3)
474 assertEquals(3, w.q)
475 assertEquals(3, o.q)
476 assertEquals(4, (new w.h(4)).q)
477 assertEquals(5, w.s(5).x.y)
478 assertSame(o, receiver)
479
480 var wb = w.b
481 var wr = w.r
482 var wf = w.f
483 var wf3 = w.f(3)
484 var wfx = w.f({a: 6})
485 var wgx = w.g({a: {aa: 7}})
486 var wh4 = new w.h(4)
487 var ws5 = w.s(5)
488 var ws5x = ws5.x
489 m.gate.revoke()
490 assertEquals(3, wf3)
491 assertThrows(function() { w.a }, Error)
492 assertThrows(function() { w.r }, Error)
493 assertThrows(function() { w.r = {a: 4} }, Error)
494 assertThrows(function() { o.r.a }, Error)
495 assertEquals("object", typeof o.r)
496 assertEquals(5, (o.r = {a: 5}).a)
497 assertEquals(5, o.r.a)
498 assertThrows(function() { w[1] }, Error)
499 assertThrows(function() { w.c }, Error)
500 assertThrows(function() { wb.bb }, Error)
501 assertEquals(3, wr.a)
502 assertThrows(function() { wf(4) }, Error)
503 assertEquals(6, wfx.a)
504 assertEquals(7, wgx.aa)
505 assertThrows(function() { wh4.q }, Error)
506 assertThrows(function() { ws5.x }, Error)
507 assertThrows(function() { ws5x.y }, Error)
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/mjsunit.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698