diff options
Diffstat (limited to 'js/src/jit-test/tests/proxy/testDirectProxySet10.js')
-rw-r--r-- | js/src/jit-test/tests/proxy/testDirectProxySet10.js | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/proxy/testDirectProxySet10.js b/js/src/jit-test/tests/proxy/testDirectProxySet10.js new file mode 100644 index 0000000000..287cced8f3 --- /dev/null +++ b/js/src/jit-test/tests/proxy/testDirectProxySet10.js @@ -0,0 +1,60 @@ +// Assigning to a non-existing property of a plain object defines that +// property on that object, even if a proxy is on the proto chain. + +// Create an object that behaves just like obj except it throws (instead of +// returning undefined) if you try to get a property that doesn't exist. +function throwIfNoSuchProperty(obj) { + return new Proxy(obj, { + get(t, id) { + if (id in t) + return t[id]; + throw new Error("no such handler method: " + id); + } + }); +} + +// Use a touchy object as our proxy handler in this test. +var hits = 0, savedDesc = undefined; +var touchyHandler = throwIfNoSuchProperty({ + set: undefined +}); +var target = {}; +var proto = new Proxy(target, touchyHandler); +var receiver = Object.create(proto); + +// This assignment `receiver.x = 2` results in a series of [[Set]] calls, +// starting with: +// +// - receiver.[[Set]]() +// - receiver is an ordinary object. +// - This looks for an own property "x" on receiver. There is none. +// - So it walks the prototype chain, doing a tail-call to: +// - proto.[[Set]]() +// - proto is a proxy. +// - This does handler.[[Get]]("set") to look for a set trap +// (that's why we need `set: undefined` on the handler, above) +// - Since there's no "set" handler, it tail-calls: +// - target.[[Set]]() +// - ordinary +// - no own property "x" +// - tail call to: +// - Object.prototype.[[Set]]() +// - ordinary +// - no own property "x" +// - We're at the end of the line: there's nothing left on the proto chain. +// - So at last we call: +// - receiver.[[DefineOwnProperty]]() +// - ordinary +// - creates the property +// +// Got all that? Let's try it. +// +receiver.x = 2; +assertEq(receiver.x, 2); + +var desc = Object.getOwnPropertyDescriptor(receiver, "x"); +assertEq(desc.enumerable, true); +assertEq(desc.configurable, true); +assertEq(desc.writable, true); +assertEq(desc.value, 2); + |