diff --git a/test/language/statements/with/get-mutable-binding-binding-deleted-in-get-unscopables-strict-mode.js b/test/language/statements/with/get-mutable-binding-binding-deleted-in-get-unscopables-strict-mode.js new file mode 100644 index 0000000000..68d3810aba --- /dev/null +++ b/test/language/statements/with/get-mutable-binding-binding-deleted-in-get-unscopables-strict-mode.js @@ -0,0 +1,42 @@ +// Copyright (C) 2024 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object-environment-records-getbindingvalue-n-s +description: > + Binding deleted when retrieving unscopables. +info: | + 9.1.1.2.6 GetBindingValue ( N, S ) + + 1. Let bindingObject be envRec.[[BindingObject]]. + 2. Let value be ? HasProperty(bindingObject, N). + 3. If value is false, then + a. If S is false, return undefined; otherwise throw a ReferenceError exception. + ... + +flags: [noStrict] +features: [Symbol.unscopables] +---*/ + +var unscopablesCalled = 0; + +var env = { + binding: 0, + get [Symbol.unscopables]() { + unscopablesCalled++; + delete env.binding; + return null; + } +}; + +var result = null; +with (env) { + assert.throws(ReferenceError, function() { + "use strict"; + result = binding; + }); +} + +assert.sameValue(unscopablesCalled, 1, "get [Symbol.unscopables] called once"); + +assert.sameValue(result, null, "result not modified"); diff --git a/test/language/statements/with/get-mutable-binding-binding-deleted-in-get-unscopables.js b/test/language/statements/with/get-mutable-binding-binding-deleted-in-get-unscopables.js new file mode 100644 index 0000000000..7ebb6877ba --- /dev/null +++ b/test/language/statements/with/get-mutable-binding-binding-deleted-in-get-unscopables.js @@ -0,0 +1,39 @@ +// Copyright (C) 2024 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object-environment-records-getbindingvalue-n-s +description: > + Binding deleted when retrieving unscopables. +info: | + 9.1.1.2.6 GetBindingValue ( N, S ) + + 1. Let bindingObject be envRec.[[BindingObject]]. + 2. Let value be ? HasProperty(bindingObject, N). + 3. If value is false, then + a. If S is false, return undefined; otherwise throw a ReferenceError exception. + ... + +flags: [noStrict] +features: [Symbol.unscopables] +---*/ + +var unscopablesCalled = 0; + +var env = { + binding: 0, + get [Symbol.unscopables]() { + unscopablesCalled++; + delete env.binding; + return null; + } +}; + +var result = null; +with (env) { + result = binding; +} + +assert.sameValue(unscopablesCalled, 1, "get [Symbol.unscopables] called once"); + +assert.sameValue(result, undefined, "result set to undefined"); diff --git a/test/language/statements/with/set-mutable-binding-binding-deleted-in-get-unscopables-strict-mode.js b/test/language/statements/with/set-mutable-binding-binding-deleted-in-get-unscopables-strict-mode.js new file mode 100644 index 0000000000..d966990ae4 --- /dev/null +++ b/test/language/statements/with/set-mutable-binding-binding-deleted-in-get-unscopables-strict-mode.js @@ -0,0 +1,40 @@ +// Copyright (C) 2024 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object-environment-records-setmutablebinding-n-v-s +description: > + Binding deleted when retrieving unscopables. +info: | + 9.1.1.2.5 SetMutableBinding ( N, V, S ) + + 1. Let bindingObject be envRec.[[BindingObject]]. + 2. Let stillExists be ? HasProperty(bindingObject, N). + 3. If stillExists is false and S is true, throw a ReferenceError exception. + ... + +flags: [noStrict] +features: [Symbol.unscopables] +---*/ + +var unscopablesCalled = 0; + +var env = { + binding: 0, + get [Symbol.unscopables]() { + unscopablesCalled++; + delete env.binding; + return null; + } +}; + +with (env) { + assert.throws(ReferenceError, function() { + "use strict"; + binding = 123; + }); +} + +assert.sameValue(unscopablesCalled, 1, "get [Symbol.unscopables] called once"); + +assert.sameValue(Object.getOwnPropertyDescriptor(env, "binding"), undefined, "binding deleted"); diff --git a/test/language/statements/with/set-mutable-binding-binding-deleted-in-get-unscopables.js b/test/language/statements/with/set-mutable-binding-binding-deleted-in-get-unscopables.js new file mode 100644 index 0000000000..ec40c10db2 --- /dev/null +++ b/test/language/statements/with/set-mutable-binding-binding-deleted-in-get-unscopables.js @@ -0,0 +1,44 @@ +// Copyright (C) 2024 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object-environment-records-setmutablebinding-n-v-s +description: > + Binding deleted when retrieving unscopables. +info: | + 9.1.1.2.5 SetMutableBinding ( N, V, S ) + + 1. Let bindingObject be envRec.[[BindingObject]]. + 2. Let stillExists be ? HasProperty(bindingObject, N). + 3. If stillExists is false and S is true, throw a ReferenceError exception. + 4. Perform ? Set(bindingObject, N, V, S). + ... + +flags: [noStrict] +features: [Symbol.unscopables] +includes: [propertyHelper.js] +---*/ + +var unscopablesCalled = 0; + +var env = { + binding: 0, + get [Symbol.unscopables]() { + unscopablesCalled++; + delete env.binding; + return null; + } +}; + +with (env) { + binding = 123; +} + +assert.sameValue(unscopablesCalled, 1, "get [Symbol.unscopables] called once"); + +verifyProperty(env, "binding", { + value: 123, + writable: true, + enumerable: true, + configurable: true, +}); diff --git a/test/language/statements/with/set-mutable-binding-binding-deleted-with-typed-array-in-proto-chain-strict-mode.js b/test/language/statements/with/set-mutable-binding-binding-deleted-with-typed-array-in-proto-chain-strict-mode.js new file mode 100644 index 0000000000..75c732657f --- /dev/null +++ b/test/language/statements/with/set-mutable-binding-binding-deleted-with-typed-array-in-proto-chain-strict-mode.js @@ -0,0 +1,36 @@ +// Copyright (C) 2024 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object-environment-records-setmutablebinding-n-v-s +description: > + Typed Array index binding deleted from object. +info: | + 9.1.1.2.5 SetMutableBinding ( N, V, S ) + + 1. Let bindingObject be envRec.[[BindingObject]]. + 2. Let stillExists be ? HasProperty(bindingObject, N). + 3. If stillExists is false and S is true, throw a ReferenceError exception. + ... + +flags: [noStrict] +features: [TypedArray] +---*/ + +var typedArray = new Int32Array(10); + +var env = Object.create(typedArray); + +Object.defineProperty(env, "NaN", { + configurable: true, + value: 100, +}); + +with (env) { + assert.throws(ReferenceError, function() { + "use strict"; + NaN = (delete env.NaN, 0); + }); +} + +assert.sameValue(Object.getOwnPropertyDescriptor(env, "NaN"), undefined); diff --git a/test/language/statements/with/set-mutable-binding-binding-deleted-with-typed-array-in-proto-chain.js b/test/language/statements/with/set-mutable-binding-binding-deleted-with-typed-array-in-proto-chain.js new file mode 100644 index 0000000000..a351998209 --- /dev/null +++ b/test/language/statements/with/set-mutable-binding-binding-deleted-with-typed-array-in-proto-chain.js @@ -0,0 +1,33 @@ +// Copyright (C) 2024 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object-environment-records-setmutablebinding-n-v-s +description: > + Typed Array index binding deleted from object. +info: | + 9.1.1.2.5 SetMutableBinding ( N, V, S ) + + 1. Let bindingObject be envRec.[[BindingObject]]. + 2. Let stillExists be ? HasProperty(bindingObject, N). + 3. If stillExists is false and S is true, throw a ReferenceError exception. + 4. Perform ? Set(bindingObject, N, V, S). + +flags: [noStrict] +features: [TypedArray] +---*/ + +var typedArray = new Int32Array(10); + +var env = Object.create(typedArray); + +Object.defineProperty(env, "NaN", { + configurable: true, + value: 100, +}); + +with (env) { + NaN = (delete env.NaN, 0); +} + +assert.sameValue(Object.getOwnPropertyDescriptor(env, "NaN"), undefined);