diff options
Diffstat (limited to '')
19 files changed, 732 insertions, 0 deletions
diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/browser.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/browser.js diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/call-parameters.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/call-parameters.js new file mode 100644 index 0000000000..bc5ac03d57 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/call-parameters.js @@ -0,0 +1,41 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.2 +description: > + Trap is called with handler on its context, first parameter is target and + second parameter is the given value. +info: | + [[SetPrototypeOf]] (V) + + ... + 9. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target, V»)). + ... +features: [Proxy] +---*/ + +var _handler, _target, _value; +var target = {}; +var val = { + foo: 1 +}; +var handler = { + setPrototypeOf: function(t, v) { + _handler = this; + _target = t; + _value = v; + + Object.setPrototypeOf(t, v); + + return true; + } +}; +var p = new Proxy(target, handler); + +Object.setPrototypeOf(p, val); + +assert.sameValue(_handler, handler); +assert.sameValue(_target, target); +assert.sameValue(_value, val); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/internals-call-order.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/internals-call-order.js new file mode 100644 index 0000000000..e6f3e20551 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/internals-call-order.js @@ -0,0 +1,50 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v +description: > + Calls target.[[GetPrototypeOf]] after trap result as false and not extensible + target +info: | + [[SetPrototypeOf]] (V) + + 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, V »)). + 9. If booleanTrapResult is false, return false. + 10. Let extensibleTarget be ? IsExtensible(target). + 11. If extensibleTarget is true, return true. + 12. Let targetProto be ? target.[[GetPrototypeOf]](). +features: [Proxy, Reflect, Reflect.setPrototypeOf] +---*/ + +var calls = []; +var proto = {}; + +var target = new Proxy(Object.create(proto), { + isExtensible: function() { + calls.push("target.[[IsExtensible]]"); + return false; + }, + getPrototypeOf: function() { + calls.push("target.[[GetPrototypeOf]]"); + return proto; + } +}); + +// Proxy must report same extensiblitity as target +Object.preventExtensions(target); + +var proxy = new Proxy(target, { + setPrototypeOf: function() { + calls.push("proxy.[[setPrototypeOf]]"); + return true; + } +}); + +assert.sameValue(Reflect.setPrototypeOf(proxy, proto), true); +assert.sameValue(calls.length, 3); +assert.sameValue(calls[0], "proxy.[[setPrototypeOf]]"); +assert.sameValue(calls[1], "target.[[IsExtensible]]"); +assert.sameValue(calls[2], "target.[[GetPrototypeOf]]"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/not-extensible-target-not-same-target-prototype.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/not-extensible-target-not-same-target-prototype.js new file mode 100644 index 0000000000..3c59f9a50e --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/not-extensible-target-not-same-target-prototype.js @@ -0,0 +1,55 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.2 +description: > + Throws a TypeError exception if boolean trap result is true, target is + not extensible, and the given parameter is not the same object as the target + prototype. +info: | + [[SetPrototypeOf]] (V) + + ... + 2. Let handler be the value of the [[ProxyHandler]] internal slot of O. + ... + 5. Let target be the value of the [[ProxyTarget]] internal slot of O. + 6. Let trap be GetMethod(handler, "setPrototypeOf"). + ... + 9. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target, V»)). + 14. Let targetProto be target.[[GetPrototypeOf]](). + 15. ReturnIfAbrupt(targetProto). + 16. If booleanTrapResult is true and SameValue(V, targetProto) is false, + throw a TypeError exception. + ... +features: [Proxy, Reflect, Reflect.setPrototypeOf] +---*/ + +var target, proxy; +target = {}; +proxy = new Proxy(target, { + setPrototypeOf: function() { + return true; + } +}); + +Object.preventExtensions(target); + +assert.throws(TypeError, function() { + Reflect.setPrototypeOf(proxy, {}); +}, "target prototype is different"); + +var proto = {}; +target = Object.setPrototypeOf({}, proto); +proxy = new Proxy(target, { + setPrototypeOf: function() { + Object.setPrototypeOf(target, {}); + Object.preventExtensions(target); + return true; + } +}); + +assert.throws(TypeError, function() { + Reflect.setPrototypeOf(proxy, proto); +}, "target prototype is changed inside trap handler"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/not-extensible-target-same-target-prototype.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/not-extensible-target-same-target-prototype.js new file mode 100644 index 0000000000..8910a2ddcd --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/not-extensible-target-same-target-prototype.js @@ -0,0 +1,56 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v +description: > + Handler can only return true for non-extensible targets if the given prototype + is the same as target's prototype +info: | + [[SetPrototypeOf]] (V) + + 12. Let targetProto be ? target.[[GetPrototypeOf]](). + 13. If SameValue(V, targetProto) is false, throw a TypeError exception. + 14. Return true. +features: [Proxy, Reflect, Reflect.setPrototypeOf] +---*/ + +var proto = {}; +var target = Object.setPrototypeOf({}, proto); + +Object.preventExtensions(target); + +var proxy; + +proxy = new Proxy(target, { + setPrototypeOf: function() { + return true; + } +}); + +assert.sameValue( + Reflect.setPrototypeOf(proxy, proto), + true, + "prototype arg is the same in target" +); + +var outro = {}; +proxy = new Proxy(outro, { + setPrototypeOf: function(t, p) { + Object.setPrototypeOf(t, p); + Object.preventExtensions(t); + return true; + } +}); + +assert.sameValue( + Reflect.setPrototypeOf(proxy, proto), + true, + "prototype is set to target inside handler trap" +); +assert.sameValue( + Object.getPrototypeOf(outro), + proto, + "target has the custom set prototype" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/null-handler.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/null-handler.js new file mode 100644 index 0000000000..71aa84b3ad --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/null-handler.js @@ -0,0 +1,18 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.2 +description: > + Throws a TypeError exception if handler is null +features: [Proxy] +---*/ + +var p = Proxy.revocable({}, {}); + +p.revoke(); + +assert.throws(TypeError, function() { + Object.setPrototypeOf(p.proxy, {}); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/return-abrupt-from-get-trap.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/return-abrupt-from-get-trap.js new file mode 100644 index 0000000000..aa525697bc --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/return-abrupt-from-get-trap.js @@ -0,0 +1,26 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist +description: > + Return abrupt getting handler trap +info: | + [[SetPrototypeOf]] (V) + + 6. Let trap be ? GetMethod(handler, "setPrototypeOf"). +features: [Proxy] +---*/ + +var handler = Object.defineProperty({}, "setPrototypeOf", { + get: function() { + throw new Test262Error(); + } +}); + +var proxy = new Proxy({}, handler); + +assert.throws(Test262Error, function() { + Object.setPrototypeOf(proxy, {}); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/return-abrupt-from-isextensible-target.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/return-abrupt-from-isextensible-target.js new file mode 100644 index 0000000000..1ff2cb555c --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/return-abrupt-from-isextensible-target.js @@ -0,0 +1,31 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v +description: > + Return abrupt from IsExtensible(target) +info: | + [[SetPrototypeOf]] (V) + + 10. Let extensibleTarget be ? IsExtensible(target). +features: [Proxy] +---*/ + +var target = new Proxy({}, { + isExtensible: function() { + throw new Test262Error(); + } +}); + +var proxy = new Proxy(target, { + setPrototypeOf: function() { + return true; + } +}); + +assert.throws(Test262Error, function() { + Object.setPrototypeOf(proxy, {}); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/return-abrupt-from-target-getprototypeof.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/return-abrupt-from-target-getprototypeof.js new file mode 100644 index 0000000000..49173d7f77 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/return-abrupt-from-target-getprototypeof.js @@ -0,0 +1,33 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v +description: > + Return abrupt from target.[[GetPrototypeOf]]() +info: | + [[SetPrototypeOf]] (V) + + 12. Let targetProto be ? target.[[GetPrototypeOf]](). +features: [Proxy] +---*/ + +var target = new Proxy({}, { + getPrototypeOf: function() { + throw new Test262Error(); + } +}); + +Object.preventExtensions(target); + +var proxy = new Proxy(target, { + setPrototypeOf: function() { + return true; + } +}); + +assert.throws(Test262Error, function() { + Object.setPrototypeOf(proxy, {}); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/return-abrupt-from-trap.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/return-abrupt-from-trap.js new file mode 100644 index 0000000000..b5d0c90d17 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/return-abrupt-from-trap.js @@ -0,0 +1,27 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.2 +description: > + Trap returns abrupt. +info: | + [[SetPrototypeOf]] (V) + + 9. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target, V»)). + 10. ReturnIfAbrupt(booleanTrapResult). +features: [Proxy] +---*/ + +var p = new Proxy({}, { + setPrototypeOf: function() { + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + Object.setPrototypeOf(p, { + value: 1 + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/shell.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/shell.js diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/toboolean-trap-result-false.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/toboolean-trap-result-false.js new file mode 100644 index 0000000000..8720cffbc7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/toboolean-trap-result-false.js @@ -0,0 +1,77 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v +description: > + Return false if ToBoolean(trap result) is false, without checking + target.[[IsExtensible]] +info: | + [[SetPrototypeOf]] (V) + + 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, V »)). + 9. If booleanTrapResult is false, return false. + 10. Let extensibleTarget be ? IsExtensible(target). + 11. If extensibleTarget is true, return true. +features: [Proxy, Reflect, Reflect.setPrototypeOf] +---*/ + +var called = 0; + +var target = new Proxy({}, { + isExtensible: function() { + called += 1; + } +}); + +var p = new Proxy(target, { + setPrototypeOf: function(t, v) { + return v.attr; + } +}); + +var result; + +result = Reflect.setPrototypeOf(p, { + attr: false +}); +assert.sameValue(result, false, "false"); +assert.sameValue(called, 0, "false - isExtensible is not called"); + +result = Reflect.setPrototypeOf(p, { + attr: "" +}); +assert.sameValue(result, false, "the empty string"); +assert.sameValue(called, 0, "the empty string - isExtensible is not called"); + +result = Reflect.setPrototypeOf(p, { + attr: 0 +}); +assert.sameValue(result, false, "0"); +assert.sameValue(called, 0, "0 - isExtensible is not called"); + +result = Reflect.setPrototypeOf(p, { + attr: -0 +}); +assert.sameValue(result, false, "-0"); +assert.sameValue(called, 0, "-0 - isExtensible is not called"); + +result = Reflect.setPrototypeOf(p, { + attr: null +}); +assert.sameValue(result, false, "null"); +assert.sameValue(called, 0, "null - isExtensible is not called"); + +result = Reflect.setPrototypeOf(p, { + attr: undefined +}); +assert.sameValue(result, false, "undefined"); +assert.sameValue(called, 0, "undefined - isExtensible is not called"); + +result = Reflect.setPrototypeOf(p, { + attr: NaN +}); +assert.sameValue(result, false, "NaN"); +assert.sameValue(called, 0, "NaN - isExtensible is not called"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/toboolean-trap-result-true-target-is-extensible.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/toboolean-trap-result-true-target-is-extensible.js new file mode 100644 index 0000000000..6da14809f0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/toboolean-trap-result-true-target-is-extensible.js @@ -0,0 +1,80 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v +description: > + Return true if ToBoolean(trap result) is true, and target.[[IsExtensible]] is + true +info: | + [[SetPrototypeOf]] (V) + + 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, V »)). + 9. If booleanTrapResult is false, return false. + 10. Let extensibleTarget be ? IsExtensible(target). + 11. If extensibleTarget is true, return true. +features: [Proxy, Reflect, Reflect.setPrototypeOf, Symbol] +---*/ + +var called; +var target = new Proxy({}, { + isExtensible: function() { + called += 1; + return true; + }, + getPrototypeOf: function() { + throw new Test262Error("target.[[GetPrototypeOf]] is not called"); + } +}); + +var p = new Proxy(target, { + setPrototypeOf: function(t, v) { + return v.attr; + } +}); + +var result; + +called = 0; +result = Reflect.setPrototypeOf(p, { + attr: true +}); +assert.sameValue(result, true, "true"); +assert.sameValue(called, 1, "true - isExtensible is called"); + +called = 0; +result = Reflect.setPrototypeOf(p, { + attr: "false" +}); +assert.sameValue(result, true, "string"); +assert.sameValue(called, 1, "string - isExtensible is called"); + +called = 0; +result = Reflect.setPrototypeOf(p, { + attr: 42 +}); +assert.sameValue(result, true, "42"); +assert.sameValue(called, 1, "number - isExtensible is called"); + +called = 0; +result = Reflect.setPrototypeOf(p, { + attr: p +}); +assert.sameValue(result, true, "p"); +assert.sameValue(called, 1, "object - isExtensible is called"); + +called = 0; +result = Reflect.setPrototypeOf(p, { + attr: [] +}); +assert.sameValue(result, true, "[]"); +assert.sameValue(called, 1, "[] - isExtensible is called"); + +called = 0; +result = Reflect.setPrototypeOf(p, { + attr: Symbol(1) +}); +assert.sameValue(result, true, "symbol"); +assert.sameValue(called, 1, "symbol - isExtensible is called"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-missing-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-missing-target-is-proxy.js new file mode 100644 index 0000000000..8a3f56b5cb --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-missing-target-is-proxy.js @@ -0,0 +1,38 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v +description: > + If "setPrototypeOf" trap is null or undefined, [[SetPrototypeOf]] call + is properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[SetPrototypeOf]] ( V ) + + [...] + 5. Let target be O.[[ProxyTarget]]. + 6. Let trap be ? GetMethod(handler, "setPrototypeOf"). + 7. If trap is undefined, then + a. Return ? target.[[SetPrototypeOf]](V). + + [[SetPrototypeOf]] ( V ) + + [...] + 8. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, V »)). + 9. If booleanTrapResult is false, return false. +features: [Proxy] +---*/ + +var target = new Proxy({}, { + setPrototypeOf: function(_target, _value) { + return false; + }, +}); + +var proxy = new Proxy(target, {}); + +assert.throws(TypeError, function() { + Object.setPrototypeOf(proxy, null); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-not-callable-realm.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-not-callable-realm.js new file mode 100644 index 0000000000..6bcdbf6d11 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-not-callable-realm.js @@ -0,0 +1,36 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v +description: > + Throws if trap is not callable (honoring the Realm of the current execution + context) +info: | + [[SetPrototypeOf]] (V) + + ... + 2. Let handler be the value of the [[ProxyHandler]] internal slot of O. + ... + 5. Let target be the value of the [[ProxyTarget]] internal slot of O. + 6. Let trap be GetMethod(handler, "setPrototypeOf"). + ... + 7.3.9 GetMethod (O, P) + ... + 2. Let func be GetV(O, P). + 5. If IsCallable(func) is false, throw a TypeError exception. + ... +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var p = new OProxy({}, { + setPrototypeOf: {} +}); + +assert.throws(TypeError, function() { + Object.setPrototypeOf(p, { + value: 1 + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-not-callable.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-not-callable.js new file mode 100644 index 0000000000..358588e831 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-not-callable.js @@ -0,0 +1,35 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.2 +description: > + Throws a TypeError exception if trap is not callable. +info: | + [[SetPrototypeOf]] (V) + + ... + 2. Let handler be the value of the [[ProxyHandler]] internal slot of O. + ... + 5. Let target be the value of the [[ProxyTarget]] internal slot of O. + 6. Let trap be GetMethod(handler, "setPrototypeOf"). + ... + 7.3.9 GetMethod (O, P) + ... + 2. Let func be GetV(O, P). + 5. If IsCallable(func) is false, throw a TypeError exception. + ... +features: [Proxy, Reflect, Reflect.setPrototypeOf] +---*/ + +var target = {}; +var p = new Proxy(target, { + setPrototypeOf: {} +}); + +assert.throws(TypeError, function() { + Reflect.setPrototypeOf(p, { + value: 1 + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-null-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-null-target-is-proxy.js new file mode 100644 index 0000000000..c9857e94aa --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-null-target-is-proxy.js @@ -0,0 +1,42 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v +description: > + If "setPrototypeOf" trap is null or undefined, [[SetPrototypeOf]] call + is properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[SetPrototypeOf]] ( V ) + + [...] + 5. Let target be O.[[ProxyTarget]]. + 6. Let trap be ? GetMethod(handler, "setPrototypeOf"). + 7. If trap is undefined, then + a. Return ? target.[[SetPrototypeOf]](V). + + OrdinarySetPrototypeOf ( O, V ) + + [...] + 8. Repeat, while done is false, + a. If p is null, set done to true. + b. Else if SameValue(p, O) is true, return false. + [...] +features: [Proxy] +---*/ + +var plainObject = {}; +var plainObjectTarget = new Proxy(plainObject, {}); +var plainObjectProxy = new Proxy(plainObjectTarget, { + setPrototypeOf: null, +}); + +Object.setPrototypeOf(plainObjectProxy, null); +assert.sameValue(Object.getPrototypeOf(plainObject), null); + +var cyclicPrototype = Object.create(plainObject); +assert.throws(TypeError, function() { + Object.setPrototypeOf(plainObjectProxy, cyclicPrototype); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-undefined-or-null.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-undefined-or-null.js new file mode 100644 index 0000000000..84fa1c2d77 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-undefined-or-null.js @@ -0,0 +1,47 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v +description: > + Return target.[[SetPrototypeOf]] (V) if trap is undefined or null. +info: | + [[SetPrototypeOf]] (V) + + 6. Let trap be ? GetMethod(handler, "setPrototypeOf"). + 7. If trap is undefined, then + a. Return ? target.[[SetPrototypeOf]](V). + + GetMethod (V, P) + + 2. Let func be ? GetV(V, P). + 3. If func is either undefined or null, return undefined. +features: [Proxy] +---*/ + +var proxy, called, value; +var target = new Proxy({}, { + setPrototypeOf: function(t, v) { + called += 1; + value = v; + return true; + } +}); +var proto = {}; + +proxy = new Proxy(target, {}); +called = 0; +value = false; +Object.setPrototypeOf(proxy, proto); +assert.sameValue(called, 1, "undefined, target.[[SetPrototypeOf]] is called"); +assert.sameValue(value, proto, "undefined, called with V"); + +proxy = new Proxy(target, { + setPrototypeOf: null +}); +called = 0; +value = false; +Object.setPrototypeOf(proxy, proto); +assert.sameValue(called, 1, "null, target.[[SetPrototypeOf]] is called"); +assert.sameValue(value, proto, "null, called with V"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-undefined-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-undefined-target-is-proxy.js new file mode 100644 index 0000000000..091fe8abb4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-undefined-target-is-proxy.js @@ -0,0 +1,40 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v +description: > + If "setPrototypeOf" trap is null or undefined, [[SetPrototypeOf]] call + is properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[SetPrototypeOf]] ( V ) + + [...] + 5. Let target be O.[[ProxyTarget]]. + 6. Let trap be ? GetMethod(handler, "setPrototypeOf"). + 7. If trap is undefined, then + a. Return ? target.[[SetPrototypeOf]](V). + + OrdinarySetPrototypeOf ( O, V ) + + [...] + 4. Let extensible be O.[[Extensible]]. + 5. If extensible is false, return false. +features: [Proxy] +---*/ + +var array = []; +var arrayTarget = new Proxy(array, {}); +var arrayProxy = new Proxy(arrayTarget, { + setPrototypeOf: undefined, +}); + +Object.setPrototypeOf(arrayProxy, Number.prototype); +assert.sameValue(Object.getPrototypeOf(array), Number.prototype); + +Object.preventExtensions(array); +assert.throws(TypeError, function() { + Object.setPrototypeOf(arrayProxy, null); +}); + +reportCompare(0, 0); |