Diff
Modified: trunk/JSTests/ChangeLog (247193 => 247194)
--- trunk/JSTests/ChangeLog 2019-07-06 11:03:56 UTC (rev 247193)
+++ trunk/JSTests/ChangeLog 2019-07-06 13:34:51 UTC (rev 247194)
@@ -1,3 +1,17 @@
+2019-07-06 Michael Saboff <msab...@apple.com>
+
+ switch(String) needs to check for exceptions when resolving the string
+ https://bugs.webkit.org/show_bug.cgi?id=199541
+
+ Reviewed by Mark Lam.
+
+ New tests.
+
+ * stress/switch-string-oom.js: Added.
+ (test):
+ (testLowerTiers):
+ (testFTL):
+
2019-07-05 Mark Lam <mark....@apple.com>
ArgumentsEliminationPhase::eliminateCandidatesThatInterfere() should not decrement nodeIndex pass zero.
Added: trunk/JSTests/stress/switch-string-oom.js (0 => 247194)
--- trunk/JSTests/stress/switch-string-oom.js (rev 0)
+++ trunk/JSTests/stress/switch-string-oom.js 2019-07-06 13:34:51 UTC (rev 247194)
@@ -0,0 +1,52 @@
+//@ requireOptions("--jitPolicyScale=0", "--useConcurrentJIT=0")
+// This tests that when a switch(String) converts the String argument, it properly handles OOM
+
+function test(createOOMString)
+{
+ var str = String.fromCharCode(365);
+ if (createOOMString)
+ str = str.padEnd(2147483644, '123');
+
+ switch (str) {
+ case "one":
+ throw "Case \"one\", dhouldn't get here";
+ break;
+ case "two":
+ throw "Case \"two\", shouldn't get here";
+ break;
+ case "three":
+ throw "Case \"three\", shouldn't get here";
+ break;
+ default:
+ if (createOOMString)
+ throw "Default case, shouldn't get here";
+ break;
+ }
+}
+
+function testLowerTiers()
+{
+ for (let i = 0; i < 200; i++) {
+ try {
+ test(true);
+ } catch(e) {
+ if (e != "Error: Out of memory")
+ throw "Unexpecte error: \"" + e + "\"";
+ }
+ }
+}
+
+function testFTL()
+{
+ for (let i = 0; i < 1000; i++) {
+ try {
+ test(i >= 50);
+ } catch(e) {
+ if (e != "Error: Out of memory")
+ throw "Unexpecte error: \"" + e + "\"";
+ }
+ }
+}
+
+testLowerTiers();
+testFTL();
Modified: trunk/Source/_javascript_Core/ChangeLog (247193 => 247194)
--- trunk/Source/_javascript_Core/ChangeLog 2019-07-06 11:03:56 UTC (rev 247193)
+++ trunk/Source/_javascript_Core/ChangeLog 2019-07-06 13:34:51 UTC (rev 247194)
@@ -1,3 +1,17 @@
+2019-07-06 Michael Saboff <msab...@apple.com>
+
+ switch(String) needs to check for exceptions when resolving the string
+ https://bugs.webkit.org/show_bug.cgi?id=199541
+
+ Reviewed by Mark Lam.
+
+ Added exception checks for resolved Strings in switch processing for all tiers.
+
+ * dfg/DFGOperations.cpp:
+ * jit/JITOperations.cpp:
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+
2019-07-05 Mark Lam <mark....@apple.com>
ArgumentsEliminationPhase::eliminateCandidatesThatInterfere() should not decrement nodeIndex pass zero.
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (247193 => 247194)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2019-07-06 11:03:56 UTC (rev 247193)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2019-07-06 13:34:51 UTC (rev 247194)
@@ -2446,7 +2446,6 @@
{
VM& vm = exec->vm();
NativeCallFrameTracer tracer(&vm, exec);
-
CodeBlock* codeBlock = exec->codeBlock();
SimpleJumpTable& table = codeBlock->switchJumpTable(tableIndex);
JSValue value = JSValue::decode(encodedValue);
@@ -2462,8 +2461,13 @@
{
VM& vm = exec->vm();
NativeCallFrameTracer tracer(&vm, exec);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
- return exec->codeBlock()->stringSwitchJumpTable(tableIndex).ctiForValue(string->value(exec).impl()).executableAddress<char*>();
+ StringImpl* strImpl = string->value(exec).impl();
+
+ RETURN_IF_EXCEPTION(throwScope, nullptr);
+
+ return exec->codeBlock()->stringSwitchJumpTable(tableIndex).ctiForValue(strImpl).executableAddress<char*>();
}
int32_t JIT_OPERATION operationSwitchStringAndGetBranchOffset(ExecState* exec, size_t tableIndex, JSString* string)
@@ -2470,8 +2474,13 @@
{
VM& vm = exec->vm();
NativeCallFrameTracer tracer(&vm, exec);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
- return exec->codeBlock()->stringSwitchJumpTable(tableIndex).offsetForValue(string->value(exec).impl(), std::numeric_limits<int32_t>::min());
+ StringImpl* strImpl = string->value(exec).impl();
+
+ RETURN_IF_EXCEPTION(throwScope, 0);
+
+ return exec->codeBlock()->stringSwitchJumpTable(tableIndex).offsetForValue(strImpl, std::numeric_limits<int32_t>::min());
}
uintptr_t JIT_OPERATION operationCompareStringImplLess(StringImpl* a, StringImpl* b)
Modified: trunk/Source/_javascript_Core/jit/JITOperations.cpp (247193 => 247194)
--- trunk/Source/_javascript_Core/jit/JITOperations.cpp 2019-07-06 11:03:56 UTC (rev 247193)
+++ trunk/Source/_javascript_Core/jit/JITOperations.cpp 2019-07-06 13:34:51 UTC (rev 247194)
@@ -2312,6 +2312,7 @@
NativeCallFrameTracer tracer(&vm, exec);
JSValue key = JSValue::decode(encodedKey);
CodeBlock* codeBlock = exec->codeBlock();
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
void* result;
StringJumpTable& jumpTable = codeBlock->stringSwitchJumpTable(tableIndex);
@@ -2318,6 +2319,9 @@
if (key.isString()) {
StringImpl* value = asString(key)->value(exec).impl();
+
+ RETURN_IF_EXCEPTION(throwScope, nullptr);
+
result = jumpTable.ctiForValue(value).executableAddress();
} else
result = jumpTable.ctiDefault.executableAddress();
Modified: trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp (247193 => 247194)
--- trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2019-07-06 11:03:56 UTC (rev 247193)
+++ trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2019-07-06 13:34:51 UTC (rev 247194)
@@ -1317,8 +1317,13 @@
if (!scrutinee.isString())
JUMP_TO(defaultOffset);
else {
+ StringImpl* scrutineeStringImpl = asString(scrutinee)->value(exec).impl();
+
+ LLINT_CHECK_EXCEPTION();
+
CodeBlock* codeBlock = exec->codeBlock();
- JUMP_TO(codeBlock->stringSwitchJumpTable(bytecode.m_tableIndex).offsetForValue(asString(scrutinee)->value(exec).impl(), defaultOffset));
+
+ JUMP_TO(codeBlock->stringSwitchJumpTable(bytecode.m_tableIndex).offsetForValue(scrutineeStringImpl, defaultOffset));
}
LLINT_END();
}