Title: [287544] trunk
Revision
287544
Author
[email protected]
Date
2022-01-03 08:50:30 -0800 (Mon, 03 Jan 2022)

Log Message

[JSC] Read-modify-write operation's second put-to-scope should not throw error if binding does not exist
https://bugs.webkit.org/show_bug.cgi?id=234813

Reviewed by Alexey Shvayka.

JSTests:

* stress/global-object-read-modify-write-remove-at-get-strict.js: Added.
(shouldThrow):
* stress/global-object-read-modify-write-remove-at-get.js: Added.
(shouldBe):
* test262/expectations.yaml:

Source/_javascript_Core:

This patch fixes a bug throwing RefereceError when read-modify-write's read operation removes binding from object.
Throwing error should happen only when evaluating it under strict mode.

* bytecompiler/NodesCodegen.cpp:
(JSC::PostfixNode::emitResolve):
(JSC::PrefixNode::emitResolve):
(JSC::ReadModifyResolveNode::emitBytecode):
(JSC::ShortCircuitReadModifyResolveNode::emitBytecode):

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (287543 => 287544)


--- trunk/JSTests/ChangeLog	2022-01-03 16:31:18 UTC (rev 287543)
+++ trunk/JSTests/ChangeLog	2022-01-03 16:50:30 UTC (rev 287544)
@@ -1,5 +1,18 @@
 2022-01-03  Yusuke Suzuki  <[email protected]>
 
+        [JSC] Read-modify-write operation's second put-to-scope should not throw error if binding does not exist
+        https://bugs.webkit.org/show_bug.cgi?id=234813
+
+        Reviewed by Alexey Shvayka.
+
+        * stress/global-object-read-modify-write-remove-at-get-strict.js: Added.
+        (shouldThrow):
+        * stress/global-object-read-modify-write-remove-at-get.js: Added.
+        (shouldBe):
+        * test262/expectations.yaml:
+
+2022-01-03  Yusuke Suzuki  <[email protected]>
+
         [JSC] Fix length of Intl.NumberFormat.formatRange and Intl.PluralRules.selectRange
         https://bugs.webkit.org/show_bug.cgi?id=234806
 

Added: trunk/JSTests/stress/global-object-read-modify-write-remove-at-get-strict.js (0 => 287544)


--- trunk/JSTests/stress/global-object-read-modify-write-remove-at-get-strict.js	                        (rev 0)
+++ trunk/JSTests/stress/global-object-read-modify-write-remove-at-get-strict.js	2022-01-03 16:50:30 UTC (rev 287544)
@@ -0,0 +1,29 @@
+function shouldThrow(func, errorMessage) {
+    var errorThrown = false;
+    var error = null;
+    try {
+        func();
+    } catch (e) {
+        errorThrown = true;
+        error = e;
+    }
+    if (!errorThrown)
+        throw new Error('not thrown');
+    if (String(error) !== errorMessage)
+        throw new Error(`bad error: ${String(error)}`);
+}
+
+shouldThrow(() => {
+    runString(`
+    'use strict';
+    Object.defineProperty(globalThis, 'x', {
+        get() {
+            delete globalThis.x;
+            return 2;
+        },
+        configurable: true,
+    });
+
+    x += 42;
+    `);
+}, `ReferenceError: Can't find variable: x`);

Added: trunk/JSTests/stress/global-object-read-modify-write-remove-at-get.js (0 => 287544)


--- trunk/JSTests/stress/global-object-read-modify-write-remove-at-get.js	                        (rev 0)
+++ trunk/JSTests/stress/global-object-read-modify-write-remove-at-get.js	2022-01-03 16:50:30 UTC (rev 287544)
@@ -0,0 +1,15 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+Object.defineProperty(globalThis, 'x', {
+    get() {
+        delete globalThis.x;
+        return 2;
+    },
+    configurable: true,
+});
+
+x += 42;
+shouldBe(x, 44);

Modified: trunk/JSTests/test262/expectations.yaml (287543 => 287544)


--- trunk/JSTests/test262/expectations.yaml	2022-01-03 16:31:18 UTC (rev 287543)
+++ trunk/JSTests/test262/expectations.yaml	2022-01-03 16:50:30 UTC (rev 287544)
@@ -2095,72 +2095,6 @@
 test/language/expressions/class/elements/nested-private-direct-eval-err-contains-arguments.js:
   default: 'Test262Error: Expected a SyntaxError but got a ReferenceError'
   strict mode: 'Test262Error: Expected a SyntaxError but got a ReferenceError'
-test/language/expressions/compound-assignment/S11.13.2_A5.10_T1.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.10_T2.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.10_T3.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.11_T1.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.11_T2.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.11_T3.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.1_T1.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.1_T2.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.1_T3.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.2_T1.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.2_T2.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.2_T3.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.3_T1.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.3_T2.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.3_T3.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.4_T1.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.4_T2.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.4_T3.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.5_T1.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.5_T2.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.5_T3.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.6_T1.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.6_T2.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.6_T3.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.7_T1.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.7_T2.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.7_T3.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.8_T1.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.8_T2.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.8_T3.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.9_T1.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.9_T2.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/compound-assignment/S11.13.2_A5.9_T3.js:
-  default: "ReferenceError: Can't find variable: x"
 test/language/expressions/compound-assignment/S11.13.2_A7.10_T4.js:
   default: 'Test262Error: Expected true but got false'
   strict mode: 'Test262Error: Expected true but got false'
@@ -2246,39 +2180,15 @@
   default: 'Test262Error: Expected SameValue(«outside», «inside») to be true'
 test/language/expressions/object/scope-setter-body-lex-distinc.js:
   default: 'Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all'
