diff options
Diffstat (limited to 'js/src/tests/non262/expressions/short-circuit-compound-assignment-scope-lookup.js')
-rw-r--r-- | js/src/tests/non262/expressions/short-circuit-compound-assignment-scope-lookup.js | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/js/src/tests/non262/expressions/short-circuit-compound-assignment-scope-lookup.js b/js/src/tests/non262/expressions/short-circuit-compound-assignment-scope-lookup.js new file mode 100644 index 0000000000..dc1d7a421d --- /dev/null +++ b/js/src/tests/non262/expressions/short-circuit-compound-assignment-scope-lookup.js @@ -0,0 +1,191 @@ +// Test scope lookups are executed in the correct order. + +function createScope() { + let log = []; + let environment = {}; + let scope = new Proxy(environment, new Proxy({ + has(target, property) { + log.push({target, property}); + return Reflect.has(target, property); + }, + get(target, property, receiver) { + log.push({target, property, receiver}); + return Reflect.get(target, property, receiver); + }, + set(target, property, value, receiver) { + log.push({target, property, value, receiver}); + return Reflect.set(target, property, value, receiver); + }, + getOwnPropertyDescriptor(target, property) { + log.push({target, property}); + return Reflect.getOwnPropertyDescriptor(target, property); + }, + defineProperty(target, property, descriptor) { + log.push({target, property, descriptor}); + return Reflect.defineProperty(target, property, descriptor); + }, + }, { + get(target, property, receiver) { + log.push(property); + return Reflect.get(target, property, receiver); + } + })); + + return {log, environment, scope}; +} + +// AndAssignExpr +{ + let {log, environment, scope} = createScope(); + + environment.a = true; + + with (scope) { + a &&= false; + } + assertEq(environment.a, false); + + with (scope) { + a &&= true; + } + assertEq(environment.a, false); + + assertDeepEq(log, [ + // Execution Contexts, 8.3.2 ResolveBinding ( name [ , env ] ) + // Lexical Environments, 8.1.2.1 GetIdentifierReference ( lex, name, strict ) + // Object Environment Records, 8.1.1.2.1 HasBinding ( N ) + "has", {target: environment, property: "a"}, + "get", {target: environment, property: Symbol.unscopables, receiver: scope}, + + // Reference Type, 6.2.4.8 GetValue ( V ) + // Object Environment Records, 8.1.1.2.6 GetBindingValue ( N, S ) + "has", {target: environment, property: "a"}, + "get", {target: environment, property: "a", receiver: scope}, + + // Reference Type, 6.2.4.9 PutValue ( V, W ) + // Object Environment Records, 8.1.1.2.5 SetMutableBinding ( N, V, S ) + "set", {target: environment, property: "a", value: false, receiver: scope}, + + // Ordinary Objects, 9.1.9 [[Set]] ( P, V, Receiver ) + // Ordinary Objects, 9.1.9.1 OrdinarySet ( O, P, V, Receiver ) + // Ordinary Objects, 9.1.9.2 OrdinarySetWithOwnDescriptor ( O, P, V, Receiver, ownDesc ) + "getOwnPropertyDescriptor", {target: environment, property: "a"}, + "defineProperty", {target: environment, property: "a", descriptor: {value: false}}, + + // Execution Contexts, 8.3.2 ResolveBinding ( name [ , env ] ) + // Lexical Environments, 8.1.2.1 GetIdentifierReference ( lex, name, strict ) + // Object Environment Records, 8.1.1.2.1 HasBinding ( N ) + "has", {target: environment, property: "a"}, + "get", {target: environment, property: Symbol.unscopables, receiver: scope}, + + // Reference Type, 6.2.4.8 GetValue ( V ) + // Object Environment Records, 8.1.1.2.6 GetBindingValue ( N, S ) + "has", {target: environment, property: "a"}, + "get", {target: environment, property: "a", receiver: scope}, + ]); +} + +// OrAssignExpr +{ + let {log, environment, scope} = createScope(); + + environment.a = false; + + with (scope) { + a ||= true; + } + assertEq(environment.a, true); + + with (scope) { + a ||= false; + } + assertEq(environment.a, true); + + assertDeepEq(log, [ + // Execution Contexts, 8.3.2 ResolveBinding ( name [ , env ] ) + // Lexical Environments, 8.1.2.1 GetIdentifierReference ( lex, name, strict ) + // Object Environment Records, 8.1.1.2.1 HasBinding ( N ) + "has", {target: environment, property: "a"}, + "get", {target: environment, property: Symbol.unscopables, receiver: scope}, + + // Reference Type, 6.2.4.8 GetValue ( V ) + // Object Environment Records, 8.1.1.2.6 GetBindingValue ( N, S ) + "has", {target: environment, property: "a"}, + "get", {target: environment, property: "a", receiver: scope}, + + // Reference Type, 6.2.4.9 PutValue ( V, W ) + // Object Environment Records, 8.1.1.2.5 SetMutableBinding ( N, V, S ) + "set", {target: environment, property: "a", value: true, receiver: scope}, + + // Ordinary Objects, 9.1.9 [[Set]] ( P, V, Receiver ) + // Ordinary Objects, 9.1.9.1 OrdinarySet ( O, P, V, Receiver ) + // Ordinary Objects, 9.1.9.2 OrdinarySetWithOwnDescriptor ( O, P, V, Receiver, ownDesc ) + "getOwnPropertyDescriptor", {target: environment, property: "a"}, + "defineProperty", {target: environment, property: "a", descriptor: {value: true}}, + + // Execution Contexts, 8.3.2 ResolveBinding ( name [ , env ] ) + // Lexical Environments, 8.1.2.1 GetIdentifierReference ( lex, name, strict ) + // Object Environment Records, 8.1.1.2.1 HasBinding ( N ) + "has", {target: environment, property: "a"}, + "get", {target: environment, property: Symbol.unscopables, receiver: scope}, + + // Reference Type, 6.2.4.8 GetValue ( V ) + // Object Environment Records, 8.1.1.2.6 GetBindingValue ( N, S ) + "has", {target: environment, property: "a"}, + "get", {target: environment, property: "a", receiver: scope}, + ]); +} + +// CoalesceAssignExpr +{ + let {log, environment, scope} = createScope(); + + environment.a = null; + + with (scope) { + a ??= true; + } + assertEq(environment.a, true); + + with (scope) { + a ??= false; + } + assertEq(environment.a, true); + + assertDeepEq(log, [ + // Execution Contexts, 8.3.2 ResolveBinding ( name [ , env ] ) + // Lexical Environments, 8.1.2.1 GetIdentifierReference ( lex, name, strict ) + // Object Environment Records, 8.1.1.2.1 HasBinding ( N ) + "has", {target: environment, property: "a"}, + "get", {target: environment, property: Symbol.unscopables, receiver: scope}, + + // Reference Type, 6.2.4.8 GetValue ( V ) + // Object Environment Records, 8.1.1.2.6 GetBindingValue ( N, S ) + "has", {target: environment, property: "a"}, + "get", {target: environment, property: "a", receiver: scope}, + + // Reference Type, 6.2.4.9 PutValue ( V, W ) + // Object Environment Records, 8.1.1.2.5 SetMutableBinding ( N, V, S ) + "set", {target: environment, property: "a", value: true, receiver: scope}, + + // Ordinary Objects, 9.1.9 [[Set]] ( P, V, Receiver ) + // Ordinary Objects, 9.1.9.1 OrdinarySet ( O, P, V, Receiver ) + // Ordinary Objects, 9.1.9.2 OrdinarySetWithOwnDescriptor ( O, P, V, Receiver, ownDesc ) + "getOwnPropertyDescriptor", {target: environment, property: "a"}, + "defineProperty", {target: environment, property: "a", descriptor: {value: true}}, + + // Execution Contexts, 8.3.2 ResolveBinding ( name [ , env ] ) + // Lexical Environments, 8.1.2.1 GetIdentifierReference ( lex, name, strict ) + // Object Environment Records, 8.1.1.2.1 HasBinding ( N ) + "has", {target: environment, property: "a"}, + "get", {target: environment, property: Symbol.unscopables, receiver: scope}, + + // Reference Type, 6.2.4.8 GetValue ( V ) + // Object Environment Records, 8.1.1.2.6 GetBindingValue ( N, S ) + "has", {target: environment, property: "a"}, + "get", {target: environment, property: "a", receiver: scope}, + ]); +} + +if (typeof reportCompare === "function") + reportCompare(0, 0); |