summaryrefslogtreecommitdiff
path: root/deps/v8/test/mjsunit/es6/proxies-example-membrane.js
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/mjsunit/es6/proxies-example-membrane.js')
-rw-r--r--deps/v8/test/mjsunit/es6/proxies-example-membrane.js308
1 files changed, 308 insertions, 0 deletions
diff --git a/deps/v8/test/mjsunit/es6/proxies-example-membrane.js b/deps/v8/test/mjsunit/es6/proxies-example-membrane.js
new file mode 100644
index 0000000000..dd373b7429
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/proxies-example-membrane.js
@@ -0,0 +1,308 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+// A simple membrane. Adapted from:
+// http://wiki.ecmascript.org/doku.php?id=harmony:proxies#a_simple_membrane
+
+function createSimpleMembrane(target) {
+ let enabled = true;
+
+ function wrap(obj) {
+ if (obj !== Object(obj)) return obj;
+
+ let handler = new Proxy({}, {get: function(_, key) {
+ if (!enabled) throw new Error("disabled");
+ switch (key) {
+ case "apply":
+ return (_, that, args) => {
+ try {
+ return wrap(Reflect.apply(
+ obj, wrap(that), args.map((x) => wrap(x))));
+ } catch(e) {
+ throw wrap(e);
+ }
+ }
+ case "construct":
+ return (_, args, newt) => {
+ try {
+ return wrap(Reflect.construct(
+ obj, args.map((x) => wrap(x)), wrap(newt)));
+ } catch(e) {
+ throw wrap(e);
+ }
+ }
+ default:
+ return (_, ...args) => {
+ try {
+ return wrap(Reflect[key](obj, ...(args.map(wrap))));
+ } catch(e) {
+ throw wrap(e);
+ }
+ }
+ }
+ }});
+
+ return new Proxy(obj, handler);
+ }
+
+ const gate = Object.freeze({
+ enable: () => enabled = true,
+ disable: () => enabled = false
+ });
+
+ return Object.freeze({
+ wrapper: wrap(target),
+ gate: gate
+ });
+}
+
+
+// Test the simple membrane.
+{
+ var o = {
+ a: 6,
+ b: {bb: 8},
+ f: function(x) { return x },
+ g: function(x) { return x.a },
+ h: function(x) { this.q = x }
+ };
+ o[2] = {c: 7};
+ var m = createSimpleMembrane(o);
+ var w = m.wrapper;
+ var f = w.f;
+ var x = f(66);
+ var x = f({a: 1});
+ var x = w.f({a: 1});
+ var a = x.a;
+ assertEquals(6, w.a);
+ assertEquals(8, w.b.bb);
+ assertEquals(7, w[2]["c"]);
+ assertEquals(undefined, w.c);
+ assertEquals(1, w.f(1));
+ assertEquals(1, w.f({a: 1}).a);
+ assertEquals(2, w.g({a: 2}));
+ assertEquals(3, (w.r = {a: 3}).a);
+ assertEquals(3, w.r.a);
+ assertEquals(3, o.r.a);
+ w.h(3);
+ assertEquals(3, w.q);
+ assertEquals(3, o.q);
+ assertEquals(4, (new w.h(4)).q);
+
+ var wb = w.b;
+ var wr = w.r;
+ var wf = w.f;
+ var wf3 = w.f(3);
+ var wfx = w.f({a: 6});
+ var wgx = w.g({a: {aa: 7}});
+ var wh4 = new w.h(4);
+ m.gate.disable();
+ assertEquals(3, wf3);
+ assertThrows(function() { w.a }, Error);
+ assertThrows(function() { w.r }, Error);
+ assertThrows(function() { w.r = {a: 4} }, Error);
+ assertThrows(function() { o.r.a }, Error);
+ assertEquals("object", typeof o.r);
+ assertEquals(5, (o.r = {a: 5}).a);
+ assertEquals(5, o.r.a);
+ assertThrows(function() { w[1] }, Error);
+ assertThrows(function() { w.c }, Error);
+ assertThrows(function() { wb.bb }, Error);
+ assertThrows(function() { wr.a }, Error);
+ assertThrows(function() { wf(4) }, Error);
+ assertThrows(function() { wfx.a }, Error);
+ assertThrows(function() { wgx.aa }, Error);
+ assertThrows(function() { wh4.q }, Error);
+
+ m.gate.enable();
+ assertEquals(6, w.a);
+ assertEquals(5, w.r.a);
+ assertEquals(5, o.r.a);
+ assertEquals(7, w.r = 7);
+ assertEquals(7, w.r);
+ assertEquals(7, o.r);
+ assertEquals(8, w.b.bb);
+ assertEquals(7, w[2]["c"]);
+ assertEquals(undefined, w.c);
+ assertEquals(8, wb.bb);
+ assertEquals(3, wr.a);
+ assertEquals(4, wf(4));
+ assertEquals(3, wf3);
+ assertEquals(6, wfx.a);
+ assertEquals(7, wgx.aa);
+ assertEquals(4, wh4.q);
+}
+
+
+
+// An identity-preserving membrane. Adapted from:
+// http://wiki.ecmascript.org/doku.php?id=harmony:proxies#an_identity-preserving_membrane
+
+function createMembrane(target) {
+ const wet2dry = 0;
+ const dry2wet = 1;
+
+ function flip(dir) { return (dir + 1) % 2 }
+
+ let maps = [new WeakMap(), new WeakMap()];
+
+ let revoked = false;
+
+ function wrap(dir, obj) {
+ if (obj !== Object(obj)) return obj;
+
+ let wrapper = maps[dir].get(obj);
+ if (wrapper) return wrapper;
+
+ let handler = new Proxy({}, {get: function(_, key) {
+ if (revoked) throw new Error("revoked");
+ switch (key) {
+ case "apply":
+ return (_, that, args) => {
+ try {
+ return wrap(dir, Reflect.apply(
+ obj, wrap(flip(dir), that),
+ args.map((x) => wrap(flip(dir), x))));
+ } catch(e) {
+ throw wrap(dir, e);
+ }
+ }
+ case "construct":
+ return (_, args, newt) => {
+ try {
+ return wrap(dir, Reflect.construct(
+ obj, args.map((x) => wrap(flip(dir), x)),
+ wrap(flip(dir), newt)));
+ } catch(e) {
+ throw wrap(dir, e);
+ }
+ }
+ default:
+ return (_, ...args) => {
+ try {
+ return wrap(dir, Reflect[key](
+ obj, ...(args.map((x) => wrap(flip(dir), x)))))
+ } catch(e) {
+ throw wrap(dir, e);
+ }
+ }
+ }
+ }});
+
+ wrapper = new Proxy(obj, handler);
+ maps[dir].set(obj, wrapper);
+ maps[flip(dir)].set(wrapper, obj);
+ return wrapper;
+ }
+
+ const gate = Object.freeze({
+ revoke: () => revoked = true
+ });
+
+ return Object.freeze({
+ wrapper: wrap(wet2dry, target),
+ gate: gate
+ });
+}
+
+
+// Test the identity-preserving membrane.
+{
+ var receiver
+ var argument
+ var o = {
+ a: 6,
+ b: {bb: 8},
+ f: function(x) {receiver = this; argument = x; return x},
+ g: function(x) {receiver = this; argument = x; return x.a},
+ h: function(x) {receiver = this; argument = x; this.q = x},
+ s: function(x) {receiver = this; argument = x; this.x = {y: x}; return this}
+ }
+ o[2] = {c: 7}
+ var m = createMembrane(o)
+ var w = m.wrapper
+ var f = w.f
+ var x = f(66)
+ var x = f({a: 1})
+ var x = w.f({a: 1})
+ var a = x.a
+ assertEquals(6, w.a)
+ assertEquals(8, w.b.bb)
+ assertEquals(7, w[2]["c"])
+ assertEquals(undefined, w.c)
+ assertEquals(1, w.f(1))
+ assertSame(o, receiver)
+ assertEquals(1, w.f({a: 1}).a)
+ assertSame(o, receiver)
+ assertEquals(2, w.g({a: 2}))
+ assertSame(o, receiver)
+ assertSame(w, w.f(w))
+ assertSame(o, receiver)
+ assertSame(o, argument)
+ assertSame(o, w.f(o))
+ assertSame(o, receiver)
+ // Note that argument !== o, since o isn't dry, so gets wrapped wet again.
+ assertEquals(3, (w.r = {a: 3}).a)
+ assertEquals(3, w.r.a)
+ assertEquals(3, o.r.a)
+ w.h(3)
+ assertEquals(3, w.q)
+ assertEquals(3, o.q)
+ assertEquals(4, (new w.h(4)).q)
+ assertEquals(5, w.s(5).x.y)
+ assertSame(o, receiver)
+
+ var wb = w.b
+ var wr = w.r
+ var wf = w.f
+ var wf3 = w.f(3)
+ var wfx = w.f({a: 6})
+ var wgx = w.g({a: {aa: 7}})
+ var wh4 = new w.h(4)
+ var ws5 = w.s(5)
+ var ws5x = ws5.x
+ m.gate.revoke()
+ assertEquals(3, wf3)
+ assertThrows(function() { w.a }, Error)
+ assertThrows(function() { w.r }, Error)
+ assertThrows(function() { w.r = {a: 4} }, Error)
+ assertThrows(function() { o.r.a }, Error)
+ assertEquals("object", typeof o.r)
+ assertEquals(5, (o.r = {a: 5}).a)
+ assertEquals(5, o.r.a)
+ assertThrows(function() { w[1] }, Error)
+ assertThrows(function() { w.c }, Error)
+ assertThrows(function() { wb.bb }, Error)
+ assertEquals(3, wr.a)
+ assertThrows(function() { wf(4) }, Error)
+ assertEquals(6, wfx.a)
+ assertEquals(7, wgx.aa)
+ assertThrows(function() { wh4.q }, Error)
+ assertThrows(function() { ws5.x }, Error)
+ assertThrows(function() { ws5x.y }, Error)
+}