Title: [264059] trunk
Revision
264059
Author
[email protected]
Date
2020-07-07 21:36:49 -0700 (Tue, 07 Jul 2020)

Log Message

[JSC] BytecodeGenerator should be robust against failed constant generation
https://bugs.webkit.org/show_bug.cgi?id=214062
<rdar://problem/65117916>

Reviewed by Saam Barati.

JSTests:

* stress/bigint-oom-in-codegen-array-literal-context.js: Added.
(shouldThrow):
(test):
* stress/bigint-oom-in-codegen-binary-conditional-context.js: Added.
(shouldThrow):
(test):
* stress/bigint-oom-in-codegen-conditional-context.js: Added.
(shouldThrow):
(test):

Source/_javascript_Core:

Some code in NodesCodegen.cpp assumes `jsValue(generator)` call for constant nodes must succeed.
But this can fail when BigInt in source code is too large and becomes OOM. BytecodeGenerator should
be robust against BigInt OOM.

* bytecompiler/NodesCodegen.cpp:
(JSC::ConstantNode::emitBytecodeInConditionContext):
(JSC::ArrayNode::emitBytecode):
(JSC::BinaryOpNode::tryFoldToBranch):

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (264058 => 264059)


--- trunk/JSTests/ChangeLog	2020-07-08 03:21:59 UTC (rev 264058)
+++ trunk/JSTests/ChangeLog	2020-07-08 04:36:49 UTC (rev 264059)
@@ -1,5 +1,23 @@
 2020-07-07  Yusuke Suzuki  <[email protected]>
 
+        [JSC] BytecodeGenerator should be robust against failed constant generation
+        https://bugs.webkit.org/show_bug.cgi?id=214062
+        <rdar://problem/65117916>
+
+        Reviewed by Saam Barati.
+
+        * stress/bigint-oom-in-codegen-array-literal-context.js: Added.
+        (shouldThrow):
+        (test):
+        * stress/bigint-oom-in-codegen-binary-conditional-context.js: Added.
+        (shouldThrow):
+        (test):
+        * stress/bigint-oom-in-codegen-conditional-context.js: Added.
+        (shouldThrow):
+        (test):
+
+2020-07-07  Yusuke Suzuki  <[email protected]>
+
         [JSC] Should not pass Exception to JSPromise::reject
         https://bugs.webkit.org/show_bug.cgi?id=214061
         <rdar://problem/65134450>

Added: trunk/JSTests/stress/bigint-oom-in-codegen-array-literal-context.js (0 => 264059)


--- trunk/JSTests/stress/bigint-oom-in-codegen-array-literal-context.js	                        (rev 0)
+++ trunk/JSTests/stress/bigint-oom-in-codegen-array-literal-context.js	2020-07-08 04:36:49 UTC (rev 264059)
@@ -0,0 +1,26 @@
+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)}`);
+}
+
+const largeNumber = 0xffffff;
+let generated = null;
+function test()
+{
+    generated = new Function(`target`, `return [0x${'f'.repeat(largeNumber)}n]`);
+}
+
+test();
+shouldThrow(() => {
+    generated();
+}, `RangeError: Out of memory`);

Added: trunk/JSTests/stress/bigint-oom-in-codegen-binary-conditional-context.js (0 => 264059)


--- trunk/JSTests/stress/bigint-oom-in-codegen-binary-conditional-context.js	                        (rev 0)
+++ trunk/JSTests/stress/bigint-oom-in-codegen-binary-conditional-context.js	2020-07-08 04:36:49 UTC (rev 264059)
@@ -0,0 +1,26 @@
+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)}`);
+}
+
+const largeNumber = 0xffffff;
+let generated = null;
+function test()
+{
+    generated = new Function(`target`, `if (0x${'f'.repeat(largeNumber)}n < 0) return true;`);
+}
+
+test();
+shouldThrow(() => {
+    generated();
+}, `RangeError: Out of memory`);

Added: trunk/JSTests/stress/bigint-oom-in-codegen-conditional-context.js (0 => 264059)


