12c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// Copyright 2011 the V8 project authors. All rights reserved. 22c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// Redistribution and use in source and binary forms, with or without 32c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// modification, are permitted provided that the following conditions are 42c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// met: 52c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// 62c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// * Redistributions of source code must retain the above copyright 72c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// notice, this list of conditions and the following disclaimer. 82c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// * Redistributions in binary form must reproduce the above 92c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// copyright notice, this list of conditions and the following 102c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// disclaimer in the documentation and/or other materials provided 112c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// with the distribution. 122c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// * Neither the name of Google Inc. nor the names of its 132c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// contributors may be used to endorse or promote products derived 142c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// from this software without specific prior written permission. 152c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// 162c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 288640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org// Flags: --harmony --harmony-proxies 292c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 302c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 312c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// A simple no-op handler. Adapted from: 322c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// http://wiki.ecmascript.org/doku.php?id=harmony:proxies#examplea_no-op_forwarding_proxy 332c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 342c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgfunction createHandler(obj) { 352c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return { 362c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org getOwnPropertyDescriptor: function(name) { 372c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var desc = Object.getOwnPropertyDescriptor(obj, name); 382c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org if (desc !== undefined) desc.configurable = true; 392c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return desc; 402c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org }, 412c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org getPropertyDescriptor: function(name) { 422c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var desc = Object.getOwnPropertyDescriptor(obj, name); 432c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org //var desc = Object.getPropertyDescriptor(obj, name); // not in ES5 442c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org if (desc !== undefined) desc.configurable = true; 452c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return desc; 462c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org }, 472c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org getOwnPropertyNames: function() { 482c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return Object.getOwnPropertyNames(obj); 492c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org }, 502c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org getPropertyNames: function() { 512c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return Object.getOwnPropertyNames(obj); 522c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org //return Object.getPropertyNames(obj); // not in ES5 532c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org }, 542c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org defineProperty: function(name, desc) { 552c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org Object.defineProperty(obj, name, desc); 562c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org }, 572c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org delete: function(name) { 582c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return delete obj[name]; 592c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org }, 602c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org fix: function() { 612c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org if (Object.isFrozen(obj)) { 622c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var result = {}; 632c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org Object.getOwnPropertyNames(obj).forEach(function(name) { 642c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org result[name] = Object.getOwnPropertyDescriptor(obj, name); 652c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org }); 662c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return result; 672c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 682c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org // As long as obj is not frozen, the proxy won't allow itself to be fixed 692c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return undefined; // will cause a TypeError to be thrown 702c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org }, 712c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org has: function(name) { return name in obj; }, 722c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org hasOwn: function(name) { return ({}).hasOwnProperty.call(obj, name); }, 732c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org get: function(receiver, name) { return obj[name]; }, 742c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org set: function(receiver, name, val) { 75486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org obj[name] = val; // bad behavior when set fails in sloppy mode 762c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return true; 772c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org }, 782c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org enumerate: function() { 792c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var result = []; 802c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org for (var name in obj) { result.push(name); }; 812c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return result; 822c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org }, 832c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org keys: function() { return Object.keys(obj); } 842c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org }; 852c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org} 862c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 872c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 882c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 892c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// Auxiliary definitions enabling tracking of object identity in output. 902c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 912c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar objectMap = new WeakMap; 922c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar objectCounter = 0; 932c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 942c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgfunction registerObject(x, s) { 952c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org if (x === Object(x) && !objectMap.has(x)) 962c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org objectMap.set(x, ++objectCounter + (s == undefined ? "" : ":" + s)); 972c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org} 982c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 992c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgregisterObject(this, "global"); 1002c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgregisterObject(Object.prototype, "Object.prototype"); 1012c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 1022c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgfunction str(x) { 1032c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org if (x === Object(x)) return "[" + typeof x + " " + objectMap.get(x) + "]"; 1042c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org if (typeof x == "string") return "\"" + x + "\""; 1052c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return "" + x; 1062c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org} 1072c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 1082c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 1092c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 1102c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// A simple membrane. Adapted from: 1112c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// http://wiki.ecmascript.org/doku.php?id=harmony:proxies#a_simple_membrane 1122c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 1132c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgfunction createSimpleMembrane(target) { 1142c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var enabled = true; 1152c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 1162c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org function wrap(obj) { 1172c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org registerObject(obj); 1182c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org print("wrap enter", str(obj)); 1192c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org try { 1202c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var x = wrap2(obj); 1212c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org registerObject(x, "wrapped"); 1222c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org print("wrap exit", str(obj), "as", str(x)); 1232c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return x; 1242c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } catch(e) { 1252c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org print("wrap exception", str(e)); 1262c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org throw e; 1272c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 1282c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 1292c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 1302c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org function wrap2(obj) { 1312c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org if (obj !== Object(obj)) { 1322c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return obj; 1332c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 1342c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 1352c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org function wrapCall(fun, that, args) { 1362c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org registerObject(that); 1372c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org print("wrapCall enter", fun, str(that)); 1382c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org try { 1392c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var x = wrapCall2(fun, that, args); 1402c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org print("wrapCall exit", fun, str(that), "returning", str(x)); 1412c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return x; 1422c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } catch(e) { 1432c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org print("wrapCall exception", fun, str(that), str(e)); 1442c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org throw e; 1452c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 1462c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 1472c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 1482c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org function wrapCall2(fun, that, args) { 1492c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org if (!enabled) { throw new Error("disabled"); } 1502c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org try { 1512c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return wrap(fun.apply(that, Array.prototype.map.call(args, wrap))); 1522c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } catch (e) { 1532c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org throw wrap(e); 1542c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 1552c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 1562c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 1572c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var baseHandler = createHandler(obj); 1582c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var handler = Proxy.create(Object.freeze({ 1592c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org get: function(receiver, name) { 1602c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return function() { 1612c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var arg = (name === "get" || name == "set") ? arguments[1] : ""; 1622c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org print("handler enter", name, arg); 1632c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var x = wrapCall(baseHandler[name], baseHandler, arguments); 1642c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org print("handler exit", name, arg, "returning", str(x)); 1652c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return x; 1662c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 1672c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 1682c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org })); 1692c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org registerObject(baseHandler, "basehandler"); 1702c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org registerObject(handler, "handler"); 1712c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 1722c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org if (typeof obj === "function") { 1732c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org function callTrap() { 1742c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org print("call trap enter", str(obj), str(this)); 1752c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var x = wrapCall(obj, wrap(this), arguments); 1762c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org print("call trap exit", str(obj), str(this), "returning", str(x)); 1772c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return x; 1782c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 1792c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org function constructTrap() { 1802c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org if (!enabled) { throw new Error("disabled"); } 1812c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org try { 1822c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org function forward(args) { return obj.apply(this, args) } 1832c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return wrap(new forward(Array.prototype.map.call(arguments, wrap))); 1842c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } catch (e) { 1852c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org throw wrap(e); 1862c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 1872c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 1882c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return Proxy.createFunction(handler, callTrap, constructTrap); 1892c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } else { 1902c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var prototype = wrap(Object.getPrototypeOf(obj)); 1912c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return Proxy.create(handler, prototype); 1922c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 1932c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 1942c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 1952c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var gate = Object.freeze({ 1962c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org enable: function() { enabled = true; }, 1972c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org disable: function() { enabled = false; } 1982c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org }); 1992c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 2002c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return Object.freeze({ 2012c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org wrapper: wrap(target), 2022c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org gate: gate 2032c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org }); 2042c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org} 2052c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 2062c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 2072c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar o = { 2082c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org a: 6, 2092c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org b: {bb: 8}, 2102c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org f: function(x) { return x }, 2112c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org g: function(x) { return x.a }, 2122c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org h: function(x) { this.q = x } 2132c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org}; 2142c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgo[2] = {c: 7}; 2152c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar m = createSimpleMembrane(o); 2162c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar w = m.wrapper; 2172c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgprint("o =", str(o)) 2182c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgprint("w =", str(w)); 2192c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 2202c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar f = w.f; 2212c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar x = f(66); 2222c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar x = f({a: 1}); 2232c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar x = w.f({a: 1}); 2242c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar a = x.a; 2252c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(6, w.a); 2262c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(8, w.b.bb); 2272c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(7, w[2]["c"]); 2282c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(undefined, w.c); 2292c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(1, w.f(1)); 2302c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(1, w.f({a: 1}).a); 2312c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(2, w.g({a: 2})); 2322c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(3, (w.r = {a: 3}).a); 2332c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(3, w.r.a); 2342c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(3, o.r.a); 2352c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgw.h(3); 2362c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(3, w.q); 2372c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(3, o.q); 2382c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(4, (new w.h(4)).q); 2392c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 2402c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar wb = w.b; 2412c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar wr = w.r; 2422c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar wf = w.f; 2432c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar wf3 = w.f(3); 2442c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar wfx = w.f({a: 6}); 2452c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar wgx = w.g({a: {aa: 7}}); 2462c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar wh4 = new w.h(4); 2472c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgm.gate.disable(); 2482c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(3, wf3); 2492c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertThrows(function() { w.a }, Error); 2502c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertThrows(function() { w.r }, Error); 2512c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertThrows(function() { w.r = {a: 4} }, Error); 2522c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertThrows(function() { o.r.a }, Error); 2532c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals("object", typeof o.r); 2542c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(5, (o.r = {a: 5}).a); 2552c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(5, o.r.a); 2562c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertThrows(function() { w[1] }, Error); 2572c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertThrows(function() { w.c }, Error); 2582c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertThrows(function() { wb.bb }, Error); 2592c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertThrows(function() { wr.a }, Error); 2602c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertThrows(function() { wf(4) }, Error); 2612c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertThrows(function() { wfx.a }, Error); 2622c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertThrows(function() { wgx.aa }, Error); 2632c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertThrows(function() { wh4.q }, Error); 2642c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 2652c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgm.gate.enable(); 2662c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(6, w.a); 2672c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(5, w.r.a); 2682c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(5, o.r.a); 2692c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(7, w.r = 7); 2702c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(7, w.r); 2712c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(7, o.r); 2722c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(8, w.b.bb); 2732c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(7, w[2]["c"]); 2742c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(undefined, w.c); 2752c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(8, wb.bb); 2762c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(3, wr.a); 2772c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(4, wf(4)); 2782c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(3, wf3); 2792c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(6, wfx.a); 2802c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(7, wgx.aa); 2812c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(4, wh4.q); 2822c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 2832c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 2842c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// An identity-preserving membrane. Adapted from: 2852c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// http://wiki.ecmascript.org/doku.php?id=harmony:proxies#an_identity-preserving_membrane 2862c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 2872c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgfunction createMembrane(wetTarget) { 288d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org var wet2dry = new WeakMap(); 289d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org var dry2wet = new WeakMap(); 2902c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 2912c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org function asDry(obj) { 2922c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org registerObject(obj) 2932c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org print("asDry enter", str(obj)) 2942c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org try { 2952c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var x = asDry2(obj); 2962c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org registerObject(x, "dry"); 2972c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org print("asDry exit", str(obj), "as", str(x)); 2982c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return x; 2992c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } catch(e) { 3002c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org print("asDry exception", str(e)); 3012c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org throw e; 3022c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 3032c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 3042c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org function asDry2(wet) { 3052c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org if (wet !== Object(wet)) { 3062c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org // primitives provide only irrevocable knowledge, so don't 3072c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org // bother wrapping it. 3082c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return wet; 3092c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 3102c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var dryResult = wet2dry.get(wet); 3112c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org if (dryResult) { return dryResult; } 3122c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 3132c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var wetHandler = createHandler(wet); 3142c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var dryRevokeHandler = Proxy.create(Object.freeze({ 3152c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org get: function(receiver, name) { 3162c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return function() { 3172c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var arg = (name === "get" || name == "set") ? arguments[1] : ""; 3182c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org print("dry handler enter", name, arg); 3192c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var optWetHandler = dry2wet.get(dryRevokeHandler); 3202c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org try { 3212c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var x = asDry(optWetHandler[name].apply( 3222c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org optWetHandler, Array.prototype.map.call(arguments, asWet))); 3232c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org print("dry handler exit", name, arg, "returning", str(x)); 3242c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return x; 3252c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } catch (eWet) { 3262c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var x = asDry(eWet); 3272c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org print("dry handler exception", name, arg, "throwing", str(x)); 3282c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org throw x; 3292c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 3302c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org }; 3312c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 3322c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org })); 3332c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org dry2wet.set(dryRevokeHandler, wetHandler); 3342c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 3352c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org if (typeof wet === "function") { 3362c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org function callTrap() { 3372c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org print("dry call trap enter", str(this)); 3382c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var x = asDry(wet.apply( 3392c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org asWet(this), Array.prototype.map.call(arguments, asWet))); 3402c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org print("dry call trap exit", str(this), "returning", str(x)); 3412c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return x; 3422c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 3432c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org function constructTrap() { 3442c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org function forward(args) { return wet.apply(this, args) } 3452c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return asDry(new forward(Array.prototype.map.call(arguments, asWet))); 3462c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 3472c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org dryResult = 3482c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org Proxy.createFunction(dryRevokeHandler, callTrap, constructTrap); 3492c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } else { 3502c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org dryResult = 3512c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org Proxy.create(dryRevokeHandler, asDry(Object.getPrototypeOf(wet))); 3522c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 3532c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org wet2dry.set(wet, dryResult); 3542c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org dry2wet.set(dryResult, wet); 3552c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return dryResult; 3562c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 3572c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 3582c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org function asWet(obj) { 3592c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org registerObject(obj) 3602c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org print("asWet enter", str(obj)) 3612c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org try { 3622c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var x = asWet2(obj) 3632c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org registerObject(x, "wet") 3642c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org print("asWet exit", str(obj), "as", str(x)) 3652c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return x 3662c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } catch(e) { 3672c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org print("asWet exception", str(e)) 3682c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org throw e 3692c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 3702c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 3712c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org function asWet2(dry) { 3722c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org if (dry !== Object(dry)) { 3732c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org // primitives provide only irrevocable knowledge, so don't 3742c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org // bother wrapping it. 3752c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return dry; 3762c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 3772c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var wetResult = dry2wet.get(dry); 3782c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org if (wetResult) { return wetResult; } 3792c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 3802c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var dryHandler = createHandler(dry); 3812c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var wetRevokeHandler = Proxy.create(Object.freeze({ 3822c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org get: function(receiver, name) { 3832c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return function() { 3842c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var arg = (name === "get" || name == "set") ? arguments[1] : ""; 3852c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org print("wet handler enter", name, arg); 3862c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var optDryHandler = wet2dry.get(wetRevokeHandler); 3872c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org try { 3882c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var x = asWet(optDryHandler[name].apply( 3892c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org optDryHandler, Array.prototype.map.call(arguments, asDry))); 3902c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org print("wet handler exit", name, arg, "returning", str(x)); 3912c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return x; 3922c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } catch (eDry) { 3932c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var x = asWet(eDry); 3942c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org print("wet handler exception", name, arg, "throwing", str(x)); 3952c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org throw x; 3962c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 3972c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org }; 3982c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 3992c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org })); 4002c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org wet2dry.set(wetRevokeHandler, dryHandler); 4012c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 4022c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org if (typeof dry === "function") { 4032c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org function callTrap() { 4042c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org print("wet call trap enter", str(this)); 4052c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var x = asWet(dry.apply( 4062c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org asDry(this), Array.prototype.map.call(arguments, asDry))); 4072c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org print("wet call trap exit", str(this), "returning", str(x)); 4082c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return x; 4092c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 4102c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org function constructTrap() { 4112c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org function forward(args) { return dry.apply(this, args) } 4122c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return asWet(new forward(Array.prototype.map.call(arguments, asDry))); 4132c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 4142c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org wetResult = 4152c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org Proxy.createFunction(wetRevokeHandler, callTrap, constructTrap); 4162c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } else { 4172c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org wetResult = 4182c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org Proxy.create(wetRevokeHandler, asWet(Object.getPrototypeOf(dry))); 4192c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 4202c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org dry2wet.set(dry, wetResult); 4212c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org wet2dry.set(wetResult, dry); 4222c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return wetResult; 4232c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 4242c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 4252c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org var gate = Object.freeze({ 4262c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org revoke: function() { 4272c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org dry2wet = wet2dry = Object.freeze({ 4282c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org get: function(key) { throw new Error("revoked"); }, 4292c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org set: function(key, val) { throw new Error("revoked"); } 4302c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org }); 4312c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org } 4322c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org }); 4332c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 4342c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return Object.freeze({ wrapper: asDry(wetTarget), gate: gate }); 4352c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org} 4362c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 4372c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 4382c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar receiver 4392c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar argument 4402c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar o = { 4412c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org a: 6, 4422c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org b: {bb: 8}, 4432c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org f: function(x) { receiver = this; argument = x; return x }, 4442c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org g: function(x) { receiver = this; argument = x; return x.a }, 4452c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org h: function(x) { receiver = this; argument = x; this.q = x }, 4462c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org s: function(x) { receiver = this; argument = x; this.x = {y: x}; return this } 4472c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org} 4482c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgo[2] = {c: 7} 4492c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar m = createMembrane(o) 4502c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar w = m.wrapper 4512c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgprint("o =", str(o)) 4522c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgprint("w =", str(w)) 4532c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 4542c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar f = w.f 4552c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar x = f(66) 4562c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar x = f({a: 1}) 4572c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar x = w.f({a: 1}) 4582c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar a = x.a 4592c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(6, w.a) 4602c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(8, w.b.bb) 4612c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(7, w[2]["c"]) 4622c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(undefined, w.c) 4632c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(1, w.f(1)) 4642c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertSame(o, receiver) 4652c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(1, w.f({a: 1}).a) 4662c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertSame(o, receiver) 4672c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(2, w.g({a: 2})) 4682c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertSame(o, receiver) 4692c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertSame(w, w.f(w)) 4702c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertSame(o, receiver) 4712c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertSame(o, argument) 4722c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertSame(o, w.f(o)) 4732c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertSame(o, receiver) 4742c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org// Note that argument !== o, since o isn't dry, so gets wrapped wet again. 4752c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(3, (w.r = {a: 3}).a) 4762c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(3, w.r.a) 4772c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(3, o.r.a) 4782c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgw.h(3) 4792c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(3, w.q) 4802c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(3, o.q) 4812c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(4, (new w.h(4)).q) 4822c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(5, w.s(5).x.y) 4832c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertSame(o, receiver) 4842c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 4852c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar wb = w.b 4862c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar wr = w.r 4872c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar wf = w.f 4882c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar wf3 = w.f(3) 4892c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar wfx = w.f({a: 6}) 4902c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar wgx = w.g({a: {aa: 7}}) 4912c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar wh4 = new w.h(4) 4922c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar ws5 = w.s(5) 4932c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgvar ws5x = ws5.x 4942c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgm.gate.revoke() 4952c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(3, wf3) 4962c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertThrows(function() { w.a }, Error) 4972c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertThrows(function() { w.r }, Error) 4982c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertThrows(function() { w.r = {a: 4} }, Error) 4992c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertThrows(function() { o.r.a }, Error) 5002c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals("object", typeof o.r) 5012c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(5, (o.r = {a: 5}).a) 5022c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(5, o.r.a) 5032c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertThrows(function() { w[1] }, Error) 5042c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertThrows(function() { w.c }, Error) 5052c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertThrows(function() { wb.bb }, Error) 5062c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(3, wr.a) 5072c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertThrows(function() { wf(4) }, Error) 5082c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(6, wfx.a) 5092c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertEquals(7, wgx.aa) 5102c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertThrows(function() { wh4.q }, Error) 5112c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertThrows(function() { ws5.x }, Error) 5122c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgassertThrows(function() { ws5x.y }, Error) 513