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;