diff options
Diffstat (limited to '')
48 files changed, 1793 insertions, 0 deletions
diff --git a/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-boolean-return-false.js b/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-boolean-return-false.js new file mode 100644 index 0000000000..0d69437b4a --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-boolean-return-false.js @@ -0,0 +1,22 @@ +// 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.9 +description: > + [[Set]] ( P, V, Receiver) + + 11. If booleanTrapResult is false, return false. +features: [Proxy, Reflect, Reflect.set] +---*/ + +var target = {}; +var handler = { + set: function(t, prop, value, receiver) { + return false; + } +}; +var p = new Proxy(target, handler); + +assert.sameValue(Reflect.set(p, "attr", "foo"), false); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-null-return-false.js b/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-null-return-false.js new file mode 100644 index 0000000000..f904449f7d --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-null-return-false.js @@ -0,0 +1,22 @@ +// 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.9 +description: > + [[Set]] ( P, V, Receiver) + + 11. If booleanTrapResult is false, return false. +features: [Proxy, Reflect, Reflect.set] +---*/ + +var target = {}; +var handler = { + set: function(t, prop, value, receiver) { + return null; + } +}; +var p = new Proxy(target, handler); + +assert.sameValue(Reflect.set(p, "attr", "foo"), false); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-number-return-false.js b/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-number-return-false.js new file mode 100644 index 0000000000..edf18a07ea --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-number-return-false.js @@ -0,0 +1,22 @@ +// 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.9 +description: > + [[Set]] ( P, V, Receiver) + + 11. If booleanTrapResult is false, return false. +features: [Proxy, Reflect, Reflect.set] +---*/ + +var target = {}; +var handler = { + set: function(t, prop, value, receiver) { + return 0; + } +}; +var p = new Proxy(target, handler); + +assert.sameValue(Reflect.set(p, "attr", "foo"), false); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-string-return-false.js b/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-string-return-false.js new file mode 100644 index 0000000000..2eab3a0c63 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-string-return-false.js @@ -0,0 +1,22 @@ +// 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.9 +description: > + [[Set]] ( P, V, Receiver) + + 11. If booleanTrapResult is false, return false. +features: [Proxy, Reflect, Reflect.set] +---*/ + +var target = {}; +var handler = { + set: function(t, prop, value, receiver) { + return ""; + } +}; +var p = new Proxy(target, handler); + +assert.sameValue(Reflect.set(p, "attr", "foo"), false); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-undefined-return-false.js b/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-undefined-return-false.js new file mode 100644 index 0000000000..0ff8ca59a4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-undefined-return-false.js @@ -0,0 +1,22 @@ +// 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.9 +description: > + [[Set]] ( P, V, Receiver) + + 11. If booleanTrapResult is false, return false. +features: [Proxy, Reflect, Reflect.set] +---*/ + +var target = {}; +var handler = { + set: function(t, prop, value, receiver) { + return undefined; + } +}; +var p = new Proxy(target, handler); + +assert.sameValue(Reflect.set(p, "attr", "foo"), false); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/browser.js b/js/src/tests/test262/built-ins/Proxy/set/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/browser.js diff --git a/js/src/tests/test262/built-ins/Proxy/set/call-parameters-prototype-dunder-proto.js b/js/src/tests/test262/built-ins/Proxy/set/call-parameters-prototype-dunder-proto.js new file mode 100644 index 0000000000..8b4ec874d2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/call-parameters-prototype-dunder-proto.js @@ -0,0 +1,58 @@ +// Copyright (C) 2019 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-set-p-v-receiver +description: > + Ordinary [[Set]] forwards call to Proxy "set" trap with correct arguments. + Property name is "__proto__". +info: | + OrdinarySet ( O, P, V, Receiver ) + + ... + 3. Return OrdinarySetWithOwnDescriptor(O, P, V, Receiver, ownDesc). + + OrdinarySetWithOwnDescriptor ( O, P, V, Receiver, ownDesc ) + + ... + 2. If ownDesc is undefined, then + a. Let parent be ? O.[[GetPrototypeOf]](). + b. If parent is not null, then + i. Return ? parent.[[Set]](P, V, Receiver). + + [[Set]] ( P, V, Receiver ) + + ... + 8. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P, V, Receiver »)). + ... + 12. Return true. +includes: [proxyTrapsHelper.js] +features: [Proxy, __proto__] +---*/ + +var _handler, _target, _prop, _value, _receiver; +var target = {}; +var handler = allowProxyTraps({ + set: function(target, prop, value, receiver) { + _handler = this; + _target = target; + _prop = prop; + _value = value; + _receiver = receiver; + return true; + }, +}); + +var proxy = new Proxy(target, handler); +var receiver = Object.create(proxy); +var prop = '__proto__'; +var value = {}; + +receiver[prop] = value; + +assert.sameValue(_handler, handler, 'handler object is the trap context'); +assert.sameValue(_target, target, 'first argument is the target object'); +assert.sameValue(_prop, prop, 'second argument is the property name'); +assert.sameValue(_value, value, 'third argument is the new value'); +assert.sameValue(_receiver, receiver, 'fourth argument is the receiver object'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/call-parameters-prototype-index.js b/js/src/tests/test262/built-ins/Proxy/set/call-parameters-prototype-index.js new file mode 100644 index 0000000000..e57e40c3e0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/call-parameters-prototype-index.js @@ -0,0 +1,57 @@ +// Copyright (C) 2019 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-set-p-v-receiver +description: > + Ordinary [[Set]] forwards call to Proxy "set" trap with correct arguments. + (integer index property name) +info: | + OrdinarySet ( O, P, V, Receiver ) + + ... + 3. Return OrdinarySetWithOwnDescriptor(O, P, V, Receiver, ownDesc). + + OrdinarySetWithOwnDescriptor ( O, P, V, Receiver, ownDesc ) + + ... + 2. If ownDesc is undefined, then + a. Let parent be ? O.[[GetPrototypeOf]](). + b. If parent is not null, then + i. Return ? parent.[[Set]](P, V, Receiver). + + [[Set]] ( P, V, Receiver ) + + ... + 8. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P, V, Receiver »)). + ... + 12. Return true. +includes: [proxyTrapsHelper.js] +features: [Proxy] +---*/ + +var _handler, _target, _prop, _value, _receiver; +var target = {}; +var handler = allowProxyTraps({ + set: function(target, prop, value, receiver) { + _handler = this; + _target = target; + _prop = prop; + _value = value; + _receiver = receiver; + return true; + }, +}); + +var proxy = new Proxy(target, handler); +var array = new Array(1); +Object.setPrototypeOf(array, proxy); + +array[0] = 1; + +assert.sameValue(_handler, handler, 'handler object is the trap context'); +assert.sameValue(_target, target, 'first argument is the target object'); +assert.sameValue(_prop, '0', 'second argument is the property name'); +assert.sameValue(_value, 1, 'third argument is the new value'); +assert.sameValue(_receiver, array, 'fourth argument is the receiver object'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/call-parameters-prototype.js b/js/src/tests/test262/built-ins/Proxy/set/call-parameters-prototype.js new file mode 100644 index 0000000000..c11f535d95 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/call-parameters-prototype.js @@ -0,0 +1,55 @@ +// Copyright (C) 2019 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-set-p-v-receiver +description: > + Ordinary [[Set]] forwards call to Proxy "set" trap with correct arguments. +info: | + OrdinarySet ( O, P, V, Receiver ) + + ... + 3. Return OrdinarySetWithOwnDescriptor(O, P, V, Receiver, ownDesc). + + OrdinarySetWithOwnDescriptor ( O, P, V, Receiver, ownDesc ) + + ... + 2. If ownDesc is undefined, then + a. Let parent be ? O.[[GetPrototypeOf]](). + b. If parent is not null, then + i. Return ? parent.[[Set]](P, V, Receiver). + + [[Set]] ( P, V, Receiver ) + + ... + 8. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P, V, Receiver »)). + ... + 12. Return true. +includes: [proxyTrapsHelper.js] +features: [Proxy] +---*/ + +var _handler, _target, _prop, _value, _receiver; +var target = {}; +var handler = allowProxyTraps({ + set: function(target, prop, value, receiver) { + _handler = this; + _target = target; + _prop = prop; + _value = value; + _receiver = receiver; + return true; + }, +}); + +var proxy = new Proxy(target, handler); +var receiver = Object.create(proxy); + +receiver.prop = 'value'; + +assert.sameValue(_handler, handler, 'handler object is the trap context'); +assert.sameValue(_target, target, 'first argument is the target object'); +assert.sameValue(_prop, 'prop', 'second argument is the property name'); +assert.sameValue(_value, 'value', 'third argument is the new value'); +assert.sameValue(_receiver, receiver, 'fourth argument is the receiver object'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/call-parameters.js b/js/src/tests/test262/built-ins/Proxy/set/call-parameters.js new file mode 100644 index 0000000000..304fc661c9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/call-parameters.js @@ -0,0 +1,39 @@ +// 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-set-p-v-receiver +description: > + Proxy "set" trap is called with correct arguments. +info: | + [[Set]] ( P, V, Receiver ) + + ... + 8. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P, V, Receiver »)). + ... + 12. Return true. +features: [Proxy] +---*/ + +var _target, _handler, _prop, _value, _receiver; +var target = {}; +var handler = { + set: function(t, prop, value, receiver) { + _handler = this; + _target = t; + _prop = prop; + _value = value; + _receiver = receiver; + return true; + } +}; +var p = new Proxy(target, handler); + +p.attr = "foo"; + +assert.sameValue(_handler, handler, "handler object as the trap context"); +assert.sameValue(_target, target, "first argument is the target object"); +assert.sameValue(_prop, "attr", "second argument is the property name"); +assert.sameValue(_value, "foo", "third argument is the new value"); +assert.sameValue(_receiver, p, "forth argument is the proxy object"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/null-handler.js b/js/src/tests/test262/built-ins/Proxy/set/null-handler.js new file mode 100644 index 0000000000..dd5c16829f --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/null-handler.js @@ -0,0 +1,24 @@ +// 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.9 +description: > + [[Set]] ( P, V, Receiver) + + 3. If handler is null, throw a TypeError exception. +features: [Proxy] +---*/ + +var p = Proxy.revocable({}, {}); + +p.revoke(); + +assert.throws(TypeError, function() { + p.proxy.attr = 1; +}); + +assert.throws(TypeError, function() { + p.proxy['attr'] = 1; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/return-is-abrupt.js b/js/src/tests/test262/built-ins/Proxy/set/return-is-abrupt.js new file mode 100644 index 0000000000..4dbff93a3c --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/return-is-abrupt.js @@ -0,0 +1,31 @@ +// 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.9 +description: > + Trap returns abrupt. +info: | + [[Set]] ( P, V, Receiver) + + ... + 9. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target, P, V, Receiver»)). + 10. ReturnIfAbrupt(booleanTrapResult). + ... +features: [Proxy] +---*/ + +var p = new Proxy({}, { + set: function(t, prop, value, receiver) { + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + p.attr = "bar"; +}); + +assert.throws(Test262Error, function() { + p["attr"] = "bar"; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/return-true-target-property-accessor-is-configurable-set-is-undefined.js b/js/src/tests/test262/built-ins/Proxy/set/return-true-target-property-accessor-is-configurable-set-is-undefined.js new file mode 100644 index 0000000000..5d9cf8144e --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/return-true-target-property-accessor-is-configurable-set-is-undefined.js @@ -0,0 +1,28 @@ +// 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.9 +description: > + [[Set]] ( P, V, Receiver) + + Returns true if trap returns true and target property accessor is + configurable and set is undefined. +features: [Proxy, Reflect, Reflect.set] +---*/ + +var target = {}; +var handler = { + set: function(t, prop, value, receiver) { + return true; + } +}; +var p = new Proxy(target, handler); + +Object.defineProperty(target, "attr", { + configurable: true, + set: undefined +}); + +assert(Reflect.set(p, "attr", "bar")); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/return-true-target-property-accessor-is-not-configurable.js b/js/src/tests/test262/built-ins/Proxy/set/return-true-target-property-accessor-is-not-configurable.js new file mode 100644 index 0000000000..536429bf75 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/return-true-target-property-accessor-is-not-configurable.js @@ -0,0 +1,30 @@ +// 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.9 +description: > + [[Set]] ( P, V, Receiver) + + Returns true if trap returns true and target property accessor is not + configurable and set is not undefined. +features: [Proxy, Reflect, Reflect.set] +---*/ + +var target = {}; +var handler = { + set: function(t, prop, value, receiver) { + return true; + } +}; +var p = new Proxy(target, handler); + +Object.defineProperty(target, 'attr', { + configurable: false, + set: function(value) { + return value; + } +}); + +assert(Reflect.set(p, "attr", 1)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/return-true-target-property-is-not-configurable.js b/js/src/tests/test262/built-ins/Proxy/set/return-true-target-property-is-not-configurable.js new file mode 100644 index 0000000000..6d0ed0f8f1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/return-true-target-property-is-not-configurable.js @@ -0,0 +1,29 @@ +// 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.9 +description: > + [[Set]] ( P, V, Receiver) + + Returns true if trap returns true and target property is not configurable + but writable. +features: [Proxy, Reflect, Reflect.set] +---*/ + +var target = {}; +var handler = { + set: function(t, prop, value, receiver) { + return true; + } +}; +var p = new Proxy(target, handler); + +Object.defineProperty(target, 'attr', { + configurable: false, + writable: true, + value: 'foo' +}); + +assert(Reflect.set(p, "attr", 1)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/return-true-target-property-is-not-writable.js b/js/src/tests/test262/built-ins/Proxy/set/return-true-target-property-is-not-writable.js new file mode 100644 index 0000000000..04bd86bdcc --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/return-true-target-property-is-not-writable.js @@ -0,0 +1,29 @@ +// 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.9 +description: > + [[Set]] ( P, V, Receiver) + + Returns true if trap returns true and target property is configurable + but not writable. +features: [Proxy, Reflect, Reflect.set] +---*/ + +var target = {}; +var handler = { + set: function(t, prop, value, receiver) { + return true; + } +}; +var p = new Proxy(target, handler); + +Object.defineProperty(target, "attr", { + configurable: true, + writable: false, + value: "foo" +}); + +assert(Reflect.set(p, "attr", "foo")); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/shell.js b/js/src/tests/test262/built-ins/Proxy/set/shell.js new file mode 100644 index 0000000000..bc72493f03 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/shell.js @@ -0,0 +1,33 @@ +// GENERATED, DO NOT EDIT +// file: proxyTrapsHelper.js +// Copyright (C) 2016 Jordan Harband. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: | + Used to assert the correctness of object behavior in the presence + and context of Proxy objects. +defines: [allowProxyTraps] +---*/ + +function allowProxyTraps(overrides) { + function throwTest262Error(msg) { + return function () { throw new Test262Error(msg); }; + } + if (!overrides) { overrides = {}; } + return { + getPrototypeOf: overrides.getPrototypeOf || throwTest262Error('[[GetPrototypeOf]] trap called'), + setPrototypeOf: overrides.setPrototypeOf || throwTest262Error('[[SetPrototypeOf]] trap called'), + isExtensible: overrides.isExtensible || throwTest262Error('[[IsExtensible]] trap called'), + preventExtensions: overrides.preventExtensions || throwTest262Error('[[PreventExtensions]] trap called'), + getOwnPropertyDescriptor: overrides.getOwnPropertyDescriptor || throwTest262Error('[[GetOwnProperty]] trap called'), + has: overrides.has || throwTest262Error('[[HasProperty]] trap called'), + get: overrides.get || throwTest262Error('[[Get]] trap called'), + set: overrides.set || throwTest262Error('[[Set]] trap called'), + deleteProperty: overrides.deleteProperty || throwTest262Error('[[Delete]] trap called'), + defineProperty: overrides.defineProperty || throwTest262Error('[[DefineOwnProperty]] trap called'), + enumerate: throwTest262Error('[[Enumerate]] trap called: this trap has been removed'), + ownKeys: overrides.ownKeys || throwTest262Error('[[OwnPropertyKeys]] trap called'), + apply: overrides.apply || throwTest262Error('[[Call]] trap called'), + construct: overrides.construct || throwTest262Error('[[Construct]] trap called') + }; +} diff --git a/js/src/tests/test262/built-ins/Proxy/set/target-property-is-accessor-not-configurable-set-is-undefined.js b/js/src/tests/test262/built-ins/Proxy/set/target-property-is-accessor-not-configurable-set-is-undefined.js new file mode 100644 index 0000000000..da4292f791 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/target-property-is-accessor-not-configurable-set-is-undefined.js @@ -0,0 +1,39 @@ +// 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.9 +description: > + [[Set]] ( P, V, Receiver) + + Throws a TypeError when target property is an accessor not configurable and + and set is undefined. +info: | + 14. If targetDesc is not undefined, then + b. If IsAccessorDescriptor(targetDesc) and targetDesc.[[Configurable]] is false, then + i. If targetDesc.[[Set]] is undefined, throw a TypeError exception. + +features: [Proxy] +---*/ + +var target = {}; +var handler = { + set: function(t, prop, value, receiver) { + return true; + } +}; +var p = new Proxy(target, handler); + +Object.defineProperty(target, 'attr', { + configurable: false, + set: undefined +}); + +assert.throws(TypeError, function() { + p.attr = 'bar'; +}); + +assert.throws(TypeError, function() { + p['attr'] = 'bar'; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/target-property-is-not-configurable-not-writable-not-equal-to-v.js b/js/src/tests/test262/built-ins/Proxy/set/target-property-is-not-configurable-not-writable-not-equal-to-v.js new file mode 100644 index 0000000000..73fd9c7ae4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/target-property-is-not-configurable-not-writable-not-equal-to-v.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.9 +description: > + [[Set]] ( P, V, Receiver) + + Throws a TypeError when target property is not configurable neither writable + and its value is not strictly equal to V. +info: | + 14. If targetDesc is not undefined, then + a. If IsDataDescriptor(targetDesc) and targetDesc.[[Configurable]] is + false and targetDesc.[[Writable]] is false, then + i. If SameValue(V, targetDesc.[[Value]]) is false, throw a TypeError + exception. +features: [Proxy] +---*/ + +var target = {}; +var handler = { + set: function(t, prop, value, receiver) { + return true; + } +}; +var p = new Proxy(target, handler); + +Object.defineProperty(target, 'attr', { + configurable: false, + writable: false, + value: 'foo' +}); + +assert.throws(TypeError, function() { + p.attr = 'bar'; +}); + +assert.throws(TypeError, function() { + p['attr'] = 'bar'; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/trap-is-missing-receiver-multiple-calls-index.js b/js/src/tests/test262/built-ins/Proxy/set/trap-is-missing-receiver-multiple-calls-index.js new file mode 100644 index 0000000000..37a7cac0e9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/trap-is-missing-receiver-multiple-calls-index.js @@ -0,0 +1,81 @@ +// 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-set-p-v-receiver +description: > + If "set" trap is missing, the call is properly forwarded to ordinary + [[Set]] that invokes [[GetOwnProperty]] and [[DefineOwnProperty]] methods + on receiver (that is a Proxy itself) every time it is called. + (integer index property name) +info: | + [[Set]] ( P, V, Receiver ) + + [...] + 6. Let trap be ? GetMethod(handler, "set"). + 7. If trap is undefined, then + a. Return ? target.[[Set]](P, V, Receiver). + + OrdinarySetWithOwnDescriptor ( O, P, V, Receiver, ownDesc ) + + [...] + 3. If IsDataDescriptor(ownDesc) is true, then + [...] + c. Let existingDescriptor be ? Receiver.[[GetOwnProperty]](P). + d. If existingDescriptor is not undefined, then + [...] + iii. Let valueDesc be the PropertyDescriptor { [[Value]]: V }. + iv. Return ? Receiver.[[DefineOwnProperty]](P, valueDesc). + e. Else, + i. Assert: Receiver does not currently have a property P. + ii. Return ? CreateDataProperty(Receiver, P, V). + [...] + + [[DefineOwnProperty]] ( P, Desc ) + + [...] + 9. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P, descObj »)). + [...] + 17. Return true. +features: [Proxy, Reflect] +includes: [compareArray.js] +---*/ + +var getOwnPropertyKeys = []; +var definePropertyKeys = []; + +var p = new Proxy({ + "0": null, +}, { + getOwnPropertyDescriptor: function(target, key) { + getOwnPropertyKeys.push(key); + return Reflect.getOwnPropertyDescriptor(target, key); + }, + defineProperty: function(target, key, desc) { + definePropertyKeys.push(key); + return Reflect.defineProperty(target, key, desc); + }, +}); + +p[0] = true; +p[0] = true; +p["0"] = true; + +assert.compareArray(getOwnPropertyKeys, ["0", "0", "0"], + "getOwnPropertyDescriptor: key present on [[ProxyTarget]]"); +assert.compareArray(definePropertyKeys, ["0", "0", "0"], + "defineProperty: key present on [[ProxyTarget]]"); + +getOwnPropertyKeys = []; +definePropertyKeys = []; + +p[22] = false; +p["22"] = false; +p[22] = false; + +assert.compareArray(getOwnPropertyKeys, ["22", "22", "22"], + "getOwnPropertyDescriptor: key absent on [[ProxyTarget]]"); +assert.compareArray(definePropertyKeys, ["22", "22", "22"], + "defineProperty: key absent on [[ProxyTarget]]"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/trap-is-missing-receiver-multiple-calls.js b/js/src/tests/test262/built-ins/Proxy/set/trap-is-missing-receiver-multiple-calls.js new file mode 100644 index 0000000000..3144580a4b --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/trap-is-missing-receiver-multiple-calls.js @@ -0,0 +1,80 @@ +// 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-set-p-v-receiver +description: > + If "set" trap is missing, the call is properly forwarded to ordinary + [[Set]] that invokes [[GetOwnProperty]] and [[DefineOwnProperty]] methods + on receiver (that is a Proxy itself) every time it is called. +info: | + [[Set]] ( P, V, Receiver ) + + [...] + 6. Let trap be ? GetMethod(handler, "set"). + 7. If trap is undefined, then + a. Return ? target.[[Set]](P, V, Receiver). + + OrdinarySetWithOwnDescriptor ( O, P, V, Receiver, ownDesc ) + + [...] + 3. If IsDataDescriptor(ownDesc) is true, then + [...] + c. Let existingDescriptor be ? Receiver.[[GetOwnProperty]](P). + d. If existingDescriptor is not undefined, then + [...] + iii. Let valueDesc be the PropertyDescriptor { [[Value]]: V }. + iv. Return ? Receiver.[[DefineOwnProperty]](P, valueDesc). + e. Else, + i. Assert: Receiver does not currently have a property P. + ii. Return ? CreateDataProperty(Receiver, P, V). + [...] + + [[DefineOwnProperty]] ( P, Desc ) + + [...] + 9. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P, descObj »)). + [...] + 17. Return true. +features: [Proxy, Reflect] +includes: [compareArray.js] +---*/ + +var getOwnPropertyKeys = []; +var definePropertyKeys = []; + +var p = new Proxy({ + foo: 1, +}, { + getOwnPropertyDescriptor: function(target, key) { + getOwnPropertyKeys.push(key); + return Reflect.getOwnPropertyDescriptor(target, key); + }, + defineProperty: function(target, key, desc) { + definePropertyKeys.push(key); + return Reflect.defineProperty(target, key, desc); + }, +}); + +p["foo"] = 2; +p.foo = 2; +p.foo = 2; + +assert.compareArray(getOwnPropertyKeys, ["foo", "foo", "foo"], + "getOwnPropertyDescriptor: key present on [[ProxyTarget]]"); +assert.compareArray(definePropertyKeys, ["foo", "foo", "foo"], + "defineProperty: key present on [[ProxyTarget]]"); + +getOwnPropertyKeys = []; +definePropertyKeys = []; + +p.bar = 3; +p["bar"] = 3; +p.bar = 3; + +assert.compareArray(getOwnPropertyKeys, ["bar", "bar", "bar"], + "getOwnPropertyDescriptor: key absent on [[ProxyTarget]]"); +assert.compareArray(definePropertyKeys, ["bar", "bar", "bar"], + "defineProperty: key absent on [[ProxyTarget]]"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/trap-is-missing-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/set/trap-is-missing-target-is-proxy.js new file mode 100644 index 0000000000..1ef5cd59ac --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/trap-is-missing-target-is-proxy.js @@ -0,0 +1,49 @@ +// 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-set-p-v-receiver +description: > + If "set" trap is null or undefined, [[Set]] call is properly + forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[Set]] ( P, V, Receiver ) + + [...] + 5. Let target be O.[[ProxyTarget]]. + 6. Let trap be ? GetMethod(handler, "set"). + 7. If trap is undefined, then + a. Return ? target.[[Set]](P, V, Receiver). +features: [Proxy, Reflect] +---*/ + +var barValue; +var plainObject = { + get foo() {}, + set bar(value) { + barValue = value; + }, +}; + +var plainObjectTarget = new Proxy(plainObject, {}); +var plainObjectProxy = new Proxy(plainObjectTarget, {}); + +plainObjectProxy.bar = 1; +assert.sameValue(barValue, 1); + +assert.throws(TypeError, function() { + "use strict"; + plainObjectProxy.foo = 2; +}); + + +var regExp = /(?:)/g; +var regExpTarget = new Proxy(regExp, {}); +var regExpProxy = new Proxy(regExpTarget, {}); + +assert(!Reflect.set(regExpProxy, "global", true)); + +regExpProxy.lastIndex = 1; +assert.sameValue(regExp.lastIndex, 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/trap-is-not-callable-realm.js b/js/src/tests/test262/built-ins/Proxy/set/trap-is-not-callable-realm.js new file mode 100644 index 0000000000..07e710b1ee --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/trap-is-not-callable-realm.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-set-p-v-receiver +description: > + Throws if trap is not callable (honoring the Realm of the current execution + context) +info: | + [[Set]] ( P, V, Receiver) + + 6. Let trap be GetMethod(handler, "set"). + ... + + 7.3.9 GetMethod (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({}, { + set: {} +}); + +assert.throws(TypeError, function() { + p.attr = 1; +}); + +assert.throws(TypeError, function() { + p["attr"] = 1; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/trap-is-not-callable.js b/js/src/tests/test262/built-ins/Proxy/set/trap-is-not-callable.js new file mode 100644 index 0000000000..60ca4a96d0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/trap-is-not-callable.js @@ -0,0 +1,31 @@ +// 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.9 +description: > + Trap is not callable. +info: | + [[Set]] ( P, V, Receiver) + + 6. Let trap be GetMethod(handler, "set"). + ... + + 7.3.9 GetMethod (O, P) + + 5. If IsCallable(func) is false, throw a TypeError exception. +features: [Proxy] +---*/ + +var p = new Proxy({}, { + set: {} +}); + +assert.throws(TypeError, function() { + p.attr = 1; +}); + +assert.throws(TypeError, function() { + p["attr"] = 1; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/trap-is-null-receiver.js b/js/src/tests/test262/built-ins/Proxy/set/trap-is-null-receiver.js new file mode 100644 index 0000000000..ae93a63b62 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/trap-is-null-receiver.js @@ -0,0 +1,32 @@ +// Copyright (C) 2016 Aleksey 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-set-p-v-receiver +description: > + Pass to target's [[Set]] correct receiver if trap is missing +info: | + [[Set]] (P, V, Receiver) + + 7. If trap is undefined, then + a. Return ? target.[[Set]](P, V, Receiver). +features: [Proxy] +---*/ + +var context; +var target = { + set attr(val) { + context = this; + } +}; + +var p = new Proxy(target, { + set: null +}); +p.attr = 1; +assert.sameValue(context, p); + +var pParent = Object.create(new Proxy(target, {})); +pParent.attr = 3; +assert.sameValue(context, pParent); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/trap-is-null-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/set/trap-is-null-target-is-proxy.js new file mode 100644 index 0000000000..4687576ddd --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/trap-is-null-target-is-proxy.js @@ -0,0 +1,51 @@ +// 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-set-p-v-receiver +description: > + If "set" trap is null or undefined, [[Set]] call is properly + forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[Set]] ( P, V, Receiver ) + + [...] + 5. Let target be O.[[ProxyTarget]]. + 6. Let trap be ? GetMethod(handler, "set"). + 7. If trap is undefined, then + a. Return ? target.[[Set]](P, V, Receiver). +features: [Proxy, Reflect] +includes: [compareArray.js] +---*/ + +var array = [1, 2, 3]; +var arrayTarget = new Proxy(array, {}); +var arrayProxy = new Proxy(arrayTarget, { + set: null, +}); + +arrayProxy.length = 0; +assert.compareArray(array, []); + +Object.preventExtensions(array); + +assert(!Reflect.set(arrayProxy, "foo", 2)); +assert.throws(TypeError, function() { + "use strict"; + arrayProxy[0] = 3; +}); + + +var string = new String("str"); +var stringTarget = new Proxy(string, {}); +var stringProxy = new Proxy(stringTarget, { + set: null, +}); + +stringProxy[4] = 1; +assert.sameValue(string[4], 1); + +assert(!Reflect.set(stringProxy, "0", "s")); +assert(!Reflect.set(stringProxy, "length", 3)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/trap-is-undefined-no-property.js b/js/src/tests/test262/built-ins/Proxy/set/trap-is-undefined-no-property.js new file mode 100644 index 0000000000..8929897575 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/trap-is-undefined-no-property.js @@ -0,0 +1,22 @@ +// 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.9 +description: > + [[Set]] ( P, V, Receiver) + + 8. If trap is undefined, then return target.[[Set]](P, V, Receiver). + +features: [Proxy] +---*/ + +var target = { + attr: 1 +}; +var p = new Proxy(target, {}); + +p.attr = 2; + +assert.sameValue(target.attr, 2); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/trap-is-undefined-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/set/trap-is-undefined-target-is-proxy.js new file mode 100644 index 0000000000..ac2f7a8497 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/trap-is-undefined-target-is-proxy.js @@ -0,0 +1,54 @@ +// 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-set-p-v-receiver +description: > + If "set" trap is null or undefined, [[Set]] call is properly + forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[Set]] ( P, V, Receiver ) + + [...] + 5. Let target be O.[[ProxyTarget]]. + 6. Let trap be ? GetMethod(handler, "set"). + 7. If trap is undefined, then + a. Return ? target.[[Set]](P, V, Receiver). +features: [Proxy, Reflect] +---*/ + +var func = function() {}; +var funcTarget = new Proxy(func, {}); +var funcProxy = new Proxy(funcTarget, { + set: undefined, +}); + +assert(Reflect.set(funcProxy, "prototype", null)); +assert.sameValue(func.prototype, null); + +assert(!Reflect.set(funcProxy, "length", 2)); +assert.throws(TypeError, function() { + "use strict"; + funcProxy.name = "foo"; +}); + + +var trapCalls = 0; +var target = new Proxy({}, { + set: function(_target, key) { + trapCalls++; + return key === "foo"; + }, +}); + +var proxy = new Proxy(target, { + set: undefined, +}); + +assert(Reflect.set(Object.create(proxy), "foo", 1)); +assert.sameValue(trapCalls, 1); + +assert(!Reflect.set(proxy, "bar", 2)); +assert.sameValue(trapCalls, 2); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/trap-is-undefined.js b/js/src/tests/test262/built-ins/Proxy/set/trap-is-undefined.js new file mode 100644 index 0000000000..3bc6d09e01 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/trap-is-undefined.js @@ -0,0 +1,25 @@ +// 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-set-p-v-receiver +description: > + [[Set]] ( P, V, Receiver) + + 7. If trap is undefined, then + a. Return ? target.[[Set]](P, V, Receiver) + +features: [Proxy] +---*/ + +var target = { + attr: 1 +}; +var p = new Proxy(target, { + set: undefined +}); + +p.attr = 2; + +assert.sameValue(target.attr, 2); + +reportCompare(0, 0); 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); |