summaryrefslogtreecommitdiffstats
path: root/js/src/tests/test262/language/expressions/logical-assignment
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/tests/test262/language/expressions/logical-assignment')
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/browser.js0
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-and.js63
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-nullish.js62
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-or.js63
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-short-circuit-and.js64
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-short-circuit-nullish.js63
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-short-circuit-or.js64
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-data-property-and.js55
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-data-property-nullish.js54
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-data-property-or.js55
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-data-property-short-circuit-and.js58
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-data-property-short-circuit-nullish.js57
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-data-property-short-circuit-or.js58
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-method-and.js51
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-method-short-circuit-nullish.js57
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-method-short-circuit-or.js58
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-readonly-accessor-property-and.js53
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-readonly-accessor-property-nullish.js52
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-readonly-accessor-property-or.js53
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-readonly-accessor-property-short-circuit-and.js57
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-readonly-accessor-property-short-circuit-nullish.js56
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-readonly-accessor-property-short-circuit-or.js57
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-arguments-strict-strict.js20
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-bigint.js29
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-lhs-before-rhs.js55
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-namedevaluation-arrow-function.js22
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-namedevaluation-class-expression.js22
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-namedevaluation-function.js22
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-no-set-put-strict.js31
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-no-set-strict.js28
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-non-extensible-strict.js22
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-non-simple-lhs.js20
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-non-writeable-put-strict.js29
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-non-writeable-strict.js26
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-unresolved-lhs-strict.js19
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-unresolved-rhs-put.js21
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-unresolved-rhs.js18
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator.js63
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-eval-strict-strict.js19
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-non-simple.js18
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-whitespace.js60
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-arguments-strict-strict.js20
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-bigint.js28
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-lhs-before-rhs.js55
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-namedevaluation-arrow-function.js22
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-namedevaluation-class-expression.js22
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-namedevaluation-function.js22
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-no-set-put-strict.js31
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-no-set-strict.js28
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-non-extensible-strict.js24
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-non-simple-lhs.js20
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-non-writeable-put-strict.js29
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-non-writeable-strict.js26
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-unresolved-lhs-strict.js19
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-unresolved-rhs-put.js21
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-unresolved-rhs.js18
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator.js62
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-eval-strict-strict.js19
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-non-simple.js18
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-whitespace.js60
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-arguments-strict-strict.js20
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-bigint.js29
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-lhs-before-rhs.js55
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-namedevaluation-arrow-function.js22
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-namedevaluation-class-expression.js22
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-namedevaluation-function.js22
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-no-set-put-strict.js31
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-no-set-strict.js28
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-non-extensible-strict.js24
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-non-simple-lhs.js20
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-non-writeable-put-strict.js29
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-non-writeable-strict.js26
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-unresolved-lhs-strict.js19
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-unresolved-rhs-put.js21
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-unresolved-rhs.js18
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator.js63
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-eval-strict-strict.js19
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-non-simple.js18
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-whitespace.js60
-rw-r--r--js/src/tests/test262/language/expressions/logical-assignment/shell.js0
80 files changed, 2844 insertions, 0 deletions
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/browser.js b/js/src/tests/test262/language/expressions/logical-assignment/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/browser.js
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-and.js b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-and.js
new file mode 100644
index 0000000000..600b575719
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-and.js
@@ -0,0 +1,63 @@
+// This file was procedurally generated from the following sources:
+// - src/logical-assignment-private/and.case
+// - src/logical-assignment-private/default/getter-setter.template
+/*---
+description: Logical-and assignment with target being a private reference (to an accessor property with getter and setter)
+esid: sec-assignment-operators-runtime-semantics-evaluation
+features: [class-fields-private, logical-assignment-operators]
+flags: [generated]
+info: |
+ sec-property-accessors-runtime-semantics-evaluation
+ MemberExpression : MemberExpression `.` PrivateIdentifier
+
+ 1. Let _baseReference_ be the result of evaluating |MemberExpression|.
+ 2. Let _baseValue_ be ? GetValue(_baseReference_).
+ 3. Let _fieldNameString_ be the StringValue of |PrivateIdentifier|.
+ 4. Return ! MakePrivateReference(_baseValue_, _fieldNameString_).
+
+ PutValue (V, W)
+ ...
+ 5.b. If IsPrivateReference(_V_) is *true*, then
+ i. Return ? PrivateSet(_baseObj_, _V_.[[ReferencedName]], _W_).
+
+ PrivateSet (O, P, value)
+ ...
+ 5.a. Assert: _entry_.[[Kind]] is ~accessor~.
+ ...
+ 5.c. Let _setter_ be _entry_.[[Set]].
+ d. Perform ? Call(_setter_, _O_, « _value_ »).
+
+
+ sec-assignment-operators-runtime-semantics-evaluation
+ AssignmentExpression : LeftHandSideExpression &&= AssignmentExpression
+ 1. Let _lref_ be the result of evaluating |LeftHandSideExpression|.
+ 2. Let _lval_ be ? GetValue(_lref_).
+ 3. Let _lbool_ be ! ToBoolean(_lval_).
+ 4. If _lbool_ is *false*, return _lval_.
+ ...
+ 7. Perform ? PutValue(_lref_, _rval_).
+ 8. Return _rval_.
+---*/
+
+
+class C {
+ #setterCalledWith;
+ get #field() {
+ return true;
+ }
+ set #field(value) {
+ this.#setterCalledWith = value;
+ }
+ compoundAssignment() {
+ return this.#field &&= false;
+ }
+ setterCalledWithValue() {
+ return this.#setterCalledWith;
+ }
+}
+
+const o = new C();
+assert.sameValue(o.compoundAssignment(), false, "The expression should evaluate to the result");
+assert.sameValue(o.setterCalledWithValue(), false, "PutValue should call the setter with the result");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-nullish.js b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-nullish.js
new file mode 100644
index 0000000000..8bb644f294
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-nullish.js
@@ -0,0 +1,62 @@
+// This file was procedurally generated from the following sources:
+// - src/logical-assignment-private/nullish.case
+// - src/logical-assignment-private/default/getter-setter.template
+/*---
+description: Nullish-coalescing assignment with target being a private reference (to an accessor property with getter and setter)
+esid: sec-assignment-operators-runtime-semantics-evaluation
+features: [class-fields-private, logical-assignment-operators]
+flags: [generated]
+info: |
+ sec-property-accessors-runtime-semantics-evaluation
+ MemberExpression : MemberExpression `.` PrivateIdentifier
+
+ 1. Let _baseReference_ be the result of evaluating |MemberExpression|.
+ 2. Let _baseValue_ be ? GetValue(_baseReference_).
+ 3. Let _fieldNameString_ be the StringValue of |PrivateIdentifier|.
+ 4. Return ! MakePrivateReference(_baseValue_, _fieldNameString_).
+
+ PutValue (V, W)
+ ...
+ 5.b. If IsPrivateReference(_V_) is *true*, then
+ i. Return ? PrivateSet(_baseObj_, _V_.[[ReferencedName]], _W_).
+
+ PrivateSet (O, P, value)
+ ...
+ 5.a. Assert: _entry_.[[Kind]] is ~accessor~.
+ ...
+ 5.c. Let _setter_ be _entry_.[[Set]].
+ d. Perform ? Call(_setter_, _O_, « _value_ »).
+
+
+ sec-assignment-operators-runtime-semantics-evaluation
+ AssignmentExpression : LeftHandSideExpression ??= AssignmentExpression
+ 1. Let _lref_ be the result of evaluating |LeftHandSideExpression|.
+ 2. Let _lval_ be ? GetValue(_lref_).
+ 3. If _lval_ is neither *undefined* nor *null*, return _lval_.
+ ...
+ 6. Perform ? PutValue(_lref_, _rval_).
+ 7. Return _rval_.
+---*/
+
+
+class C {
+ #setterCalledWith;
+ get #field() {
+ return null;
+ }
+ set #field(value) {
+ this.#setterCalledWith = value;
+ }
+ compoundAssignment() {
+ return this.#field ??= 1;
+ }
+ setterCalledWithValue() {
+ return this.#setterCalledWith;
+ }
+}
+
+const o = new C();
+assert.sameValue(o.compoundAssignment(), 1, "The expression should evaluate to the result");
+assert.sameValue(o.setterCalledWithValue(), 1, "PutValue should call the setter with the result");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-or.js b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-or.js
new file mode 100644
index 0000000000..769a1d4d16
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-or.js
@@ -0,0 +1,63 @@
+// This file was procedurally generated from the following sources:
+// - src/logical-assignment-private/or.case
+// - src/logical-assignment-private/default/getter-setter.template
+/*---
+description: Logical-or assignment with target being a private reference (to an accessor property with getter and setter)
+esid: sec-assignment-operators-runtime-semantics-evaluation
+features: [class-fields-private, logical-assignment-operators]
+flags: [generated]
+info: |
+ sec-property-accessors-runtime-semantics-evaluation
+ MemberExpression : MemberExpression `.` PrivateIdentifier
+
+ 1. Let _baseReference_ be the result of evaluating |MemberExpression|.
+ 2. Let _baseValue_ be ? GetValue(_baseReference_).
+ 3. Let _fieldNameString_ be the StringValue of |PrivateIdentifier|.
+ 4. Return ! MakePrivateReference(_baseValue_, _fieldNameString_).
+
+ PutValue (V, W)
+ ...
+ 5.b. If IsPrivateReference(_V_) is *true*, then
+ i. Return ? PrivateSet(_baseObj_, _V_.[[ReferencedName]], _W_).
+
+ PrivateSet (O, P, value)
+ ...
+ 5.a. Assert: _entry_.[[Kind]] is ~accessor~.
+ ...
+ 5.c. Let _setter_ be _entry_.[[Set]].
+ d. Perform ? Call(_setter_, _O_, « _value_ »).
+
+
+ sec-assignment-operators-runtime-semantics-evaluation
+ AssignmentExpression : LeftHandSideExpression ||= AssignmentExpression
+ 1. Let _lref_ be the result of evaluating |LeftHandSideExpression|.
+ 2. Let _lval_ be ? GetValue(_lref_).
+ 3. Let _lbool_ be ! ToBoolean(_lval_).
+ 4. If _lbool_ is *true*, return _lval_.
+ ...
+ 7. Perform ? PutValue(_lref_, _rval_).
+ 8. Return _rval_.
+---*/
+
+
+class C {
+ #setterCalledWith;
+ get #field() {
+ return false;
+ }
+ set #field(value) {
+ this.#setterCalledWith = value;
+ }
+ compoundAssignment() {
+ return this.#field ||= true;
+ }
+ setterCalledWithValue() {
+ return this.#setterCalledWith;
+ }
+}
+
+const o = new C();
+assert.sameValue(o.compoundAssignment(), true, "The expression should evaluate to the result");
+assert.sameValue(o.setterCalledWithValue(), true, "PutValue should call the setter with the result");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-short-circuit-and.js b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-short-circuit-and.js
new file mode 100644
index 0000000000..3fbc6760d8
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-short-circuit-and.js
@@ -0,0 +1,64 @@
+// This file was procedurally generated from the following sources:
+// - src/logical-assignment-private/and.case
+// - src/logical-assignment-private/default/getter-setter-short-circuit.template
+/*---
+description: Logical-and assignment with target being a private reference (to an accessor property with getter and setter (short-circuit version))
+esid: sec-assignment-operators-runtime-semantics-evaluation
+features: [class-fields-private, logical-assignment-operators]
+flags: [generated]
+info: |
+ sec-property-accessors-runtime-semantics-evaluation
+ MemberExpression : MemberExpression `.` PrivateIdentifier
+
+ 1. Let _baseReference_ be the result of evaluating |MemberExpression|.
+ 2. Let _baseValue_ be ? GetValue(_baseReference_).
+ 3. Let _fieldNameString_ be the StringValue of |PrivateIdentifier|.
+ 4. Return ! MakePrivateReference(_baseValue_, _fieldNameString_).
+
+ PutValue (V, W)
+ ...
+ 5.b. If IsPrivateReference(_V_) is *true*, then
+ i. Return ? PrivateSet(_baseObj_, _V_.[[ReferencedName]], _W_).
+
+ PrivateSet (O, P, value)
+ ...
+ 5.a. Assert: _entry_.[[Kind]] is ~accessor~.
+ ...
+ 5.c. Let _setter_ be _entry_.[[Set]].
+ d. Perform ? Call(_setter_, _O_, « _value_ »).
+
+
+ sec-assignment-operators-runtime-semantics-evaluation
+ AssignmentExpression : LeftHandSideExpression &&= AssignmentExpression
+ 1. Let _lref_ be the result of evaluating |LeftHandSideExpression|.
+ 2. Let _lval_ be ? GetValue(_lref_).
+ 3. Let _lbool_ be ! ToBoolean(_lval_).
+ 4. If _lbool_ is *false*, return _lval_.
+ ...
+ 7. Perform ? PutValue(_lref_, _rval_).
+ 8. Return _rval_.
+---*/
+
+
+function doNotCall() {
+ throw new Test262Error("The right-hand side should not be evaluated");
+}
+
+class C {
+ setterWasCalled = false;
+ get #field() {
+ return false;
+ }
+ set #field(value) {
+ this.setterWasCalled = true;
+ }
+ compoundAssignment() {
+ return this.#field &&= doNotCall();
+ }
+}
+
+const o = new C();
+assert.sameValue(o.compoundAssignment(), false, "The expression should evaluate to the short-circuit value");
+assert(!o.setterWasCalled, "The setter should not be called");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-short-circuit-nullish.js b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-short-circuit-nullish.js
new file mode 100644
index 0000000000..4933a5e99d
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-short-circuit-nullish.js
@@ -0,0 +1,63 @@
+// This file was procedurally generated from the following sources:
+// - src/logical-assignment-private/nullish.case
+// - src/logical-assignment-private/default/getter-setter-short-circuit.template
+/*---
+description: Nullish-coalescing assignment with target being a private reference (to an accessor property with getter and setter (short-circuit version))
+esid: sec-assignment-operators-runtime-semantics-evaluation
+features: [class-fields-private, logical-assignment-operators]
+flags: [generated]
+info: |
+ sec-property-accessors-runtime-semantics-evaluation
+ MemberExpression : MemberExpression `.` PrivateIdentifier
+
+ 1. Let _baseReference_ be the result of evaluating |MemberExpression|.
+ 2. Let _baseValue_ be ? GetValue(_baseReference_).
+ 3. Let _fieldNameString_ be the StringValue of |PrivateIdentifier|.
+ 4. Return ! MakePrivateReference(_baseValue_, _fieldNameString_).
+
+ PutValue (V, W)
+ ...
+ 5.b. If IsPrivateReference(_V_) is *true*, then
+ i. Return ? PrivateSet(_baseObj_, _V_.[[ReferencedName]], _W_).
+
+ PrivateSet (O, P, value)
+ ...
+ 5.a. Assert: _entry_.[[Kind]] is ~accessor~.
+ ...
+ 5.c. Let _setter_ be _entry_.[[Set]].
+ d. Perform ? Call(_setter_, _O_, « _value_ »).
+
+
+ sec-assignment-operators-runtime-semantics-evaluation
+ AssignmentExpression : LeftHandSideExpression ??= AssignmentExpression
+ 1. Let _lref_ be the result of evaluating |LeftHandSideExpression|.
+ 2. Let _lval_ be ? GetValue(_lref_).
+ 3. If _lval_ is neither *undefined* nor *null*, return _lval_.
+ ...
+ 6. Perform ? PutValue(_lref_, _rval_).
+ 7. Return _rval_.
+---*/
+
+
+function doNotCall() {
+ throw new Test262Error("The right-hand side should not be evaluated");
+}
+
+class C {
+ setterWasCalled = false;
+ get #field() {
+ return 1;
+ }
+ set #field(value) {
+ this.setterWasCalled = true;
+ }
+ compoundAssignment() {
+ return this.#field ??= doNotCall();
+ }
+}
+
+const o = new C();
+assert.sameValue(o.compoundAssignment(), 1, "The expression should evaluate to the short-circuit value");
+assert(!o.setterWasCalled, "The setter should not be called");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-short-circuit-or.js b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-short-circuit-or.js
new file mode 100644
index 0000000000..ad8113b875
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-short-circuit-or.js
@@ -0,0 +1,64 @@
+// This file was procedurally generated from the following sources:
+// - src/logical-assignment-private/or.case
+// - src/logical-assignment-private/default/getter-setter-short-circuit.template
+/*---
+description: Logical-or assignment with target being a private reference (to an accessor property with getter and setter (short-circuit version))
+esid: sec-assignment-operators-runtime-semantics-evaluation
+features: [class-fields-private, logical-assignment-operators]
+flags: [generated]
+info: |
+ sec-property-accessors-runtime-semantics-evaluation
+ MemberExpression : MemberExpression `.` PrivateIdentifier
+
+ 1. Let _baseReference_ be the result of evaluating |MemberExpression|.
+ 2. Let _baseValue_ be ? GetValue(_baseReference_).
+ 3. Let _fieldNameString_ be the StringValue of |PrivateIdentifier|.
+ 4. Return ! MakePrivateReference(_baseValue_, _fieldNameString_).
+
+ PutValue (V, W)
+ ...
+ 5.b. If IsPrivateReference(_V_) is *true*, then
+ i. Return ? PrivateSet(_baseObj_, _V_.[[ReferencedName]], _W_).
+
+ PrivateSet (O, P, value)
+ ...
+ 5.a. Assert: _entry_.[[Kind]] is ~accessor~.
+ ...
+ 5.c. Let _setter_ be _entry_.[[Set]].
+ d. Perform ? Call(_setter_, _O_, « _value_ »).
+
+
+ sec-assignment-operators-runtime-semantics-evaluation
+ AssignmentExpression : LeftHandSideExpression ||= AssignmentExpression
+ 1. Let _lref_ be the result of evaluating |LeftHandSideExpression|.
+ 2. Let _lval_ be ? GetValue(_lref_).
+ 3. Let _lbool_ be ! ToBoolean(_lval_).
+ 4. If _lbool_ is *true*, return _lval_.
+ ...
+ 7. Perform ? PutValue(_lref_, _rval_).
+ 8. Return _rval_.
+---*/
+
+
+function doNotCall() {
+ throw new Test262Error("The right-hand side should not be evaluated");
+}
+
+class C {
+ setterWasCalled = false;
+ get #field() {
+ return true;
+ }
+ set #field(value) {
+ this.setterWasCalled = true;
+ }
+ compoundAssignment() {
+ return this.#field ||= doNotCall();
+ }
+}
+
+const o = new C();
+assert.sameValue(o.compoundAssignment(), true, "The expression should evaluate to the short-circuit value");
+assert(!o.setterWasCalled, "The setter should not be called");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-data-property-and.js b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-data-property-and.js
new file mode 100644
index 0000000000..48f9da1452
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-data-property-and.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/logical-assignment-private/and.case
+// - src/logical-assignment-private/default/data-property.template
+/*---
+description: Logical-and assignment with target being a private reference (to a field)
+esid: sec-assignment-operators-runtime-semantics-evaluation
+features: [class-fields-private, logical-assignment-operators]
+flags: [generated]
+info: |
+ sec-property-accessors-runtime-semantics-evaluation
+ MemberExpression : MemberExpression `.` PrivateIdentifier
+
+ 1. Let _baseReference_ be the result of evaluating |MemberExpression|.
+ 2. Let _baseValue_ be ? GetValue(_baseReference_).
+ 3. Let _fieldNameString_ be the StringValue of |PrivateIdentifier|.
+ 4. Return ! MakePrivateReference(_baseValue_, _fieldNameString_).
+
+ PutValue (V, W)
+ ...
+ 5.b. If IsPrivateReference(_V_) is *true*, then
+ i. Return ? PrivateSet(_baseObj_, _V_.[[ReferencedName]], _W_).
+
+ PrivateSet (O, P, value)
+ ...
+ 3. If _entry_.[[Kind]] is ~field~, then
+ a. Set _entry_.[[Value]] to _value_.
+
+
+ sec-assignment-operators-runtime-semantics-evaluation
+ AssignmentExpression : LeftHandSideExpression &&= AssignmentExpression
+ 1. Let _lref_ be the result of evaluating |LeftHandSideExpression|.
+ 2. Let _lval_ be ? GetValue(_lref_).
+ 3. Let _lbool_ be ! ToBoolean(_lval_).
+ 4. If _lbool_ is *false*, return _lval_.
+ ...
+ 7. Perform ? PutValue(_lref_, _rval_).
+ 8. Return _rval_.
+---*/
+
+
+class C {
+ #field = true;
+ compoundAssignment() {
+ return this.#field &&= false;
+ }
+ fieldValue() {
+ return this.#field;
+ }
+}
+
+const o = new C();
+assert.sameValue(o.compoundAssignment(), false, "The expression should evaluate to the result");
+assert.sameValue(o.fieldValue(), false, "PutValue should store the result in the private reference");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-data-property-nullish.js b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-data-property-nullish.js
new file mode 100644
index 0000000000..895371b4ed
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-data-property-nullish.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/logical-assignment-private/nullish.case
+// - src/logical-assignment-private/default/data-property.template
+/*---
+description: Nullish-coalescing assignment with target being a private reference (to a field)
+esid: sec-assignment-operators-runtime-semantics-evaluation
+features: [class-fields-private, logical-assignment-operators]
+flags: [generated]
+info: |
+ sec-property-accessors-runtime-semantics-evaluation
+ MemberExpression : MemberExpression `.` PrivateIdentifier
+
+ 1. Let _baseReference_ be the result of evaluating |MemberExpression|.
+ 2. Let _baseValue_ be ? GetValue(_baseReference_).
+ 3. Let _fieldNameString_ be the StringValue of |PrivateIdentifier|.
+ 4. Return ! MakePrivateReference(_baseValue_, _fieldNameString_).
+
+ PutValue (V, W)
+ ...
+ 5.b. If IsPrivateReference(_V_) is *true*, then
+ i. Return ? PrivateSet(_baseObj_, _V_.[[ReferencedName]], _W_).
+
+ PrivateSet (O, P, value)
+ ...
+ 3. If _entry_.[[Kind]] is ~field~, then
+ a. Set _entry_.[[Value]] to _value_.
+
+
+ sec-assignment-operators-runtime-semantics-evaluation
+ AssignmentExpression : LeftHandSideExpression ??= AssignmentExpression
+ 1. Let _lref_ be the result of evaluating |LeftHandSideExpression|.
+ 2. Let _lval_ be ? GetValue(_lref_).
+ 3. If _lval_ is neither *undefined* nor *null*, return _lval_.
+ ...
+ 6. Perform ? PutValue(_lref_, _rval_).
+ 7. Return _rval_.
+---*/
+
+
+class C {
+ #field = null;
+ compoundAssignment() {
+ return this.#field ??= 1;
+ }
+ fieldValue() {
+ return this.#field;
+ }
+}
+
+const o = new C();
+assert.sameValue(o.compoundAssignment(), 1, "The expression should evaluate to the result");
+assert.sameValue(o.fieldValue(), 1, "PutValue should store the result in the private reference");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-data-property-or.js b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-data-property-or.js
new file mode 100644
index 0000000000..ecd05f0a85
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-data-property-or.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/logical-assignment-private/or.case
+// - src/logical-assignment-private/default/data-property.template
+/*---
+description: Logical-or assignment with target being a private reference (to a field)
+esid: sec-assignment-operators-runtime-semantics-evaluation
+features: [class-fields-private, logical-assignment-operators]
+flags: [generated]
+info: |
+ sec-property-accessors-runtime-semantics-evaluation
+ MemberExpression : MemberExpression `.` PrivateIdentifier
+
+ 1. Let _baseReference_ be the result of evaluating |MemberExpression|.
+ 2. Let _baseValue_ be ? GetValue(_baseReference_).
+ 3. Let _fieldNameString_ be the StringValue of |PrivateIdentifier|.
+ 4. Return ! MakePrivateReference(_baseValue_, _fieldNameString_).
+
+ PutValue (V, W)
+ ...
+ 5.b. If IsPrivateReference(_V_) is *true*, then
+ i. Return ? PrivateSet(_baseObj_, _V_.[[ReferencedName]], _W_).
+
+ PrivateSet (O, P, value)
+ ...
+ 3. If _entry_.[[Kind]] is ~field~, then
+ a. Set _entry_.[[Value]] to _value_.
+
+
+ sec-assignment-operators-runtime-semantics-evaluation
+ AssignmentExpression : LeftHandSideExpression ||= AssignmentExpression
+ 1. Let _lref_ be the result of evaluating |LeftHandSideExpression|.
+ 2. Let _lval_ be ? GetValue(_lref_).
+ 3. Let _lbool_ be ! ToBoolean(_lval_).
+ 4. If _lbool_ is *true*, return _lval_.
+ ...
+ 7. Perform ? PutValue(_lref_, _rval_).
+ 8. Return _rval_.
+---*/
+
+
+class C {
+ #field = false;
+ compoundAssignment() {
+ return this.#field ||= true;
+ }
+ fieldValue() {
+ return this.#field;
+ }
+}
+
+const o = new C();
+assert.sameValue(o.compoundAssignment(), true, "The expression should evaluate to the result");
+assert.sameValue(o.fieldValue(), true, "PutValue should store the result in the private reference");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-data-property-short-circuit-and.js b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-data-property-short-circuit-and.js
new file mode 100644
index 0000000000..b97a76a866
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-data-property-short-circuit-and.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/logical-assignment-private/and.case
+// - src/logical-assignment-private/default/data-property-short-circuit.template
+/*---
+description: Logical-and assignment with target being a private reference (to a field (short-circuit version))
+esid: sec-assignment-operators-runtime-semantics-evaluation
+features: [class-fields-private, logical-assignment-operators]
+flags: [generated]
+info: |
+ sec-property-accessors-runtime-semantics-evaluation
+ MemberExpression : MemberExpression `.` PrivateIdentifier
+
+ 1. Let _baseReference_ be the result of evaluating |MemberExpression|.
+ 2. Let _baseValue_ be ? GetValue(_baseReference_).
+ 3. Let _fieldNameString_ be the StringValue of |PrivateIdentifier|.
+ 4. Return ! MakePrivateReference(_baseValue_, _fieldNameString_).
+
+ PutValue (V, W)
+ ...
+ 5.b. If IsPrivateReference(_V_) is *true*, then
+ i. Return ? PrivateSet(_baseObj_, _V_.[[ReferencedName]], _W_).
+
+ PrivateSet (O, P, value)
+ ...
+ 3. If _entry_.[[Kind]] is ~field~, then
+ a. Set _entry_.[[Value]] to _value_.
+
+
+ sec-assignment-operators-runtime-semantics-evaluation
+ AssignmentExpression : LeftHandSideExpression &&= AssignmentExpression
+ 1. Let _lref_ be the result of evaluating |LeftHandSideExpression|.
+ 2. Let _lval_ be ? GetValue(_lref_).
+ 3. Let _lbool_ be ! ToBoolean(_lval_).
+ 4. If _lbool_ is *false*, return _lval_.
+ ...
+ 7. Perform ? PutValue(_lref_, _rval_).
+ 8. Return _rval_.
+---*/
+
+
+function doNotCall() {
+ throw new Test262Error("The right-hand side should not be evaluated");
+}
+
+class C {
+ #field = false;
+ compoundAssignment() {
+ return this.#field &&= doNotCall();
+ }
+ fieldValue() {
+ return this.#field;
+ }
+}
+
+const o = new C();
+assert.sameValue(o.compoundAssignment(), false, "The expression should evaluate to the short-circuit value");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-data-property-short-circuit-nullish.js b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-data-property-short-circuit-nullish.js
new file mode 100644
index 0000000000..fa4568829b
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-data-property-short-circuit-nullish.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/logical-assignment-private/nullish.case
+// - src/logical-assignment-private/default/data-property-short-circuit.template
+/*---
+description: Nullish-coalescing assignment with target being a private reference (to a field (short-circuit version))
+esid: sec-assignment-operators-runtime-semantics-evaluation
+features: [class-fields-private, logical-assignment-operators]
+flags: [generated]
+info: |
+ sec-property-accessors-runtime-semantics-evaluation
+ MemberExpression : MemberExpression `.` PrivateIdentifier
+
+ 1. Let _baseReference_ be the result of evaluating |MemberExpression|.
+ 2. Let _baseValue_ be ? GetValue(_baseReference_).
+ 3. Let _fieldNameString_ be the StringValue of |PrivateIdentifier|.
+ 4. Return ! MakePrivateReference(_baseValue_, _fieldNameString_).
+
+ PutValue (V, W)
+ ...
+ 5.b. If IsPrivateReference(_V_) is *true*, then
+ i. Return ? PrivateSet(_baseObj_, _V_.[[ReferencedName]], _W_).
+
+ PrivateSet (O, P, value)
+ ...
+ 3. If _entry_.[[Kind]] is ~field~, then
+ a. Set _entry_.[[Value]] to _value_.
+
+
+ sec-assignment-operators-runtime-semantics-evaluation
+ AssignmentExpression : LeftHandSideExpression ??= AssignmentExpression
+ 1. Let _lref_ be the result of evaluating |LeftHandSideExpression|.
+ 2. Let _lval_ be ? GetValue(_lref_).
+ 3. If _lval_ is neither *undefined* nor *null*, return _lval_.
+ ...
+ 6. Perform ? PutValue(_lref_, _rval_).
+ 7. Return _rval_.
+---*/
+
+
+function doNotCall() {
+ throw new Test262Error("The right-hand side should not be evaluated");
+}
+
+class C {
+ #field = 1;
+ compoundAssignment() {
+ return this.#field ??= doNotCall();
+ }
+ fieldValue() {
+ return this.#field;
+ }
+}
+
+const o = new C();
+assert.sameValue(o.compoundAssignment(), 1, "The expression should evaluate to the short-circuit value");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-data-property-short-circuit-or.js b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-data-property-short-circuit-or.js
new file mode 100644
index 0000000000..c1e2e206ec
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-data-property-short-circuit-or.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/logical-assignment-private/or.case
+// - src/logical-assignment-private/default/data-property-short-circuit.template
+/*---
+description: Logical-or assignment with target being a private reference (to a field (short-circuit version))
+esid: sec-assignment-operators-runtime-semantics-evaluation
+features: [class-fields-private, logical-assignment-operators]
+flags: [generated]
+info: |
+ sec-property-accessors-runtime-semantics-evaluation
+ MemberExpression : MemberExpression `.` PrivateIdentifier
+
+ 1. Let _baseReference_ be the result of evaluating |MemberExpression|.
+ 2. Let _baseValue_ be ? GetValue(_baseReference_).
+ 3. Let _fieldNameString_ be the StringValue of |PrivateIdentifier|.
+ 4. Return ! MakePrivateReference(_baseValue_, _fieldNameString_).
+
+ PutValue (V, W)
+ ...
+ 5.b. If IsPrivateReference(_V_) is *true*, then
+ i. Return ? PrivateSet(_baseObj_, _V_.[[ReferencedName]], _W_).
+
+ PrivateSet (O, P, value)
+ ...
+ 3. If _entry_.[[Kind]] is ~field~, then
+ a. Set _entry_.[[Value]] to _value_.
+
+
+ sec-assignment-operators-runtime-semantics-evaluation
+ AssignmentExpression : LeftHandSideExpression ||= AssignmentExpression
+ 1. Let _lref_ be the result of evaluating |LeftHandSideExpression|.
+ 2. Let _lval_ be ? GetValue(_lref_).
+ 3. Let _lbool_ be ! ToBoolean(_lval_).
+ 4. If _lbool_ is *true*, return _lval_.
+ ...
+ 7. Perform ? PutValue(_lref_, _rval_).
+ 8. Return _rval_.
+---*/
+
+
+function doNotCall() {
+ throw new Test262Error("The right-hand side should not be evaluated");
+}
+
+class C {
+ #field = true;
+ compoundAssignment() {
+ return this.#field ||= doNotCall();
+ }
+ fieldValue() {
+ return this.#field;
+ }
+}
+
+const o = new C();
+assert.sameValue(o.compoundAssignment(), true, "The expression should evaluate to the short-circuit value");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-method-and.js b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-method-and.js
new file mode 100644
index 0000000000..94168ea59d
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-method-and.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/logical-assignment-private/and.case
+// - src/logical-assignment-private/default/method.template
+/*---
+description: Logical-and assignment with target being a private reference (to a private method)
+esid: sec-assignment-operators-runtime-semantics-evaluation
+features: [class-fields-private, logical-assignment-operators]
+flags: [generated]
+info: |
+ sec-property-accessors-runtime-semantics-evaluation
+ MemberExpression : MemberExpression `.` PrivateIdentifier
+
+ 1. Let _baseReference_ be the result of evaluating |MemberExpression|.
+ 2. Let _baseValue_ be ? GetValue(_baseReference_).
+ 3. Let _fieldNameString_ be the StringValue of |PrivateIdentifier|.
+ 4. Return ! MakePrivateReference(_baseValue_, _fieldNameString_).
+
+ PutValue (V, W)
+ ...
+ 5.b. If IsPrivateReference(_V_) is *true*, then
+ i. Return ? PrivateSet(_baseObj_, _V_.[[ReferencedName]], _W_).
+
+ PrivateSet (O, P, value)
+ ...
+ 4. Else if _entry_.[[Kind]] is ~method~, then
+ a. Throw a *TypeError* exception.
+
+
+ sec-assignment-operators-runtime-semantics-evaluation
+ AssignmentExpression : LeftHandSideExpression &&= AssignmentExpression
+ 1. Let _lref_ be the result of evaluating |LeftHandSideExpression|.
+ 2. Let _lval_ be ? GetValue(_lref_).
+ 3. Let _lbool_ be ! ToBoolean(_lval_).
+ 4. If _lbool_ is *false*, return _lval_.
+ ...
+ 7. Perform ? PutValue(_lref_, _rval_).
+ 8. Return _rval_.
+---*/
+
+
+class C {
+ #privateMethod() {}
+ compoundAssignment() {
+ return this.#privateMethod &&= 1;
+ }
+}
+
+const o = new C();
+assert.throws(TypeError, () => o.compoundAssignment(), "PutValue throws when storing the result in a method private reference");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-method-short-circuit-nullish.js b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-method-short-circuit-nullish.js
new file mode 100644
index 0000000000..aa1b7225c7
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-method-short-circuit-nullish.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/logical-assignment-private/nullish.case
+// - src/logical-assignment-private/default/method-short-circuit.template
+/*---
+description: Nullish-coalescing assignment with target being a private reference (to a private method (short-circuit version))
+esid: sec-assignment-operators-runtime-semantics-evaluation
+features: [class-fields-private, logical-assignment-operators]
+flags: [generated]
+info: |
+ sec-property-accessors-runtime-semantics-evaluation
+ MemberExpression : MemberExpression `.` PrivateIdentifier
+
+ 1. Let _baseReference_ be the result of evaluating |MemberExpression|.
+ 2. Let _baseValue_ be ? GetValue(_baseReference_).
+ 3. Let _fieldNameString_ be the StringValue of |PrivateIdentifier|.
+ 4. Return ! MakePrivateReference(_baseValue_, _fieldNameString_).
+
+ PutValue (V, W)
+ ...
+ 5.b. If IsPrivateReference(_V_) is *true*, then
+ i. Return ? PrivateSet(_baseObj_, _V_.[[ReferencedName]], _W_).
+
+ PrivateSet (O, P, value)
+ ...
+ 4. Else if _entry_.[[Kind]] is ~method~, then
+ a. Throw a *TypeError* exception.
+
+
+ sec-assignment-operators-runtime-semantics-evaluation
+ AssignmentExpression : LeftHandSideExpression ??= AssignmentExpression
+ 1. Let _lref_ be the result of evaluating |LeftHandSideExpression|.
+ 2. Let _lval_ be ? GetValue(_lref_).
+ 3. If _lval_ is neither *undefined* nor *null*, return _lval_.
+ ...
+ 6. Perform ? PutValue(_lref_, _rval_).
+ 7. Return _rval_.
+---*/
+
+
+function doNotCall() {
+ throw new Test262Error("The right-hand side should not be evaluated");
+}
+
+class C {
+ #privateMethod() {}
+ compoundAssignment() {
+ return this.#privateMethod ??= doNotCall();
+ }
+ getPrivateMethodFunctionObject() {
+ return this.#privateMethod;
+ }
+}
+
+const o = new C();
+assert.sameValue(o.compoundAssignment(), o.getPrivateMethodFunctionObject(), "The expression should evaluate to the short-circuit value");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-method-short-circuit-or.js b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-method-short-circuit-or.js
new file mode 100644
index 0000000000..b19dd8efe0
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-method-short-circuit-or.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/logical-assignment-private/or.case
+// - src/logical-assignment-private/default/method-short-circuit.template
+/*---
+description: Logical-or assignment with target being a private reference (to a private method (short-circuit version))
+esid: sec-assignment-operators-runtime-semantics-evaluation
+features: [class-fields-private, logical-assignment-operators]
+flags: [generated]
+info: |
+ sec-property-accessors-runtime-semantics-evaluation
+ MemberExpression : MemberExpression `.` PrivateIdentifier
+
+ 1. Let _baseReference_ be the result of evaluating |MemberExpression|.
+ 2. Let _baseValue_ be ? GetValue(_baseReference_).
+ 3. Let _fieldNameString_ be the StringValue of |PrivateIdentifier|.
+ 4. Return ! MakePrivateReference(_baseValue_, _fieldNameString_).
+
+ PutValue (V, W)
+ ...
+ 5.b. If IsPrivateReference(_V_) is *true*, then
+ i. Return ? PrivateSet(_baseObj_, _V_.[[ReferencedName]], _W_).
+
+ PrivateSet (O, P, value)
+ ...
+ 4. Else if _entry_.[[Kind]] is ~method~, then
+ a. Throw a *TypeError* exception.
+
+
+ sec-assignment-operators-runtime-semantics-evaluation
+ AssignmentExpression : LeftHandSideExpression ||= AssignmentExpression
+ 1. Let _lref_ be the result of evaluating |LeftHandSideExpression|.
+ 2. Let _lval_ be ? GetValue(_lref_).
+ 3. Let _lbool_ be ! ToBoolean(_lval_).
+ 4. If _lbool_ is *true*, return _lval_.
+ ...
+ 7. Perform ? PutValue(_lref_, _rval_).
+ 8. Return _rval_.
+---*/
+
+
+function doNotCall() {
+ throw new Test262Error("The right-hand side should not be evaluated");
+}
+
+class C {
+ #privateMethod() {}
+ compoundAssignment() {
+ return this.#privateMethod ||= doNotCall();
+ }
+ getPrivateMethodFunctionObject() {
+ return this.#privateMethod;
+ }
+}
+
+const o = new C();
+assert.sameValue(o.compoundAssignment(), o.getPrivateMethodFunctionObject(), "The expression should evaluate to the short-circuit value");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-readonly-accessor-property-and.js b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-readonly-accessor-property-and.js
new file mode 100644
index 0000000000..6e47415ac7
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-readonly-accessor-property-and.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/logical-assignment-private/and.case
+// - src/logical-assignment-private/default/getter.template
+/*---
+description: Logical-and assignment with target being a private reference (to an accessor property with getter)
+esid: sec-assignment-operators-runtime-semantics-evaluation
+features: [class-fields-private, logical-assignment-operators]
+flags: [generated]
+info: |
+ sec-property-accessors-runtime-semantics-evaluation
+ MemberExpression : MemberExpression `.` PrivateIdentifier
+
+ 1. Let _baseReference_ be the result of evaluating |MemberExpression|.
+ 2. Let _baseValue_ be ? GetValue(_baseReference_).
+ 3. Let _fieldNameString_ be the StringValue of |PrivateIdentifier|.
+ 4. Return ! MakePrivateReference(_baseValue_, _fieldNameString_).
+
+ PutValue (V, W)
+ ...
+ 5.b. If IsPrivateReference(_V_) is *true*, then
+ i. Return ? PrivateSet(_baseObj_, _V_.[[ReferencedName]], _W_).
+
+ PrivateSet (O, P, value)
+ ...
+ 5.a. Assert: _entry_.[[Kind]] is ~accessor~.
+ b. If _entry_.[[Set]] is *undefined*, throw a *TypeError* exception.
+
+
+ sec-assignment-operators-runtime-semantics-evaluation
+ AssignmentExpression : LeftHandSideExpression &&= AssignmentExpression
+ 1. Let _lref_ be the result of evaluating |LeftHandSideExpression|.
+ 2. Let _lval_ be ? GetValue(_lref_).
+ 3. Let _lbool_ be ! ToBoolean(_lval_).
+ 4. If _lbool_ is *false*, return _lval_.
+ ...
+ 7. Perform ? PutValue(_lref_, _rval_).
+ 8. Return _rval_.
+---*/
+
+
+class C {
+ get #field() {
+ return true;
+ }
+ compoundAssignment() {
+ return this.#field &&= false;
+ }
+}
+
+const o = new C();
+assert.throws(TypeError, () => o.compoundAssignment(), "PutValue throws when storing the result if no setter");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-readonly-accessor-property-nullish.js b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-readonly-accessor-property-nullish.js
new file mode 100644
index 0000000000..45216d42a1
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-readonly-accessor-property-nullish.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/logical-assignment-private/nullish.case
+// - src/logical-assignment-private/default/getter.template
+/*---
+description: Nullish-coalescing assignment with target being a private reference (to an accessor property with getter)
+esid: sec-assignment-operators-runtime-semantics-evaluation
+features: [class-fields-private, logical-assignment-operators]
+flags: [generated]
+info: |
+ sec-property-accessors-runtime-semantics-evaluation
+ MemberExpression : MemberExpression `.` PrivateIdentifier
+
+ 1. Let _baseReference_ be the result of evaluating |MemberExpression|.
+ 2. Let _baseValue_ be ? GetValue(_baseReference_).
+ 3. Let _fieldNameString_ be the StringValue of |PrivateIdentifier|.
+ 4. Return ! MakePrivateReference(_baseValue_, _fieldNameString_).
+
+ PutValue (V, W)
+ ...
+ 5.b. If IsPrivateReference(_V_) is *true*, then
+ i. Return ? PrivateSet(_baseObj_, _V_.[[ReferencedName]], _W_).
+
+ PrivateSet (O, P, value)
+ ...
+ 5.a. Assert: _entry_.[[Kind]] is ~accessor~.
+ b. If _entry_.[[Set]] is *undefined*, throw a *TypeError* exception.
+
+
+ sec-assignment-operators-runtime-semantics-evaluation
+ AssignmentExpression : LeftHandSideExpression ??= AssignmentExpression
+ 1. Let _lref_ be the result of evaluating |LeftHandSideExpression|.
+ 2. Let _lval_ be ? GetValue(_lref_).
+ 3. If _lval_ is neither *undefined* nor *null*, return _lval_.
+ ...
+ 6. Perform ? PutValue(_lref_, _rval_).
+ 7. Return _rval_.
+---*/
+
+
+class C {
+ get #field() {
+ return null;
+ }
+ compoundAssignment() {
+ return this.#field ??= 1;
+ }
+}
+
+const o = new C();
+assert.throws(TypeError, () => o.compoundAssignment(), "PutValue throws when storing the result if no setter");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-readonly-accessor-property-or.js b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-readonly-accessor-property-or.js
new file mode 100644
index 0000000000..8c9695032e
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-readonly-accessor-property-or.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/logical-assignment-private/or.case
+// - src/logical-assignment-private/default/getter.template
+/*---
+description: Logical-or assignment with target being a private reference (to an accessor property with getter)
+esid: sec-assignment-operators-runtime-semantics-evaluation
+features: [class-fields-private, logical-assignment-operators]
+flags: [generated]
+info: |
+ sec-property-accessors-runtime-semantics-evaluation
+ MemberExpression : MemberExpression `.` PrivateIdentifier
+
+ 1. Let _baseReference_ be the result of evaluating |MemberExpression|.
+ 2. Let _baseValue_ be ? GetValue(_baseReference_).
+ 3. Let _fieldNameString_ be the StringValue of |PrivateIdentifier|.
+ 4. Return ! MakePrivateReference(_baseValue_, _fieldNameString_).
+
+ PutValue (V, W)
+ ...
+ 5.b. If IsPrivateReference(_V_) is *true*, then
+ i. Return ? PrivateSet(_baseObj_, _V_.[[ReferencedName]], _W_).
+
+ PrivateSet (O, P, value)
+ ...
+ 5.a. Assert: _entry_.[[Kind]] is ~accessor~.
+ b. If _entry_.[[Set]] is *undefined*, throw a *TypeError* exception.
+
+
+ sec-assignment-operators-runtime-semantics-evaluation
+ AssignmentExpression : LeftHandSideExpression ||= AssignmentExpression
+ 1. Let _lref_ be the result of evaluating |LeftHandSideExpression|.
+ 2. Let _lval_ be ? GetValue(_lref_).
+ 3. Let _lbool_ be ! ToBoolean(_lval_).
+ 4. If _lbool_ is *true*, return _lval_.
+ ...
+ 7. Perform ? PutValue(_lref_, _rval_).
+ 8. Return _rval_.
+---*/
+
+
+class C {
+ get #field() {
+ return false;
+ }
+ compoundAssignment() {
+ return this.#field ||= true;
+ }
+}
+
+const o = new C();
+assert.throws(TypeError, () => o.compoundAssignment(), "PutValue throws when storing the result if no setter");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-readonly-accessor-property-short-circuit-and.js b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-readonly-accessor-property-short-circuit-and.js
new file mode 100644
index 0000000000..f99b2c1a3b
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-readonly-accessor-property-short-circuit-and.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/logical-assignment-private/and.case
+// - src/logical-assignment-private/default/getter-short-circuit.template
+/*---
+description: Logical-and assignment with target being a private reference (to an accessor property with getter (short-circuit version))
+esid: sec-assignment-operators-runtime-semantics-evaluation
+features: [class-fields-private, logical-assignment-operators]
+flags: [generated]
+info: |
+ sec-property-accessors-runtime-semantics-evaluation
+ MemberExpression : MemberExpression `.` PrivateIdentifier
+
+ 1. Let _baseReference_ be the result of evaluating |MemberExpression|.
+ 2. Let _baseValue_ be ? GetValue(_baseReference_).
+ 3. Let _fieldNameString_ be the StringValue of |PrivateIdentifier|.
+ 4. Return ! MakePrivateReference(_baseValue_, _fieldNameString_).
+
+ PutValue (V, W)
+ ...
+ 5.b. If IsPrivateReference(_V_) is *true*, then
+ i. Return ? PrivateSet(_baseObj_, _V_.[[ReferencedName]], _W_).
+
+ PrivateSet (O, P, value)
+ ...
+ 5.a. Assert: _entry_.[[Kind]] is ~accessor~.
+ b. If _entry_.[[Set]] is *undefined*, throw a *TypeError* exception.
+
+
+ sec-assignment-operators-runtime-semantics-evaluation
+ AssignmentExpression : LeftHandSideExpression &&= AssignmentExpression
+ 1. Let _lref_ be the result of evaluating |LeftHandSideExpression|.
+ 2. Let _lval_ be ? GetValue(_lref_).
+ 3. Let _lbool_ be ! ToBoolean(_lval_).
+ 4. If _lbool_ is *false*, return _lval_.
+ ...
+ 7. Perform ? PutValue(_lref_, _rval_).
+ 8. Return _rval_.
+---*/
+
+
+function doNotCall() {
+ throw new Test262Error("The right-hand side should not be evaluated");
+}
+
+class C {
+ get #field() {
+ return false;
+ }
+ compoundAssignment() {
+ return this.#field &&= doNotCall();
+ }
+}
+
+const o = new C();
+assert.sameValue(o.compoundAssignment(), false, "The expression should evaluate to the short-circuit value");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-readonly-accessor-property-short-circuit-nullish.js b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-readonly-accessor-property-short-circuit-nullish.js
new file mode 100644
index 0000000000..00569dc546
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-readonly-accessor-property-short-circuit-nullish.js
@@ -0,0 +1,56 @@
+// This file was procedurally generated from the following sources:
+// - src/logical-assignment-private/nullish.case
+// - src/logical-assignment-private/default/getter-short-circuit.template
+/*---
+description: Nullish-coalescing assignment with target being a private reference (to an accessor property with getter (short-circuit version))
+esid: sec-assignment-operators-runtime-semantics-evaluation
+features: [class-fields-private, logical-assignment-operators]
+flags: [generated]
+info: |
+ sec-property-accessors-runtime-semantics-evaluation
+ MemberExpression : MemberExpression `.` PrivateIdentifier
+
+ 1. Let _baseReference_ be the result of evaluating |MemberExpression|.
+ 2. Let _baseValue_ be ? GetValue(_baseReference_).
+ 3. Let _fieldNameString_ be the StringValue of |PrivateIdentifier|.
+ 4. Return ! MakePrivateReference(_baseValue_, _fieldNameString_).
+
+ PutValue (V, W)
+ ...
+ 5.b. If IsPrivateReference(_V_) is *true*, then
+ i. Return ? PrivateSet(_baseObj_, _V_.[[ReferencedName]], _W_).
+
+ PrivateSet (O, P, value)
+ ...
+ 5.a. Assert: _entry_.[[Kind]] is ~accessor~.
+ b. If _entry_.[[Set]] is *undefined*, throw a *TypeError* exception.
+
+
+ sec-assignment-operators-runtime-semantics-evaluation
+ AssignmentExpression : LeftHandSideExpression ??= AssignmentExpression
+ 1. Let _lref_ be the result of evaluating |LeftHandSideExpression|.
+ 2. Let _lval_ be ? GetValue(_lref_).
+ 3. If _lval_ is neither *undefined* nor *null*, return _lval_.
+ ...
+ 6. Perform ? PutValue(_lref_, _rval_).
+ 7. Return _rval_.
+---*/
+
+
+function doNotCall() {
+ throw new Test262Error("The right-hand side should not be evaluated");
+}
+
+class C {
+ get #field() {
+ return 1;
+ }
+ compoundAssignment() {
+ return this.#field ??= doNotCall();
+ }
+}
+
+const o = new C();
+assert.sameValue(o.compoundAssignment(), 1, "The expression should evaluate to the short-circuit value");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-readonly-accessor-property-short-circuit-or.js b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-readonly-accessor-property-short-circuit-or.js
new file mode 100644
index 0000000000..b776af7911
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/left-hand-side-private-reference-readonly-accessor-property-short-circuit-or.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/logical-assignment-private/or.case
+// - src/logical-assignment-private/default/getter-short-circuit.template
+/*---
+description: Logical-or assignment with target being a private reference (to an accessor property with getter (short-circuit version))
+esid: sec-assignment-operators-runtime-semantics-evaluation
+features: [class-fields-private, logical-assignment-operators]
+flags: [generated]
+info: |
+ sec-property-accessors-runtime-semantics-evaluation
+ MemberExpression : MemberExpression `.` PrivateIdentifier
+
+ 1. Let _baseReference_ be the result of evaluating |MemberExpression|.
+ 2. Let _baseValue_ be ? GetValue(_baseReference_).
+ 3. Let _fieldNameString_ be the StringValue of |PrivateIdentifier|.
+ 4. Return ! MakePrivateReference(_baseValue_, _fieldNameString_).
+
+ PutValue (V, W)
+ ...
+ 5.b. If IsPrivateReference(_V_) is *true*, then
+ i. Return ? PrivateSet(_baseObj_, _V_.[[ReferencedName]], _W_).
+
+ PrivateSet (O, P, value)
+ ...
+ 5.a. Assert: _entry_.[[Kind]] is ~accessor~.
+ b. If _entry_.[[Set]] is *undefined*, throw a *TypeError* exception.
+
+
+ sec-assignment-operators-runtime-semantics-evaluation
+ AssignmentExpression : LeftHandSideExpression ||= AssignmentExpression
+ 1. Let _lref_ be the result of evaluating |LeftHandSideExpression|.
+ 2. Let _lval_ be ? GetValue(_lref_).
+ 3. Let _lbool_ be ! ToBoolean(_lval_).
+ 4. If _lbool_ is *true*, return _lval_.
+ ...
+ 7. Perform ? PutValue(_lref_, _rval_).
+ 8. Return _rval_.
+---*/
+
+
+function doNotCall() {
+ throw new Test262Error("The right-hand side should not be evaluated");
+}
+
+class C {
+ get #field() {
+ return true;
+ }
+ compoundAssignment() {
+ return this.#field ||= doNotCall();
+ }
+}
+
+const o = new C();
+assert.sameValue(o.compoundAssignment(), true, "The expression should evaluate to the short-circuit value");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-arguments-strict-strict.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-arguments-strict-strict.js
new file mode 100644
index 0000000000..dfb9c91e3b
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-arguments-strict-strict.js
@@ -0,0 +1,20 @@
+// |reftest| error:SyntaxError
+'use strict';
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators
+description: >
+ Strict Mode - SyntaxError is thrown if the identifier arguments
+ appear as the LeftHandSideExpression of a Logical Assignment
+ operator(&&=)
+flags: [onlyStrict]
+negative:
+ phase: parse
+ type: SyntaxError
+features: [logical-assignment-operators]
+---*/
+$DONOTEVALUATE();
+
+arguments &&= 20;
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-bigint.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-bigint.js
new file mode 100644
index 0000000000..ee443220f5
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-bigint.js
@@ -0,0 +1,29 @@
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: Logical And Assignment Operator
+features: [BigInt, logical-assignment-operators]
+info: |
+ AssignmentExpression:
+ LeftHandSideExpression &&= AssignmentExpression
+
+ 1. Let lref be the result of evaluating LeftHandSideExpression.
+ 2. Let lval be ? GetValue(lref).
+ 3. Let lbool be ! ToBoolean(lval).
+ 4. If lbool is false, return lval.
+ 5. Let rref be the result of evaluating AssignmentExpression.
+ 6. Let rval be ? GetValue(rref).
+ 7. Perform ? PutValue(lref, rval).
+ 8. Return rval.
+
+---*/
+
+var value = 0n;
+assert.sameValue(value &&= 1n, 0n, "(value &&= 1n) === 0n; where value = 0n");
+
+value = 2n;
+assert.sameValue(value &&= 1n, 1n, "(value &&= 1n) === 1n; where value = 2n");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-lhs-before-rhs.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-lhs-before-rhs.js
new file mode 100644
index 0000000000..bd11e7b6d1
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-lhs-before-rhs.js
@@ -0,0 +1,55 @@
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ The LeftHandSideExpression is evaluated before the AssignmentExpression.
+features: [logical-assignment-operators]
+
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+ var base = null;
+ var prop = function() {
+ throw new DummyError();
+ };
+ var expr = function() {
+ throw new Test262Error("right-hand side expression evaluated");
+ };
+
+ base[prop()] &&= expr();
+});
+
+assert.throws(TypeError, function() {
+ var base = null;
+ var prop = {
+ toString: function() {
+ throw new Test262Error("property key evaluated");
+ }
+ };
+ var expr = function() {
+ throw new Test262Error("right-hand side expression evaluated");
+ };
+
+ base[prop] &&= expr();
+});
+
+var count = 0;
+var obj = {};
+function incr() {
+ return ++count;
+}
+
+assert.sameValue(obj[incr()] &&= incr(), undefined, "obj[incr()] &&= incr()");
+assert.sameValue(obj[1], undefined, "obj[1]");
+assert.sameValue(count, 1, "count");
+
+obj[2] = 1;
+assert.sameValue(obj[incr()] &&= incr(), 3, "obj[incr()] &&= incr()");
+assert.sameValue(obj[2], 3, "obj[2]");
+assert.sameValue(count, 3, "count");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-namedevaluation-arrow-function.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-namedevaluation-arrow-function.js
new file mode 100644
index 0000000000..3beba1cbae
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-namedevaluation-arrow-function.js
@@ -0,0 +1,22 @@
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: NamedEvaluation of Logical And Assignment
+info: |
+ AssignmentExpression:
+ LeftHandSideExpression &&= AssignmentExpression
+
+ 5. If IsAnonymousFunctionDefinition(AssignmentExpression) and IsIdentifierRef of LeftHandSideExpression are both true, then
+ a. Let rval be NamedEvaluation of AssignmentExpression with argument GetReferencedName(lref).
+features: [logical-assignment-operators]
+
+---*/
+
+var value = 1;
+value &&= () => {};
+
+assert.sameValue(value.name, "value", "value");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-namedevaluation-class-expression.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-namedevaluation-class-expression.js
new file mode 100644
index 0000000000..eb907f8dbd
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-namedevaluation-class-expression.js
@@ -0,0 +1,22 @@
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: NamedEvaluation of Logical And Assignment
+info: |
+ AssignmentExpression:
+ LeftHandSideExpression &&= AssignmentExpression
+
+ 5. If IsAnonymousFunctionDefinition(AssignmentExpression) and IsIdentifierRef of LeftHandSideExpression are both true, then
+ a. Let rval be NamedEvaluation of AssignmentExpression with argument GetReferencedName(lref).
+features: [logical-assignment-operators]
+
+---*/
+
+var value = 1;
+value &&= class {};
+
+assert.sameValue(value.name, "value", "value");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-namedevaluation-function.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-namedevaluation-function.js
new file mode 100644
index 0000000000..dd1dbe9ded
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-namedevaluation-function.js
@@ -0,0 +1,22 @@
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: NamedEvaluation of Logical And Assignment
+info: |
+ AssignmentExpression:
+ LeftHandSideExpression &&= AssignmentExpression
+
+ 5. If IsAnonymousFunctionDefinition(AssignmentExpression) and IsIdentifierRef of LeftHandSideExpression are both true, then
+ a. Let rval be NamedEvaluation of AssignmentExpression with argument GetReferencedName(lref).
+features: [logical-assignment-operators]
+
+---*/
+
+var value = 1;
+value &&= function() {};
+
+assert.sameValue(value.name, "value", "value");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-no-set-put-strict.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-no-set-put-strict.js
new file mode 100644
index 0000000000..ac3fca3891
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-no-set-put-strict.js
@@ -0,0 +1,31 @@
+'use strict';
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ Strict Mode - TypeError is thrown if the LeftHandSide of a Logical
+ Assignment operator(&&=) is a reference to a data property with the
+ attribute value {[[Set]]:undefined} and PutValue step is reached.
+flags: [onlyStrict]
+features: [logical-assignment-operators]
+
+---*/
+
+var obj = {};
+Object.defineProperty(obj, "prop", {
+ get: function() {
+ return 2;
+ },
+ set: undefined,
+ enumerable: true,
+ configurable: true
+});
+
+assert.throws(TypeError, function() {
+ obj.prop &&= 1;
+});
+assert.sameValue(obj.prop, 2, "obj.prop");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-no-set-strict.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-no-set-strict.js
new file mode 100644
index 0000000000..9f730eead5
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-no-set-strict.js
@@ -0,0 +1,28 @@
+'use strict';
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ Strict Mode - TypeError is not thrown if the LeftHandSide of a Logical
+ Assignment operator(&&=) is a reference to a data property with the
+ attribute value {[[Set]]:undefined} and PutValue step is not reached.
+flags: [onlyStrict]
+features: [logical-assignment-operators]
+
+---*/
+
+var obj = {};
+Object.defineProperty(obj, "prop", {
+ get: function() {
+ return 0;
+ },
+ set: undefined,
+ enumerable: true,
+ configurable: true
+});
+
+assert.sameValue(obj.prop &&= 1, 0, "obj.prop");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-non-extensible-strict.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-non-extensible-strict.js
new file mode 100644
index 0000000000..d5b614d9c5
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-non-extensible-strict.js
@@ -0,0 +1,22 @@
+'use strict';
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ Strict Mode - TypeError is not thrown if The LeftHandSide of a Logical
+ Assignment operator(&&=) is a reference to a non-existent property of an
+ object whose [[Extensible]] internal property is false.
+flags: [onlyStrict]
+features: [logical-assignment-operators]
+
+---*/
+
+var obj = {};
+Object.preventExtensions(obj);
+
+obj.prop &&= 1;
+assert.sameValue(obj.prop, undefined, "obj.prop");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-non-simple-lhs.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-non-simple-lhs.js
new file mode 100644
index 0000000000..41ef1dbc56
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-non-simple-lhs.js
@@ -0,0 +1,20 @@
+// |reftest| error:SyntaxError
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-static-semantics-early-errors
+description: >
+ It is a Syntax Error if AssignmentTargetType of LeftHandSideExpression is
+ not simple.
+negative:
+ phase: parse
+ type: SyntaxError
+features: [logical-assignment-operators]
+
+---*/
+
+$DONOTEVALUATE();
+
+function test() {}
+test() &&= 1;
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-non-writeable-put-strict.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-non-writeable-put-strict.js
new file mode 100644
index 0000000000..074dfa9b75
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-non-writeable-put-strict.js
@@ -0,0 +1,29 @@
+'use strict';
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ Strict Mode - TypeError is thrown if the LeftHandSide of a Logical
+ Assignment operator(&&=) is a reference to a data property with the
+ attribute value {[[Writable]]:false} and PutValue step is reached.
+flags: [onlyStrict]
+features: [logical-assignment-operators]
+
+---*/
+
+var obj = {};
+Object.defineProperty(obj, "prop", {
+ value: 2,
+ writable: false,
+ enumerable: true,
+ configurable: true
+});
+
+assert.throws(TypeError, function() {
+ obj.prop &&= 1;
+});
+assert.sameValue(obj.prop, 2, "obj.prop");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-non-writeable-strict.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-non-writeable-strict.js
new file mode 100644
index 0000000000..befc13c134
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-non-writeable-strict.js
@@ -0,0 +1,26 @@
+'use strict';
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ Strict Mode - TypeError is not thrown if the LeftHandSide of a Logical
+ Assignment operator(&&=) is a reference to a data property with the
+ attribute value {[[Writable]]:false} and PutValue step is not reached.
+flags: [onlyStrict]
+features: [logical-assignment-operators]
+
+---*/
+
+var obj = {};
+Object.defineProperty(obj, "prop", {
+ value: 0,
+ writable: false,
+ enumerable: true,
+ configurable: true
+});
+
+assert.sameValue(obj.prop &&= 1, 0, "obj.prop");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-unresolved-lhs-strict.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-unresolved-lhs-strict.js
new file mode 100644
index 0000000000..8eaa75089f
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-unresolved-lhs-strict.js
@@ -0,0 +1,19 @@
+'use strict';
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ ReferenceError is thrown if the LeftHandSideExpression of a Logical
+ Assignment operator(&&=) evaluates to an unresolvable reference
+flags: [onlyStrict]
+features: [logical-assignment-operators]
+
+---*/
+
+assert.throws(ReferenceError, function() {
+ unresolved &&= 1;
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-unresolved-rhs-put.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-unresolved-rhs-put.js
new file mode 100644
index 0000000000..d298e9324a
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-unresolved-rhs-put.js
@@ -0,0 +1,21 @@
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ ReferenceError is thrown if the AssignmentExpression of a Logical
+ Assignment operator(&&=) evaluates to an unresolvable reference and the
+ AssignmentExpression is evaluated.
+features: [logical-assignment-operators]
+
+---*/
+
+var value = 2;
+
+assert.throws(ReferenceError, function() {
+ value &&= unresolved;
+});
+assert.sameValue(value, 2, "value");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-unresolved-rhs.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-unresolved-rhs.js
new file mode 100644
index 0000000000..631b5e9e3d
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator-unresolved-rhs.js
@@ -0,0 +1,18 @@
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ ReferenceError is not thrown if the AssignmentExpression of a Logical
+ Assignment operator(&&=) evaluates to an unresolvable reference and the
+ AssignmentExpression is not evaluated.
+features: [logical-assignment-operators]
+
+---*/
+
+var value = 0;
+
+assert.sameValue(value &&= unresolved, 0, "value");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator.js
new file mode 100644
index 0000000000..68fcd7bbaa
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-assignment-operator.js
@@ -0,0 +1,63 @@
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: Logical And Assignment Operator
+info: |
+ AssignmentExpression:
+ LeftHandSideExpression &&= AssignmentExpression
+
+ 1. Let lref be the result of evaluating LeftHandSideExpression.
+ 2. Let lval be ? GetValue(lref).
+ 3. Let lbool be ! ToBoolean(lval).
+ 4. If lbool is false, return lval.
+ 5. Let rref be the result of evaluating AssignmentExpression.
+ 6. Let rval be ? GetValue(rref).
+ 7. Perform ? PutValue(lref, rval).
+ 8. Return rval.
+features: [logical-assignment-operators]
+
+---*/
+
+var value = undefined;
+assert.sameValue(value &&= 1, undefined, "(value &&= 1) === undefined; where value = undefined");
+
+value = null;
+assert.sameValue(value &&= 1, null, "(value &&= 1) === null where value = null");
+
+value = false;
+assert.sameValue(value &&= 1, false, "(value &&= 1) === false; where value = false");
+
+value = 0;
+assert.sameValue(value &&= 1, 0, "(value &&= 1) === 0; where value = 0");
+
+value = -0;
+assert.sameValue(value &&= 1, -0, "(value &&= 1) === -0; where value = -0");
+
+value = NaN;
+assert.sameValue(value &&= 1, NaN, "(value &&= 1) === NaN; where value = NaN");
+
+value = "";
+assert.sameValue(value &&= 1, "", '(value &&= 1) === "" where value = ""');
+
+
+
+value = true;
+assert.sameValue(value &&= 1, 1, "(value &&= 1) === 1; where value = true");
+
+value = 2;
+assert.sameValue(value &&= 1, 1, "(value &&= 1) === 1; where value = 2");
+
+value = "test";
+assert.sameValue(value &&= 1, 1, '(value &&= 1) === 1; where value = "test"');
+
+var sym = Symbol("");
+value = sym;
+assert.sameValue(value &&= 1, 1, "(value &&= 1) === 1; where value = Symbol()");
+
+var obj = {};
+value = obj;
+assert.sameValue(value &&= 1, 1, "(value &&= 1) === 1; where value = {}");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-eval-strict-strict.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-eval-strict-strict.js
new file mode 100644
index 0000000000..acd470f5e4
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-eval-strict-strict.js
@@ -0,0 +1,19 @@
+// |reftest| error:SyntaxError
+'use strict';
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators
+description: >
+ Strict Mode - SyntaxError is thrown if the identifier eval appear
+ as the LeftHandSideExpression of a Logical Assignment operator(&&=)
+flags: [onlyStrict]
+negative:
+ phase: parse
+ type: SyntaxError
+features: [logical-assignment-operators]
+---*/
+$DONOTEVALUATE();
+
+eval &&= 20;
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-non-simple.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-non-simple.js
new file mode 100644
index 0000000000..d80e71c5b3
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-non-simple.js
@@ -0,0 +1,18 @@
+// |reftest| error:SyntaxError
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-static-semantics-early-errors
+info: |
+ It is an early Syntax Error if AssignmentTargetType of
+ LeftHandSideExpression is invalid or strict.
+description: Logical "&&=" assignment with non-simple target
+negative:
+ phase: parse
+ type: SyntaxError
+features: [logical-assignment-operators]
+---*/
+$DONOTEVALUATE();
+
+1 &&= 1;
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-whitespace.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-whitespace.js
new file mode 100644
index 0000000000..617b20e621
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-and-whitespace.js
@@ -0,0 +1,60 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: |
+ White Space and Line Terminator between LeftHandSideExpression and "@="
+ or between "@=" and AssignmentExpression are allowed
+esid: sec-assignment-operators
+description: Checking by evaluating expression "x[...]&&=[...]y"
+features: [logical-assignment-operators]
+---*/
+var x;
+
+x = 1;
+assert.sameValue(x &&= 2, 2, 'U+0009 (expression)');
+assert.sameValue(x, 2, 'U+0009 (side effect)');
+
+x = 1;
+assert.sameValue(x &&= 2, 2, 'U+000B (expression)');
+assert.sameValue(x, 2, 'U+000B (side effect)');
+
+x = 1;
+assert.sameValue(x &&= 2, 2, 'U+000C (expression)');
+assert.sameValue(x, 2, 'U+000C (side effect)');
+
+x = 1;
+assert.sameValue(x &&= 2, 2, 'U+0020 (expression)');
+assert.sameValue(x, 2, 'U+0020 (side effect)');
+
+x = 1;
+assert.sameValue(x &&= 2, 2, 'U+00A0 (expression)');
+assert.sameValue(x, 2, 'U+00A0 (side effect)');
+
+x = 1;
+assert.sameValue(x
+&&=
+2, 2, 'U+000A (expression)');
+assert.sameValue(x, 2, 'U+000A (side effect)');
+
+x = 1;
+assert.sameValue(x
+&&=
+2, 2, 'U+000D (expression)');
+assert.sameValue(x, 2, 'U+000D (side effect)');
+
+x = 1;
+assert.sameValue(x
&&=
2, 2, 'U+2028 (expression)');
+assert.sameValue(x, 2, 'U+2028 (side effect)');
+
+x = 1;
+assert.sameValue(x
&&=
2, 2, 'U+2029 (expression)');
+assert.sameValue(x, 2, 'U+2029 (side effect)');
+
+x = 1;
+assert.sameValue(x  
+

&&=  
+

2, 2, 'U+0009U+000BU+000CU+0020U+00A0U+000AU+000DU+2028U+2029 (expression)');
+assert.sameValue(x, 2, 'U+0009U+000BU+000CU+0020U+00A0U+000AU+000DU+2028U+2029 (side effect)');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-arguments-strict-strict.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-arguments-strict-strict.js
new file mode 100644
index 0000000000..24ca0cdcb6
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-arguments-strict-strict.js
@@ -0,0 +1,20 @@
+// |reftest| error:SyntaxError
+'use strict';
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators
+description: >
+ Strict Mode - SyntaxError is thrown if the identifier arguments
+ appear as the LeftHandSideExpression of a Logical Assignment
+ operator(??=)
+flags: [onlyStrict]
+negative:
+ phase: parse
+ type: SyntaxError
+features: [logical-assignment-operators]
+---*/
+$DONOTEVALUATE();
+
+arguments ??= 20;
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-bigint.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-bigint.js
new file mode 100644
index 0000000000..149099ab3f
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-bigint.js
@@ -0,0 +1,28 @@
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: Logical Nullish Assignment Operator
+features: [BigInt, logical-assignment-operators]
+info: |
+ AssignmentExpression:
+ LeftHandSideExpression ??= AssignmentExpression
+
+ 1. Let lref be the result of evaluating LeftHandSideExpression.
+ 2. Let lval be ? GetValue(lref).
+ 3. If lval is neither undefined nor null, return lval.
+ 4. Let rref be the result of evaluating AssignmentExpression.
+ 5. Let rval be ? GetValue(rref).
+ 6. Perform ? PutValue(lref, rval).
+ 7. Return rval.
+
+---*/
+
+var value = 0n;
+assert.sameValue(value ??= 1n, 0n, "(value ??= 1n) === 0n; where value = 0n");
+
+value = 2n;
+assert.sameValue(value ??= 1n, 2n, "(value ??= 1n) === 2n; where value = 2n");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-lhs-before-rhs.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-lhs-before-rhs.js
new file mode 100644
index 0000000000..1976fb4f91
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-lhs-before-rhs.js
@@ -0,0 +1,55 @@
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ The LeftHandSideExpression is evaluated before the AssignmentExpression.
+features: [logical-assignment-operators]
+
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+ var base = null;
+ var prop = function() {
+ throw new DummyError();
+ };
+ var expr = function() {
+ throw new Test262Error("right-hand side expression evaluated");
+ };
+
+ base[prop()] ??= expr();
+});
+
+assert.throws(TypeError, function() {
+ var base = null;
+ var prop = {
+ toString: function() {
+ throw new Test262Error("property key evaluated");
+ }
+ };
+ var expr = function() {
+ throw new Test262Error("right-hand side expression evaluated");
+ };
+
+ base[prop] ??= expr();
+});
+
+var count = 0;
+var obj = {};
+function incr() {
+ return ++count;
+}
+
+assert.sameValue(obj[incr()] ??= incr(), 2, "obj[incr()] ??= incr()");
+assert.sameValue(obj[1], 2, "obj[1]");
+assert.sameValue(count, 2, "count");
+
+obj[3] = 1;
+assert.sameValue(obj[incr()] ??= incr(), 1, "obj[incr()] ??= incr()");
+assert.sameValue(obj[3], 1, "obj[3]");
+assert.sameValue(count, 3, "count");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-namedevaluation-arrow-function.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-namedevaluation-arrow-function.js
new file mode 100644
index 0000000000..424d5f70a5
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-namedevaluation-arrow-function.js
@@ -0,0 +1,22 @@
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: NamedEvaluation of Logical Nullish Assignment
+info: |
+ AssignmentExpression:
+ LeftHandSideExpression ??= AssignmentExpression
+
+ 4. If IsAnonymousFunctionDefinition(AssignmentExpression) and IsIdentifierRef of LeftHandSideExpression are both true, then
+ a. Let rval be NamedEvaluation of AssignmentExpression with argument GetReferencedName(lref).
+features: [logical-assignment-operators]
+
+---*/
+
+var value = undefined;
+value ??= () => {};
+
+assert.sameValue(value.name, "value", "value");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-namedevaluation-class-expression.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-namedevaluation-class-expression.js
new file mode 100644
index 0000000000..389a8e896b
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-namedevaluation-class-expression.js
@@ -0,0 +1,22 @@
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: NamedEvaluation of Logical Nullish Assignment
+info: |
+ AssignmentExpression:
+ LeftHandSideExpression ??= AssignmentExpression
+
+ 4. If IsAnonymousFunctionDefinition(AssignmentExpression) and IsIdentifierRef of LeftHandSideExpression are both true, then
+ a. Let rval be NamedEvaluation of AssignmentExpression with argument GetReferencedName(lref).
+features: [logical-assignment-operators]
+
+---*/
+
+var value = undefined;
+value ??= class {};
+
+assert.sameValue(value.name, "value", "value");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-namedevaluation-function.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-namedevaluation-function.js
new file mode 100644
index 0000000000..f293f4c4cf
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-namedevaluation-function.js
@@ -0,0 +1,22 @@
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: NamedEvaluation of Logical Nullish Assignment
+info: |
+ AssignmentExpression:
+ LeftHandSideExpression ??= AssignmentExpression
+
+ 4. If IsAnonymousFunctionDefinition(AssignmentExpression) and IsIdentifierRef of LeftHandSideExpression are both true, then
+ a. Let rval be NamedEvaluation of AssignmentExpression with argument GetReferencedName(lref).
+features: [logical-assignment-operators]
+
+---*/
+
+var value = undefined;
+value ??= function() {};
+
+assert.sameValue(value.name, "value", "value");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-no-set-put-strict.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-no-set-put-strict.js
new file mode 100644
index 0000000000..8c7854d7b8
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-no-set-put-strict.js
@@ -0,0 +1,31 @@
+'use strict';
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ Strict Mode - TypeError is thrown if the LeftHandSide of a Logical
+ Assignment operator(??=) is a reference to a data property with the
+ attribute value {[[Set]]:undefined} and PutValue step is reached.
+flags: [onlyStrict]
+features: [logical-assignment-operators]
+
+---*/
+
+var obj = {};
+Object.defineProperty(obj, "prop", {
+ get: function() {
+ return undefined;
+ },
+ set: undefined,
+ enumerable: true,
+ configurable: true
+});
+
+assert.throws(TypeError, function() {
+ obj.prop ??= 1;
+});
+assert.sameValue(obj.prop, undefined, "obj.prop");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-no-set-strict.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-no-set-strict.js
new file mode 100644
index 0000000000..f97739174b
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-no-set-strict.js
@@ -0,0 +1,28 @@
+'use strict';
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ Strict Mode - TypeError is not thrown if the LeftHandSide of a Logical
+ Assignment operator(??=) is a reference to a data property with the
+ attribute value {[[Set]]:undefined} and PutValue step is not reached.
+flags: [onlyStrict]
+features: [logical-assignment-operators]
+
+---*/
+
+var obj = {};
+Object.defineProperty(obj, "prop", {
+ get: function() {
+ return 0;
+ },
+ set: undefined,
+ enumerable: true,
+ configurable: true
+});
+
+assert.sameValue(obj.prop ??= 1, 0, "obj.prop");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-non-extensible-strict.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-non-extensible-strict.js
new file mode 100644
index 0000000000..0c9b91f3fd
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-non-extensible-strict.js
@@ -0,0 +1,24 @@
+'use strict';
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ Strict Mode - TypeError is thrown if The LeftHandSide of a Logical
+ Assignment operator(??=) is a reference to a non-existent property
+ of an object whose [[Extensible]] internal property is false.
+flags: [onlyStrict]
+features: [logical-assignment-operators]
+
+---*/
+
+var obj = {};
+Object.preventExtensions(obj);
+
+assert.throws(TypeError, function() {
+ obj.prop ??= 1;
+});
+assert.sameValue(obj.prop, undefined, "obj.prop");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-non-simple-lhs.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-non-simple-lhs.js
new file mode 100644
index 0000000000..3e7a46afc3
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-non-simple-lhs.js
@@ -0,0 +1,20 @@
+// |reftest| error:SyntaxError
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-static-semantics-early-errors
+description: >
+ It is a Syntax Error if AssignmentTargetType of LeftHandSideExpression is
+ not simple.
+negative:
+ phase: parse
+ type: SyntaxError
+features: [logical-assignment-operators]
+
+---*/
+
+$DONOTEVALUATE();
+
+function test() {}
+test() ??= 1;
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-non-writeable-put-strict.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-non-writeable-put-strict.js
new file mode 100644
index 0000000000..caef17b5d5
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-non-writeable-put-strict.js
@@ -0,0 +1,29 @@
+'use strict';
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ Strict Mode - TypeError is thrown if the LeftHandSide of a Logical
+ Assignment operator(??=) is a reference to a data property with the
+ attribute value {[[Writable]]:false} and PutValue step is reached.
+flags: [onlyStrict]
+features: [logical-assignment-operators]
+
+---*/
+
+var obj = {};
+Object.defineProperty(obj, "prop", {
+ value: undefined,
+ writable: false,
+ enumerable: true,
+ configurable: true
+});
+
+assert.throws(TypeError, function() {
+ obj.prop ??= 1;
+});
+assert.sameValue(obj.prop, undefined, "obj.prop");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-non-writeable-strict.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-non-writeable-strict.js
new file mode 100644
index 0000000000..1340ca9390
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-non-writeable-strict.js
@@ -0,0 +1,26 @@
+'use strict';
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ Strict Mode - TypeError is not thrown if the LeftHandSide of a Logical
+ Assignment operator(??=) is a reference to a data property with the
+ attribute value {[[Writable]]:false} and PutValue step is not reached.
+flags: [onlyStrict]
+features: [logical-assignment-operators]
+
+---*/
+
+var obj = {};
+Object.defineProperty(obj, "prop", {
+ value: 0,
+ writable: false,
+ enumerable: true,
+ configurable: true
+});
+
+assert.sameValue(obj.prop ??= 1, 0, "obj.prop");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-unresolved-lhs-strict.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-unresolved-lhs-strict.js
new file mode 100644
index 0000000000..6473ffe917
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-unresolved-lhs-strict.js
@@ -0,0 +1,19 @@
+'use strict';
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ ReferenceError is thrown if the LeftHandSideExpression of a Logical
+ Assignment operator(??=) evaluates to an unresolvable reference
+flags: [onlyStrict]
+features: [logical-assignment-operators]
+
+---*/
+
+assert.throws(ReferenceError, function() {
+ unresolved ??= 1;
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-unresolved-rhs-put.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-unresolved-rhs-put.js
new file mode 100644
index 0000000000..70c1b469d1
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-unresolved-rhs-put.js
@@ -0,0 +1,21 @@
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ ReferenceError is thrown if the AssignmentExpression of a Logical
+ Assignment operator(??=) evaluates to an unresolvable reference and the
+ AssignmentExpression is evaluated.
+features: [logical-assignment-operators]
+
+---*/
+
+var value = undefined;
+
+assert.throws(ReferenceError, function() {
+ value ??= unresolved;
+});
+assert.sameValue(value, undefined, "value");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-unresolved-rhs.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-unresolved-rhs.js
new file mode 100644
index 0000000000..bc84537942
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator-unresolved-rhs.js
@@ -0,0 +1,18 @@
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ ReferenceError is not thrown if the AssignmentExpression of a Logical
+ Assignment operator(??=) evaluates to an unresolvable reference and the
+ AssignmentExpression is not evaluated.
+features: [logical-assignment-operators]
+
+---*/
+
+var value = 0;
+
+assert.sameValue(value ??= unresolved, 0, "value");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator.js
new file mode 100644
index 0000000000..f3cec88728
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-assignment-operator.js
@@ -0,0 +1,62 @@
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: Logical Nullish Assignment Operator
+info: |
+ AssignmentExpression:
+ LeftHandSideExpression ??= AssignmentExpression
+
+ 1. Let lref be the result of evaluating LeftHandSideExpression.
+ 2. Let lval be ? GetValue(lref).
+ 3. If lval is neither undefined nor null, return lval.
+ 4. Let rref be the result of evaluating AssignmentExpression.
+ 5. Let rval be ? GetValue(rref).
+ 6. Perform ? PutValue(lref, rval).
+ 7. Return rval.
+features: [logical-assignment-operators]
+
+---*/
+
+var value = undefined;
+assert.sameValue(value ??= 1, 1, "(value ??= 1) === 1; where value = undefined");
+
+value = null;
+assert.sameValue(value ??= 1, 1, "(value ??= 1) === 1; where value = null");
+
+value = false;
+assert.sameValue(value ??= 1, false, "(value ??= 1) === false; where value = false");
+
+value = 0;
+assert.sameValue(value ??= 1, 0, "(value ??= 1) === 0; where value = 0");
+
+value = -0;
+assert.sameValue(value ??= 1, -0, "(value ??= 1) === -0; where value = -0");
+
+value = NaN;
+assert.sameValue(value ??= 1, NaN, "(value ??= 1) === NaN; where value = NaN");
+
+value = "";
+assert.sameValue(value ??= 1, "", '(value ??= 1) === "" where value = ""');
+
+
+
+value = true;
+assert.sameValue(value ??= 1, true, "(value ??= 1) === true; where value = true");
+
+value = 2;
+assert.sameValue(value ??= 1, 2, "(value ??= 1) === 2; where value = 2");
+
+value = "test";
+assert.sameValue(value ??= 1, "test", '(value ??= 1) === "test"; where value = "test"');
+
+var sym = Symbol("");
+value = sym;
+assert.sameValue(value ??= 1, sym, "(value ??= 1) === Symbol(); where value = Symbol()");
+
+var obj = {};
+value = obj;
+assert.sameValue(value ??= 1, obj, "(value ??= 1) === {}; where value = {}");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-eval-strict-strict.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-eval-strict-strict.js
new file mode 100644
index 0000000000..61ff3631bc
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-eval-strict-strict.js
@@ -0,0 +1,19 @@
+// |reftest| error:SyntaxError
+'use strict';
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators
+description: >
+ Strict Mode - SyntaxError is thrown if the identifier eval appear
+ as the LeftHandSideExpression of a Logical Assignment operator(??=)
+flags: [onlyStrict]
+negative:
+ phase: parse
+ type: SyntaxError
+features: [logical-assignment-operators]
+---*/
+$DONOTEVALUATE();
+
+eval ??= 20;
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-non-simple.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-non-simple.js
new file mode 100644
index 0000000000..7385dcf6e1
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-non-simple.js
@@ -0,0 +1,18 @@
+// |reftest| error:SyntaxError
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-static-semantics-early-errors
+info: |
+ It is an early Syntax Error if AssignmentTargetType of
+ LeftHandSideExpression is invalid or strict.
+description: Logical "??=" assignment with non-simple target
+negative:
+ phase: parse
+ type: SyntaxError
+features: [logical-assignment-operators]
+---*/
+$DONOTEVALUATE();
+
+1 ??= 1;
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-whitespace.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-whitespace.js
new file mode 100644
index 0000000000..7d92163dd6
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-nullish-whitespace.js
@@ -0,0 +1,60 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: |
+ White Space and Line Terminator between LeftHandSideExpression and "@="
+ or between "@=" and AssignmentExpression are allowed
+esid: sec-assignment-operators
+description: Checking by evaluating expression "x[...]??=[...]y"
+features: [logical-assignment-operators]
+---*/
+var x;
+
+x = null;
+assert.sameValue(x ??= 1, 1, 'U+0009 (expression)');
+assert.sameValue(x, 1, 'U+0009 (side effect)');
+
+x = null;
+assert.sameValue(x ??= 1, 1, 'U+000B (expression)');
+assert.sameValue(x, 1, 'U+000B (side effect)');
+
+x = null;
+assert.sameValue(x ??= 1, 1, 'U+000C (expression)');
+assert.sameValue(x, 1, 'U+000C (side effect)');
+
+x = null;
+assert.sameValue(x ??= 1, 1, 'U+0020 (expression)');
+assert.sameValue(x, 1, 'U+0020 (side effect)');
+
+x = null;
+assert.sameValue(x ??= 1, 1, 'U+00A0 (expression)');
+assert.sameValue(x, 1, 'U+00A0 (side effect)');
+
+x = null;
+assert.sameValue(x
+??=
+1, 1, 'U+000A (expression)');
+assert.sameValue(x, 1, 'U+000A (side effect)');
+
+x = null;
+assert.sameValue(x
+??=
+1, 1, 'U+000D (expression)');
+assert.sameValue(x, 1, 'U+000D (side effect)');
+
+x = null;
+assert.sameValue(x
??=
1, 1, 'U+2028 (expression)');
+assert.sameValue(x, 1, 'U+2028 (side effect)');
+
+x = null;
+assert.sameValue(x
??=
1, 1, 'U+2029 (expression)');
+assert.sameValue(x, 1, 'U+2029 (side effect)');
+
+x = null;
+assert.sameValue(x  
+

??=  
+

1, 1, 'U+0009U+000BU+000CU+0020U+00A0U+000AU+000DU+2028U+2029 (expression)');
+assert.sameValue(x, 1, 'U+0009U+000BU+000CU+0020U+00A0U+000AU+000DU+2028U+2029 (side effect)');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-arguments-strict-strict.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-arguments-strict-strict.js
new file mode 100644
index 0000000000..48f2c6847c
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-arguments-strict-strict.js
@@ -0,0 +1,20 @@
+// |reftest| error:SyntaxError
+'use strict';
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators
+description: >
+ Strict Mode - SyntaxError is thrown if the identifier arguments
+ appear as the LeftHandSideExpression of a Logical Assignment
+ operator(||=)
+flags: [onlyStrict]
+negative:
+ phase: parse
+ type: SyntaxError
+features: [logical-assignment-operators]
+---*/
+$DONOTEVALUATE();
+
+arguments ||= 20;
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-bigint.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-bigint.js
new file mode 100644
index 0000000000..bda9c537eb
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-bigint.js
@@ -0,0 +1,29 @@
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: Logical Or Assignment Operator
+features: [BigInt, logical-assignment-operators]
+info: |
+ AssignmentExpression:
+ LeftHandSideExpression ||= AssignmentExpression
+
+ 1. Let lref be the result of evaluating LeftHandSideExpression.
+ 2. Let lval be ? GetValue(lref).
+ 3. Let lbool be ! ToBoolean(lval).
+ 4. If lbool is true, return lval.
+ 5. Let rref be the result of evaluating AssignmentExpression.
+ 6. Let rval be ? GetValue(rref).
+ 7. Perform ? PutValue(lref, rval).
+ 8. Return rval.
+
+---*/
+
+var value = 0n;
+assert.sameValue(value ||= 1n, 1n, "(value ||= 1n) === 1n; where value = 0n");
+
+value = 2n;
+assert.sameValue(value ||= 1n, 2n, "(value ||= 1n) === 2n; where value = 2n");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-lhs-before-rhs.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-lhs-before-rhs.js
new file mode 100644
index 0000000000..f65d4acfff
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-lhs-before-rhs.js
@@ -0,0 +1,55 @@
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ The LeftHandSideExpression is evaluated before the AssignmentExpression.
+features: [logical-assignment-operators]
+
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+ var base = null;
+ var prop = function() {
+ throw new DummyError();
+ };
+ var expr = function() {
+ throw new Test262Error("right-hand side expression evaluated");
+ };
+
+ base[prop()] ||= expr();
+});
+
+assert.throws(TypeError, function() {
+ var base = null;
+ var prop = {
+ toString: function() {
+ throw new Test262Error("property key evaluated");
+ }
+ };
+ var expr = function() {
+ throw new Test262Error("right-hand side expression evaluated");
+ };
+
+ base[prop] ||= expr();
+});
+
+var count = 0;
+var obj = {};
+function incr() {
+ return ++count;
+}
+
+assert.sameValue(obj[incr()] ||= incr(), 2, "obj[incr()] ||= incr()");
+assert.sameValue(obj[1], 2, "obj[1]");
+assert.sameValue(count, 2, "count");
+
+obj[3] = 1;
+assert.sameValue(obj[incr()] ||= incr(), 1, "obj[incr()] ||= incr()");
+assert.sameValue(obj[3], 1, "obj[3]");
+assert.sameValue(count, 3, "count");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-namedevaluation-arrow-function.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-namedevaluation-arrow-function.js
new file mode 100644
index 0000000000..19de1c8150
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-namedevaluation-arrow-function.js
@@ -0,0 +1,22 @@
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: NamedEvaluation of Logical Or Assignment
+info: |
+ AssignmentExpression:
+ LeftHandSideExpression ||= AssignmentExpression
+
+ 5. If IsAnonymousFunctionDefinition(AssignmentExpression) and IsIdentifierRef of LeftHandSideExpression are both true, then
+ a. Let rval be NamedEvaluation of AssignmentExpression with argument GetReferencedName(lref).
+features: [logical-assignment-operators]
+
+---*/
+
+var value = 0;
+value ||= () => {};
+
+assert.sameValue(value.name, "value", "value");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-namedevaluation-class-expression.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-namedevaluation-class-expression.js
new file mode 100644
index 0000000000..5c4aa91368
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-namedevaluation-class-expression.js
@@ -0,0 +1,22 @@
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: NamedEvaluation of Logical Or Assignment
+info: |
+ AssignmentExpression:
+ LeftHandSideExpression ||= AssignmentExpression
+
+ 5. If IsAnonymousFunctionDefinition(AssignmentExpression) and IsIdentifierRef of LeftHandSideExpression are both true, then
+ a. Let rval be NamedEvaluation of AssignmentExpression with argument GetReferencedName(lref).
+features: [logical-assignment-operators]
+
+---*/
+
+var value = 0;
+value ||= class {};
+
+assert.sameValue(value.name, "value", "value");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-namedevaluation-function.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-namedevaluation-function.js
new file mode 100644
index 0000000000..46c71f128b
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-namedevaluation-function.js
@@ -0,0 +1,22 @@
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: NamedEvaluation of Logical Or Assignment
+info: |
+ AssignmentExpression:
+ LeftHandSideExpression ||= AssignmentExpression
+
+ 5. If IsAnonymousFunctionDefinition(AssignmentExpression) and IsIdentifierRef of LeftHandSideExpression are both true, then
+ a. Let rval be NamedEvaluation of AssignmentExpression with argument GetReferencedName(lref).
+features: [logical-assignment-operators]
+
+---*/
+
+var value = 0;
+value ||= function() {};
+
+assert.sameValue(value.name, "value", "value");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-no-set-put-strict.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-no-set-put-strict.js
new file mode 100644
index 0000000000..0d987baf23
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-no-set-put-strict.js
@@ -0,0 +1,31 @@
+'use strict';
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ Strict Mode - TypeError is thrown if the LeftHandSide of a Logical
+ Assignment operator(||=) is a reference to a data property with the
+ attribute value {[[Set]]:undefined} and PutValue step is reached.
+flags: [onlyStrict]
+features: [logical-assignment-operators]
+
+---*/
+
+var obj = {};
+Object.defineProperty(obj, "prop", {
+ get: function() {
+ return 0;
+ },
+ set: undefined,
+ enumerable: true,
+ configurable: true
+});
+
+assert.throws(TypeError, function() {
+ obj.prop ||= 1;
+});
+assert.sameValue(obj.prop, 0, "obj.prop");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-no-set-strict.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-no-set-strict.js
new file mode 100644
index 0000000000..3decdd426a
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-no-set-strict.js
@@ -0,0 +1,28 @@
+'use strict';
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ Strict Mode - TypeError is not thrown if the LeftHandSide of a Logical
+ Assignment operator(||=) is a reference to a data property with the
+ attribute value {[[Set]]:undefined} and PutValue step is not reached.
+flags: [onlyStrict]
+features: [logical-assignment-operators]
+
+---*/
+
+var obj = {};
+Object.defineProperty(obj, "prop", {
+ get: function() {
+ return 2;
+ },
+ set: undefined,
+ enumerable: true,
+ configurable: true
+});
+
+assert.sameValue(obj.prop ||= 1, 2, "obj.prop");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-non-extensible-strict.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-non-extensible-strict.js
new file mode 100644
index 0000000000..6d3bd90e75
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-non-extensible-strict.js
@@ -0,0 +1,24 @@
+'use strict';
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ Strict Mode - TypeError is thrown if The LeftHandSide of a Logical
+ Assignment operator(||=) is a reference to a non-existent property
+ of an object whose [[Extensible]] internal property is false.
+flags: [onlyStrict]
+features: [logical-assignment-operators]
+
+---*/
+
+var obj = {};
+Object.preventExtensions(obj);
+
+assert.throws(TypeError, function() {
+ obj.prop ||= 1;
+});
+assert.sameValue(obj.prop, undefined, "obj.prop");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-non-simple-lhs.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-non-simple-lhs.js
new file mode 100644
index 0000000000..fe6f770428
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-non-simple-lhs.js
@@ -0,0 +1,20 @@
+// |reftest| error:SyntaxError
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-static-semantics-early-errors
+description: >
+ It is a Syntax Error if AssignmentTargetType of LeftHandSideExpression is
+ not simple.
+negative:
+ phase: parse
+ type: SyntaxError
+features: [logical-assignment-operators]
+
+---*/
+
+$DONOTEVALUATE();
+
+function test() {}
+test() ||= 1;
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-non-writeable-put-strict.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-non-writeable-put-strict.js
new file mode 100644
index 0000000000..d534ad4358
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-non-writeable-put-strict.js
@@ -0,0 +1,29 @@
+'use strict';
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ Strict Mode - TypeError is thrown if the LeftHandSide of a Logical
+ Assignment operator(||=) is a reference to a data property with the
+ attribute value {[[Writable]]:false} and PutValue step is reached.
+flags: [onlyStrict]
+features: [logical-assignment-operators]
+
+---*/
+
+var obj = {};
+Object.defineProperty(obj, "prop", {
+ value: 0,
+ writable: false,
+ enumerable: true,
+ configurable: true
+});
+
+assert.throws(TypeError, function() {
+ obj.prop ||= 1;
+});
+assert.sameValue(obj.prop, 0, "obj.prop");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-non-writeable-strict.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-non-writeable-strict.js
new file mode 100644
index 0000000000..58097a20ab
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-non-writeable-strict.js
@@ -0,0 +1,26 @@
+'use strict';
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ Strict Mode - TypeError is not thrown if the LeftHandSide of a Logical
+ Assignment operator(||=) is a reference to a data property with the
+ attribute value {[[Writable]]:false} and PutValue step is not reached.
+flags: [onlyStrict]
+features: [logical-assignment-operators]
+
+---*/
+
+var obj = {};
+Object.defineProperty(obj, "prop", {
+ value: 2,
+ writable: false,
+ enumerable: true,
+ configurable: true
+});
+
+assert.sameValue(obj.prop ||= 1, 2, "obj.prop");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-unresolved-lhs-strict.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-unresolved-lhs-strict.js
new file mode 100644
index 0000000000..e783ff5ff4
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-unresolved-lhs-strict.js
@@ -0,0 +1,19 @@
+'use strict';
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ ReferenceError is thrown if the LeftHandSideExpression of a Logical
+ Assignment operator(||=) evaluates to an unresolvable reference
+flags: [onlyStrict]
+features: [logical-assignment-operators]
+
+---*/
+
+assert.throws(ReferenceError, function() {
+ unresolved ||= 1;
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-unresolved-rhs-put.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-unresolved-rhs-put.js
new file mode 100644
index 0000000000..d482fe38d8
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-unresolved-rhs-put.js
@@ -0,0 +1,21 @@
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ ReferenceError is thrown if the AssignmentExpression of a Logical
+ Assignment operator(||=) evaluates to an unresolvable reference and the
+ AssignmentExpression is evaluated.
+features: [logical-assignment-operators]
+
+---*/
+
+var value = 0;
+
+assert.throws(ReferenceError, function() {
+ value ||= unresolved;
+});
+assert.sameValue(value, 0, "value");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-unresolved-rhs.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-unresolved-rhs.js
new file mode 100644
index 0000000000..6a41c574e9
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator-unresolved-rhs.js
@@ -0,0 +1,18 @@
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ ReferenceError is not thrown if the AssignmentExpression of a Logical
+ Assignment operator(||=) evaluates to an unresolvable reference and the
+ AssignmentExpression is not evaluated.
+features: [logical-assignment-operators]
+
+---*/
+
+var value = 2;
+
+assert.sameValue(value ||= unresolved, 2, "value");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator.js
new file mode 100644
index 0000000000..6043caaf87
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-assignment-operator.js
@@ -0,0 +1,63 @@
+// Copyright (c) 2020 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: Logical Or Assignment Operator
+info: |
+ AssignmentExpression:
+ LeftHandSideExpression ||= AssignmentExpression
+
+ 1. Let lref be the result of evaluating LeftHandSideExpression.
+ 2. Let lval be ? GetValue(lref).
+ 3. Let lbool be ! ToBoolean(lval).
+ 4. If lbool is true, return lval.
+ 5. Let rref be the result of evaluating AssignmentExpression.
+ 6. Let rval be ? GetValue(rref).
+ 7. Perform ? PutValue(lref, rval).
+ 8. Return rval.
+features: [logical-assignment-operators]
+
+---*/
+
+var value = undefined;
+assert.sameValue(value ||= 1, 1, "(value ||= 1) === 1; where value = undefined");
+
+value = null;
+assert.sameValue(value ||= 1, 1, "(value ||= 1) === 1; where value = null");
+
+value = false;
+assert.sameValue(value ||= 1, 1, "(value ||= 1) === 1; where value = false");
+
+value = 0;
+assert.sameValue(value ||= 1, 1, "(value ||= 1) === 1; where value = 0");
+
+value = -0;
+assert.sameValue(value ||= 1, 1, "(value ||= 1) === 1; where value = -0");
+
+value = NaN;
+assert.sameValue(value ||= 1, 1, "(value ||= 1) === 1; where value = NaN");
+
+value = "";
+assert.sameValue(value ||= 1, 1, '(value ||= 1) === 1; where value = ""');
+
+
+
+value = true;
+assert.sameValue(value ||= 1, true, "(value ||= 1) === true; where value = true");
+
+value = 2;
+assert.sameValue(value ||= 1, 2, "(value ||= 1) === 2; where value = 2");
+
+value = "test";
+assert.sameValue(value ||= 1, "test", '(value ||= 1) === "test"; where value = "test"');
+
+var sym = Symbol("");
+value = sym;
+assert.sameValue(value ||= 1, sym, "(value ||= 1) === Symbol(); where value = Symbol()");
+
+var obj = {};
+value = obj;
+assert.sameValue(value ||= 1, obj, "(value ||= 1) === {}; where value = {}");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-eval-strict-strict.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-eval-strict-strict.js
new file mode 100644
index 0000000000..d64e44e0b0
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-eval-strict-strict.js
@@ -0,0 +1,19 @@
+// |reftest| error:SyntaxError
+'use strict';
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators
+description: >
+ Strict Mode - SyntaxError is thrown if the identifier eval appear
+ as the LeftHandSideExpression of a Logical Assignment operator(||=)
+flags: [onlyStrict]
+negative:
+ phase: parse
+ type: SyntaxError
+features: [logical-assignment-operators]
+---*/
+$DONOTEVALUATE();
+
+eval ||= 20;
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-non-simple.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-non-simple.js
new file mode 100644
index 0000000000..2c3195010b
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-non-simple.js
@@ -0,0 +1,18 @@
+// |reftest| error:SyntaxError
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-assignment-operators-static-semantics-early-errors
+info: |
+ It is an early Syntax Error if AssignmentTargetType of
+ LeftHandSideExpression is invalid or strict.
+description: Logical "||=" assignment with non-simple target
+negative:
+ phase: parse
+ type: SyntaxError
+features: [logical-assignment-operators]
+---*/
+$DONOTEVALUATE();
+
+1 ||= 1;
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-whitespace.js b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-whitespace.js
new file mode 100644
index 0000000000..d4091dcb2d
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/lgcl-or-whitespace.js
@@ -0,0 +1,60 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: |
+ White Space and Line Terminator between LeftHandSideExpression and "@="
+ or between "@=" and AssignmentExpression are allowed
+esid: sec-assignment-operators
+description: Checking by evaluating expression "x[...]||=[...]y"
+features: [logical-assignment-operators]
+---*/
+var x;
+
+x = 0;
+assert.sameValue(x ||= 1, 1, 'U+0009 (expression)');
+assert.sameValue(x, 1, 'U+0009 (side effect)');
+
+x = 0;
+assert.sameValue(x ||= 1, 1, 'U+000B (expression)');
+assert.sameValue(x, 1, 'U+000B (side effect)');
+
+x = 0;
+assert.sameValue(x ||= 1, 1, 'U+000C (expression)');
+assert.sameValue(x, 1, 'U+000C (side effect)');
+
+x = 0;
+assert.sameValue(x ||= 1, 1, 'U+0020 (expression)');
+assert.sameValue(x, 1, 'U+0020 (side effect)');
+
+x = 0;
+assert.sameValue(x ||= 1, 1, 'U+00A0 (expression)');
+assert.sameValue(x, 1, 'U+00A0 (side effect)');
+
+x = 0;
+assert.sameValue(x
+||=
+1, 1, 'U+000A (expression)');
+assert.sameValue(x, 1, 'U+000A (side effect)');
+
+x = 0;
+assert.sameValue(x
+||=
+1, 1, 'U+000D (expression)');
+assert.sameValue(x, 1, 'U+000D (side effect)');
+
+x = 0;
+assert.sameValue(x
||=
1, 1, 'U+2028 (expression)');
+assert.sameValue(x, 1, 'U+2028 (side effect)');
+
+x = 0;
+assert.sameValue(x
||=
1, 1, 'U+2029 (expression)');
+assert.sameValue(x, 1, 'U+2029 (side effect)');
+
+x = 0;
+assert.sameValue(x  
+

||=  
+

1, 1, 'U+0009U+000BU+000CU+0020U+00A0U+000AU+000DU+2028U+2029 (expression)');
+assert.sameValue(x, 1, 'U+0009U+000BU+000CU+0020U+00A0U+000AU+000DU+2028U+2029 (side effect)');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/logical-assignment/shell.js b/js/src/tests/test262/language/expressions/logical-assignment/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/logical-assignment/shell.js