--- trunk/JSTests/stress/bigint-oom-in-codegen-conditional-context.js	                        (rev 0)
+++ trunk/JSTests/stress/bigint-oom-in-codegen-conditional-context.js	2020-07-08 04:36:49 UTC (rev 264059)
@@ -0,0 +1,26 @@
+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)}`);
+}
+
+const largeNumber = 0xffffff;
+let generated = null;
+function test()
+{
+    generated = new Function(`target`, `if (0x${'f'.repeat(largeNumber)}n) return true;`);
+}
+
+test();
+shouldThrow(() => {
+    generated();
+}, `RangeError: Out of memory`);

Modified: trunk/Source/_javascript_Core/ChangeLog (264058 => 264059)


--- trunk/Source/_javascript_Core/ChangeLog	2020-07-08 03:21:59 UTC (rev 264058)
+++ trunk/Source/_javascript_Core/ChangeLog	2020-07-08 04:36:49 UTC (rev 264059)
@@ -1,5 +1,22 @@
 2020-07-07  Yusuke Suzuki  <[email protected]>
 
+        [JSC] BytecodeGenerator should be robust against failed constant generation
+        https://bugs.webkit.org/show_bug.cgi?id=214062
+        <rdar://problem/65117916>
+
+        Reviewed by Saam Barati.
+
+        Some code in NodesCodegen.cpp assumes `jsValue(generator)` call for constant nodes must succeed.
+        But this can fail when BigInt in source code is too large and becomes OOM. BytecodeGenerator should
+        be robust against BigInt OOM.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ConstantNode::emitBytecodeInConditionContext):
+        (JSC::ArrayNode::emitBytecode):
+        (JSC::BinaryOpNode::tryFoldToBranch):
+
+2020-07-07  Yusuke Suzuki  <[email protected]>
+
         [JSC] Should not pass Exception to JSPromise::reject
         https://bugs.webkit.org/show_bug.cgi?id=214061
         <rdar://problem/65134450>

Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (264058 => 264059)


--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2020-07-08 03:21:59 UTC (rev 264058)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2020-07-08 04:36:49 UTC (rev 264059)
@@ -98,7 +98,10 @@
 
 void ConstantNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label& trueTarget, Label& falseTarget, FallThroughMode fallThroughMode)
 {
-    TriState value = jsValue(generator).pureToBoolean();
+    TriState value = TriState::Indeterminate;
+    JSValue constant = jsValue(generator);
+    if (LIKELY(constant))
+        value = constant.pureToBoolean();
 
     if (UNLIKELY(needsDebugHook())) {
         if (value != TriState::Indeterminate)
@@ -410,8 +413,13 @@
             break;
         if (!firstPutElement->value()->isConstant())
             hadVariableExpression = true;
-        else
-            recommendedIndexingType = leastUpperBoundOfIndexingTypeAndValue(recommendedIndexingType, static_cast<ConstantNode*>(firstPutElement->value())->jsValue(generator));
+        else {
+            JSValue constant = static_cast<ConstantNode*>(firstPutElement->value())->jsValue(generator);
+            if (UNLIKELY(!constant))
+                hadVariableExpression = true;
+            else
+                recommendedIndexingType = leastUpperBoundOfIndexingTypeAndValue(recommendedIndexingType, constant);
+        }
 
         ++length;
     }
@@ -424,7 +432,9 @@
             unsigned index = 0;
             for (ElementNode* element = elements; index < length; element = element->next()) {
                 ASSERT(element->value()->isConstant());
-                array->setIndex(generator.vm(), index++, static_cast<ConstantNode*>(element->value())->jsValue(generator));
+                JSValue constant = static_cast<ConstantNode*>(element->value())->jsValue(generator);
+                ASSERT(constant);
+                array->setIndex(generator.vm(), index++, constant);
             }
             return generator.emitNewArrayBuffer(dst, array, recommendedIndexingType);
         }
@@ -2703,6 +2713,8 @@
 
     OpcodeID opcodeID = this->opcodeID();
     JSValue value = constant->jsValue(generator);
+    if (UNLIKELY(!value))
+        return;
     bool canFoldToBranch = JSC::canFoldToBranch(opcodeID, branchExpression, value);
     if (!canFoldToBranch)
         return;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to