-test/language/expressions/postfix-decrement/S11.3.2_A5_T1.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/postfix-decrement/S11.3.2_A5_T2.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/postfix-decrement/S11.3.2_A5_T3.js:
-  default: "ReferenceError: Can't find variable: x"
 test/language/expressions/postfix-decrement/S11.3.2_A6_T3.js:
   default: 'Test262Error: Expected true but got false'
   strict mode: 'Test262Error: Expected true but got false'
-test/language/expressions/postfix-increment/S11.3.1_A5_T1.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/postfix-increment/S11.3.1_A5_T2.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/postfix-increment/S11.3.1_A5_T3.js:
-  default: "ReferenceError: Can't find variable: x"
 test/language/expressions/postfix-increment/S11.3.1_A6_T3.js:
   default: 'Test262Error: Expected true but got false'
   strict mode: 'Test262Error: Expected true but got false'
-test/language/expressions/prefix-decrement/S11.4.5_A5_T1.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/prefix-decrement/S11.4.5_A5_T2.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/prefix-decrement/S11.4.5_A5_T3.js:
-  default: "ReferenceError: Can't find variable: x"
 test/language/expressions/prefix-decrement/S11.4.5_A6_T3.js:
   default: 'Test262Error: Expected true but got false'
   strict mode: 'Test262Error: Expected true but got false'
-test/language/expressions/prefix-increment/S11.4.4_A5_T1.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/prefix-increment/S11.4.4_A5_T2.js:
-  default: "ReferenceError: Can't find variable: x"
-test/language/expressions/prefix-increment/S11.4.4_A5_T3.js:
-  default: "ReferenceError: Can't find variable: x"
 test/language/expressions/prefix-increment/S11.4.4_A6_T3.js:
   default: 'Test262Error: Expected true but got false'
   strict mode: 'Test262Error: Expected true but got false'

Modified: trunk/Source/_javascript_Core/ChangeLog (287543 => 287544)


--- trunk/Source/_javascript_Core/ChangeLog	2022-01-03 16:31:18 UTC (rev 287543)
+++ trunk/Source/_javascript_Core/ChangeLog	2022-01-03 16:50:30 UTC (rev 287544)
@@ -1,5 +1,21 @@
 2022-01-03  Yusuke Suzuki  <[email protected]>
 
+        [JSC] Read-modify-write operation's second put-to-scope should not throw error if binding does not exist
+        https://bugs.webkit.org/show_bug.cgi?id=234813
+
+        Reviewed by Alexey Shvayka.
+
+        This patch fixes a bug throwing RefereceError when read-modify-write's read operation removes binding from object.
+        Throwing error should happen only when evaluating it under strict mode.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::PostfixNode::emitResolve):
+        (JSC::PrefixNode::emitResolve):
+        (JSC::ReadModifyResolveNode::emitBytecode):
+        (JSC::ShortCircuitReadModifyResolveNode::emitBytecode):
+
+2022-01-03  Yusuke Suzuki  <[email protected]>
+
         [JSC] Fix length of Intl.NumberFormat.formatRange and Intl.PluralRules.selectRange
         https://bugs.webkit.org/show_bug.cgi?id=234806
 

Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (287543 => 287544)


--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2022-01-03 16:31:18 UTC (rev 287543)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2022-01-03 16:50:30 UTC (rev 287544)
@@ -2366,7 +2366,7 @@
     }
     RefPtr<RegisterID> oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
     if (!var.isReadOnly()) {
-        generator.emitPutToScope(scope.get(), var, value.get(), ThrowIfNotFound, InitializationMode::NotInitialization);
+        generator.emitPutToScope(scope.get(), var, value.get(), generator.ecmaMode().isStrict() ? ThrowIfNotFound : DoNotThrowIfNotFound, InitializationMode::NotInitialization);
         generator.emitProfileType(value.get(), var, divotStart(), divotEnd());
     }
 
@@ -2663,7 +2663,7 @@
 
     emitIncOrDec(generator, value.get(), m_operator);
     if (!var.isReadOnly()) {
-        generator.emitPutToScope(scope.get(), var, value.get(), ThrowIfNotFound, InitializationMode::NotInitialization);
+        generator.emitPutToScope(scope.get(), var, value.get(), generator.ecmaMode().isStrict() ? ThrowIfNotFound : DoNotThrowIfNotFound, InitializationMode::NotInitialization);
         generator.emitProfileType(value.get(), var, divotStart(), divotEnd());
     }
     return generator.move(dst, value.get());
@@ -3450,7 +3450,7 @@
     RefPtr<RegisterID> result = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()), this, var.isReadOnly() ? &var : nullptr);
     RegisterID* returnResult = result.get();
     if (!var.isReadOnly()) {
-        returnResult = generator.emitPutToScope(scope.get(), var, result.get(), ThrowIfNotFound, InitializationMode::NotInitialization);
+        returnResult = generator.emitPutToScope(scope.get(), var, result.get(), generator.ecmaMode().isStrict() ? ThrowIfNotFound : DoNotThrowIfNotFound, InitializationMode::NotInitialization);
         generator.emitProfileType(result.get(), var, divotStart(), divotEnd());
     }
     return returnResult;
@@ -3551,7 +3551,7 @@
         generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
 
     if (!isReadOnly) {
-        generator.emitPutToScope(scope.get(), var, uncheckedResult.get(), ThrowIfNotFound, InitializationMode::NotInitialization);
+        generator.emitPutToScope(scope.get(), var, uncheckedResult.get(), generator.ecmaMode().isStrict() ? ThrowIfNotFound : DoNotThrowIfNotFound, InitializationMode::NotInitialization);
         generator.emitProfileType(uncheckedResult.get(), var, divotStart(), divotEnd());
     }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to