switch(String) needs to check for exceptions when resolving the string
authormsaboff@apple.com <msaboff@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 6 Jul 2019 13:34:51 +0000 (13:34 +0000)
committermsaboff@apple.com <msaboff@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 6 Jul 2019 13:34:51 +0000 (13:34 +0000)
https://bugs.webkit.org/show_bug.cgi?id=199541

Reviewed by Mark Lam.

JSTests:

New tests.

* stress/switch-string-oom.js: Added.
(test):
(testLowerTiers):
(testFTL):

Source/JavaScriptCore:

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):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@247194 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JSTests/ChangeLog
JSTests/stress/switch-string-oom.js [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGOperations.cpp
Source/JavaScriptCore/jit/JITOperations.cpp
Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

index 7e423d2..decc266 100644 (file)
@@ -1,3 +1,17 @@
+2019-07-06  Michael Saboff  <msaboff@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.lam@apple.com>
 
         ArgumentsEliminationPhase::eliminateCandidatesThatInterfere() should not decrement nodeIndex pass zero.
diff --git a/JSTests/stress/switch-string-oom.js b/JSTests/stress/switch-string-oom.js
new file mode 100644 (file)
index 0000000..a581222
--- /dev/null
@@ -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();
index 5b381c3..cebfd62 100644 (file)
@@ -1,3 +1,17 @@
+2019-07-06  Michael Saboff  <msaboff@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.lam@apple.com>
 
         ArgumentsEliminationPhase::eliminateCandidatesThatInterfere() should not decrement nodeIndex pass zero.
index c425ea9..717c7a1 100644 (file)
@@ -2446,7 +2446,6 @@ char* JIT_OPERATION operationFindSwitchImmTargetForDouble(
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
-
     CodeBlock* codeBlock = exec->codeBlock();
     SimpleJumpTable& table = codeBlock->switchJumpTable(tableIndex);
     JSValue value = JSValue::decode(encodedValue);
@@ -2462,16 +2461,26 @@ char* JIT_OPERATION operationSwitchString(ExecState* exec, size_t tableIndex, JS
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
+    auto throwScope = DECLARE_THROW_SCOPE(vm);
+
+    StringImpl* strImpl = string->value(exec).impl();
+
+    RETURN_IF_EXCEPTION(throwScope, nullptr);
 
-    return exec->codeBlock()->stringSwitchJumpTable(tableIndex).ctiForValue(string->value(exec).impl()).executableAddress<char*>();
+    return exec->codeBlock()->stringSwitchJumpTable(tableIndex).ctiForValue(strImpl).executableAddress<char*>();
 }
 
 int32_t JIT_OPERATION operationSwitchStringAndGetBranchOffset(ExecState* exec, size_t tableIndex, JSString* string)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
+    auto throwScope = DECLARE_THROW_SCOPE(vm);
+
+    StringImpl* strImpl = string->value(exec).impl();
+
+    RETURN_IF_EXCEPTION(throwScope, 0);
 
-    return exec->codeBlock()->stringSwitchJumpTable(tableIndex).offsetForValue(string->value(exec).impl(), std::numeric_limits<int32_t>::min());
+    return exec->codeBlock()->stringSwitchJumpTable(tableIndex).offsetForValue(strImpl, std::numeric_limits<int32_t>::min());
 }
 
 uintptr_t JIT_OPERATION operationCompareStringImplLess(StringImpl* a, StringImpl* b)
index 7ba1823..da20c85 100644 (file)
@@ -2312,12 +2312,16 @@ char* JIT_OPERATION operationSwitchStringWithUnknownKeyType(ExecState* exec, Enc
     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);
 
     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();
index 1712378..fcfa4d3 100644 (file)
@@ -1317,8 +1317,13 @@ LLINT_SLOW_PATH_DECL(slow_path_switch_string)
     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();
 }