Title: [259092] trunk
Revision
259092
Author
msab...@apple.com
Date
2020-03-26 16:27:57 -0700 (Thu, 26 Mar 2020)

Log Message

Refactor YARR Stack Overflow Checks
https://bugs.webkit.org/show_bug.cgi?id=209435
rdar://problem/58988252

Reviewed by Mark Lam.

JSTests:

Added a new test and removed a now obsolete test.

* stress/regexp-compile-oom.js: Removed because the test is no longer valid.
Previously when therer where different stack check mechanisims we failed different.
This test was based on the different failure modes.  With these changes, most of
the contain subtests no longer throw as this test expects.
* stress/regexp-huge-oom.js: Added.
(shouldBe):
(shouldThrow):

Source/_javascript_Core:

Refactored stack checks in YARR code including adding a stack check to the YARR JIT'ed code.
The C++ code including the parser, byte code compiler and interpreter now all use StackCheck.
The JIT'ed code needs a stack limit passed via a parameter since the JIT'ed code can be 
called from the compiler thread when compiling DFG / FTL code.

Instead of adding a new parameter, consolidated the two pattern context buffer values, buffer
pointer and size, with the new stack limit into a new MatchingContextHolder, an RAII object.
The MatchingContextHolder constructor uses either the VM stack limit or the current thread's
stack limit depending on how it is called.

* runtime/RegExp.cpp:
(JSC::RegExp::finishCreation):
(JSC::RegExp::byteCodeCompileIfNecessary):
(JSC::RegExp::compile):
(JSC::RegExp::matchConcurrently):
(JSC::RegExp::compileMatchOnly):
* runtime/RegExp.h:
* runtime/RegExpInlines.h:
(JSC::RegExp::matchInline):
(JSC::PatternContextBufferHolder::PatternContextBufferHolder): Deleted.
(JSC::PatternContextBufferHolder::~PatternContextBufferHolder): Deleted.
(JSC::PatternContextBufferHolder::buffer): Deleted.
(JSC::PatternContextBufferHolder::size): Deleted.
(): Deleted.
* yarr/Yarr.h:
* yarr/YarrInterpreter.cpp:
(JSC::Yarr::Interpreter::matchDisjunction):
(JSC::Yarr::Interpreter::isSafeToRecurse):
* yarr/YarrJIT.cpp:
(JSC::Yarr::MatchingContextHolder::MatchingContextHolder):
(JSC::Yarr::MatchingContextHolder::~MatchingContextHolder):
(JSC::Yarr::YarrGenerator::initParenContextFreeList):
(JSC::Yarr::YarrGenerator::alignCallFrameSizeInBytes):
(JSC::Yarr::YarrGenerator::compile):
(JSC::Yarr::YarrGenerator::initCallFrame): Deleted.
* yarr/YarrJIT.h:
(JSC::Yarr::MatchingContextHolder::offsetOfStackLimit):
(JSC::Yarr::MatchingContextHolder::offsetOfPatternContextBuffer):
(JSC::Yarr::MatchingContextHolder::offsetOfPatternContextBufferSize):
(JSC::Yarr::YarrCodeBlock::execute):
* yarr/YarrPattern.cpp:
(JSC::Yarr::YarrPatternConstructor::YarrPatternConstructor):
(JSC::Yarr::YarrPatternConstructor::isSafeToRecurse):
(JSC::Yarr::YarrPattern::compile):
(JSC::Yarr::YarrPattern::YarrPattern):
(JSC::Yarr::YarrPatternConstructor::isSafeToRecurse const): Deleted.
* yarr/YarrPattern.h:

LayoutTests:

	Updated test for improved stack overflow checking.

* js/script-tests/stack-overflow-regexp.js:
(shouldThrow.recursiveCall):
(shouldThrow):
(recursiveCall):
* js/stack-overflow-regexp-expected.txt:

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/JSTests/ChangeLog (259091 => 259092)


--- trunk/JSTests/ChangeLog	2020-03-26 23:10:36 UTC (rev 259091)
+++ trunk/JSTests/ChangeLog	2020-03-26 23:27:57 UTC (rev 259092)
@@ -1,3 +1,21 @@
+2020-03-26  Michael Saboff  <msab...@apple.com>
+
+        Refactor YARR Stack Overflow Checks
+        https://bugs.webkit.org/show_bug.cgi?id=209435
+        rdar://problem/58988252
+
+        Reviewed by Mark Lam.
+
+        Added a new test and removed a now obsolete test.
+
+        * stress/regexp-compile-oom.js: Removed because the test is no longer valid.
+        Previously when therer where different stack check mechanisims we failed different.
+        This test was based on the different failure modes.  With these changes, most of
+        the contain subtests no longer throw as this test expects.
+        * stress/regexp-huge-oom.js: Added.
+        (shouldBe):
+        (shouldThrow):
+
 2020-03-26  Keith Miller  <keith_mil...@apple.com>
 
         TypedArrays should more gracefully handle OOM during slowDownAndWasteMemory

Deleted: trunk/JSTests/stress/regexp-compile-oom.js (259091 => 259092)


--- trunk/JSTests/stress/regexp-compile-oom.js	2020-03-26 23:10:36 UTC (rev 259091)
+++ trunk/JSTests/stress/regexp-compile-oom.js	2020-03-26 23:27:57 UTC (rev 259092)
@@ -1,99 +0,0 @@
-//@ skip if $hostOS != "darwin" or $architecture == "arm" or $architecture == "x86" or not $jitTests
-// Test that throw an OOM exception when compiling a pathological, but valid nested RegExp.
-
-var failures = [];
-
-class TestAndExpectedException
-{
-    constructor(func, exception)
-    {
-        this.func = func;
-        this.exception = exception;
-    }
-
-    runTest()
-    {
-        try {
-            this.func();
-            failures.push("Running " + this.func + ", expected OOM exception, but didn't get one");
-        } catch (e) {
-            let errStr = e.toString();
-            if (errStr != this.exception)
-                failures.push("Running " + this.func + ", expected: \"" + this.exception + "\" but got \"" + errStr + "\"");
-        }       
-    }
-}
-
-function recurseAndTest(depth, testList)
-{
-    // Probe stack depth
-    try {
-        let result = recurseAndTest(depth + 1, testList);
-        if (result == 0) {
-            // Call the test functions with a nearly full stack.
-            for (const test of testList)
-                test.runTest();
-
-            return 1;
-        } else if (result < 0)
-            return result + 1;
-        else
-            return result;
-    } catch (e) {
-        // Go up a several frames and then call the test functions
-        return -24;
-    }
-
-    return 1;
-}
-
-let deepRE = new RegExp("((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((x))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))");
-let deepGlobalRE = new RegExp(deepRE, "g");
-
-let matchLen = 401; // The number of parens plus 1 for the whole match.
-
-let regExpOOMError = "Error: Out of memory: Invalid regular _expression_: too many nested disjunctions";
-
-testList = [];
-
-// Test that all RegExp related APIs that compile RE's properly handle OOM.
-testList.push(new TestAndExpectedException(() => { deepRE.exec("x"); }, regExpOOMError));
-testList.push(new TestAndExpectedException(() => { deepRE.test("x"); }, regExpOOMError));
-testList.push(new TestAndExpectedException(() => { "x".match(deepRE); }, regExpOOMError));
-testList.push(new TestAndExpectedException(() => { "x".match(deepGlobalRE); }, regExpOOMError));
-testList.push(new TestAndExpectedException(() => { "x".replace(deepGlobalRE, ""); }, regExpOOMError));
-testList.push(new TestAndExpectedException(() => { "x".replace(deepGlobalRE, "X"); }, regExpOOMError));
-testList.push(new TestAndExpectedException(() => { "x".replace(deepGlobalRE, () => { return "X" }); }, regExpOOMError));
-testList.push(new TestAndExpectedException(() => { "x".search(deepRE); }, regExpOOMError));
-
-recurseAndTest(1, testList);
-
-if (failures.length) {
-    print("Got the following failures:");
-    for (const failure of failures)
-        print(failure);
-    throw "Got failures";
-}
-
-// Test that the RegExp works correctly with RegExp.exec() and RegExp.test() when there is sufficient stack space to compile it.
-let m = deepRE.exec("x");
-let matched = true;
-if (m.length != matchLen)
-    matched = false
-else {
-    for (i = 0; i < matchLen; i++) {
-        if (m[i] != "x")
-            matched = false;
-    }
-}
-
-if (!matched) {
-    let expectedMatch = [];
-    for (i = 0; i < matchLen; i++)
-        expectedMatch[i] = "x";
-
-    throw "Expected RegExp.exec(...) to be [" + expectedMatch + "] but got [" + m + "]";
-}
-
-if (!deepRE.test("x"))
-    throw "Expected RegExp.test(...) to be true, but was false";

Added: trunk/JSTests/stress/regexp-huge-oom.js (0 => 259092)


--- trunk/JSTests/stress/regexp-huge-oom.js	                        (rev 0)
+++ trunk/JSTests/stress/regexp-huge-oom.js	2020-03-26 23:27:57 UTC (rev 259092)
@@ -0,0 +1,33 @@
+//@ skip if $memoryLimited
+// Test that throw an OOM exception when compiling / executing a pathologically large RegExp's
+
+function shouldBe(actual, expected)
+{
+    if (actual !== expected)
+        throw new Error("Bad value: , expected \"" + expected + "\", but got \"" + actual + "\"");
+}
+
+function shouldThrow(run, errorType)
+{
+    let actual;
+    var hadError = false;
+
+    try {
+        actual = run();
+    } catch (e) {
+        hadError = true;
+        actual = e;
+    }
+
+    if (!hadError)
+        throw new Error("Expected " + run + "() to throw " + errorType.name + ", but did not throw.");
+    if (!(actual instanceof errorType))
+        throw new Error("Expeced " + run + "() to throw " + errorType.name + " , but threw '" + actual + "'");
+}
+
+// This should throw during pattern compilation.
+shouldThrow(() => RegExp('a?'.repeat(2**19) + 'b').exec('x'), SyntaxError);
+
+// This test should fail execution in the JIT'ed code and then fall back to the interpreter ans succeed.
+shouldBe(RegExp('a?'.repeat(2**19)).exec('x')[0], "");
+

Modified: trunk/LayoutTests/ChangeLog (259091 => 259092)


--- trunk/LayoutTests/ChangeLog	2020-03-26 23:10:36 UTC (rev 259091)
+++ trunk/LayoutTests/ChangeLog	2020-03-26 23:27:57 UTC (rev 259092)
@@ -1,3 +1,19 @@
+2020-03-26  Michael Saboff  <msab...@apple.com>
+
+        Refactor YARR Stack Overflow Checks
+        https://bugs.webkit.org/show_bug.cgi?id=209435
+        rdar://problem/58988252
+
+        Reviewed by Mark Lam.
+
+	Updated test for improved stack overflow checking.
+
+        * js/script-tests/stack-overflow-regexp.js:
+        (shouldThrow.recursiveCall):
+        (shouldThrow):
+        (recursiveCall):
+        * js/stack-overflow-regexp-expected.txt:
+
 2020-03-26  Jason Lawrence  <lawrenc...@apple.com>
 
         [ Mac wk2 Release ] tiled-drawing/scrolling/fixed/four-bars-zoomed.html is flaky failing.

Modified: trunk/LayoutTests/js/script-tests/stack-overflow-regexp.js (259091 => 259092)


--- trunk/LayoutTests/js/script-tests/stack-overflow-regexp.js	2020-03-26 23:10:36 UTC (rev 259091)
+++ trunk/LayoutTests/js/script-tests/stack-overflow-regexp.js	2020-03-26 23:27:57 UTC (rev 259092)
@@ -1,15 +1,16 @@
 // https://bugs.webkit.org/show_bug.cgi?id=190755
 //@ skip if $architecture == "arm" and $hostOS == "linux"
+//  &&&&
 description('Test that we do not overflow the stack while handling regular expressions');
 
 // Base case.
-shouldThrow('new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")"))', '"Error: Out of memory: Invalid regular _expression_: too many nested disjunctions"');
+shouldThrow('new RegExp(Array(500000).join("(") + "a" + Array(500000).join(")"))', '"Error: Out of memory: Invalid regular _expression_: too many nested disjunctions"');
 
 { // Verify that a deep JS stack does not help avoiding the error.
     function recursiveCall(depth) {
         if (!(depth % 10)) {
             debug("Creating RegExp at depth " + depth);
-            shouldThrow('new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")"))', '"Error: Out of memory: Invalid regular _expression_: too many nested disjunctions"');
+            shouldThrow('new RegExp(Array(500000).join("(") + "a" + Array(500000).join(")"))', '"Error: Out of memory: Invalid regular _expression_: too many nested disjunctions"');
         }
         if (depth < 100) {
             recursiveCall(depth + 1);
@@ -20,12 +21,12 @@
 
 { // Have the deepest nested subpattern surrounded by other expressions.
     var _expression_ = "";
-    for (let i = 0; i < 50000; ++i) {
+    for (let i = 0; i < 500000; ++i) {
         _expression_ += "((a)(";
     }
     _expression_ += "b";
-    for (let i = 0; i < 50000; ++i) {
+    for (let i = 0; i < 500000; ++i) {
         _expression_ += ")(c))";
     }
-    shouldThrow('new RegExp(_expression_)', '"Error: Out of memory: Invalid regular _expression_: too many nested disjunctions"');
+    shouldThrow('new RegExp(_expression_)', '"SyntaxError: Invalid regular _expression_: regular _expression_ too large"');
 }

Modified: trunk/LayoutTests/js/stack-overflow-regexp-expected.txt (259091 => 259092)


--- trunk/LayoutTests/js/stack-overflow-regexp-expected.txt	2020-03-26 23:10:36 UTC (rev 259091)
+++ trunk/LayoutTests/js/stack-overflow-regexp-expected.txt	2020-03-26 23:27:57 UTC (rev 259092)
@@ -3,30 +3,30 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception Error: Out of memory: Invalid regular _expression_: too many nested disjunctions.
+PASS new RegExp(Array(500000).join("(") + "a" + Array(500000).join(")")) threw exception Error: Out of memory: Invalid regular _expression_: too many nested disjunctions.
 Creating RegExp at depth 0
-PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception Error: Out of memory: Invalid regular _expression_: too many nested disjunctions.
+PASS new RegExp(Array(500000).join("(") + "a" + Array(500000).join(")")) threw exception Error: Out of memory: Invalid regular _expression_: too many nested disjunctions.
 Creating RegExp at depth 10
-PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception Error: Out of memory: Invalid regular _expression_: too many nested disjunctions.
+PASS new RegExp(Array(500000).join("(") + "a" + Array(500000).join(")")) threw exception Error: Out of memory: Invalid regular _expression_: too many nested disjunctions.
 Creating RegExp at depth 20
-PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception Error: Out of memory: Invalid regular _expression_: too many nested disjunctions.
+PASS new RegExp(Array(500000).join("(") + "a" + Array(500000).join(")")) threw exception Error: Out of memory: Invalid regular _expression_: too many nested disjunctions.
 Creating RegExp at depth 30
-PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception Error: Out of memory: Invalid regular _expression_: too many nested disjunctions.
+PASS new RegExp(Array(500000).join("(") + "a" + Array(500000).join(")")) threw exception Error: Out of memory: Invalid regular _expression_: too many nested disjunctions.
 Creating RegExp at depth 40
-PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception Error: Out of memory: Invalid regular _expression_: too many nested disjunctions.
+PASS new RegExp(Array(500000).join("(") + "a" + Array(500000).join(")")) threw exception Error: Out of memory: Invalid regular _expression_: too many nested disjunctions.
 Creating RegExp at depth 50
-PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception Error: Out of memory: Invalid regular _expression_: too many nested disjunctions.
+PASS new RegExp(Array(500000).join("(") + "a" + Array(500000).join(")")) threw exception Error: Out of memory: Invalid regular _expression_: too many nested disjunctions.
 Creating RegExp at depth 60
-PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception Error: Out of memory: Invalid regular _expression_: too many nested disjunctions.
+PASS new RegExp(Array(500000).join("(") + "a" + Array(500000).join(")")) threw exception Error: Out of memory: Invalid regular _expression_: too many nested disjunctions.
 Creating RegExp at depth 70
-PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception Error: Out of memory: Invalid regular _expression_: too many nested disjunctions.
+PASS new RegExp(Array(500000).join("(") + "a" + Array(500000).join(")")) threw exception Error: Out of memory: Invalid regular _expression_: too many nested disjunctions.
 Creating RegExp at depth 80
-PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception Error: Out of memory: Invalid regular _expression_: too many nested disjunctions.
+PASS new RegExp(Array(500000).join("(") + "a" + Array(500000).join(")")) threw exception Error: Out of memory: Invalid regular _expression_: too many nested disjunctions.
 Creating RegExp at depth 90
-PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception Error: Out of memory: Invalid regular _expression_: too many nested disjunctions.
+PASS new RegExp(Array(500000).join("(") + "a" + Array(500000).join(")")) threw exception Error: Out of memory: Invalid regular _expression_: too many nested disjunctions.
 Creating RegExp at depth 100
-PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception Error: Out of memory: Invalid regular _expression_: too many nested disjunctions.
-PASS new RegExp(_expression_) threw exception Error: Out of memory: Invalid regular _expression_: too many nested disjunctions.
+PASS new RegExp(Array(500000).join("(") + "a" + Array(500000).join(")")) threw exception Error: Out of memory: Invalid regular _expression_: too many nested disjunctions.
+PASS new RegExp(_expression_) threw exception SyntaxError: Invalid regular _expression_: regular _expression_ too large.
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/Source/_javascript_Core/ChangeLog (259091 => 259092)


--- trunk/Source/_javascript_Core/ChangeLog	2020-03-26 23:10:36 UTC (rev 259091)
+++ trunk/Source/_javascript_Core/ChangeLog	2020-03-26 23:27:57 UTC (rev 259092)
@@ -1,3 +1,59 @@
+2020-03-26  Michael Saboff  <msab...@apple.com>
+
+        Refactor YARR Stack Overflow Checks
+        https://bugs.webkit.org/show_bug.cgi?id=209435
+        rdar://problem/58988252
+
+        Reviewed by Mark Lam.
+
+        Refactored stack checks in YARR code including adding a stack check to the YARR JIT'ed code.
+        The C++ code including the parser, byte code compiler and interpreter now all use StackCheck.
+        The JIT'ed code needs a stack limit passed via a parameter since the JIT'ed code can be 
+        called from the compiler thread when compiling DFG / FTL code.
+
+        Instead of adding a new parameter, consolidated the two pattern context buffer values, buffer
+        pointer and size, with the new stack limit into a new MatchingContextHolder, an RAII object.
+        The MatchingContextHolder constructor uses either the VM stack limit or the current thread's
+        stack limit depending on how it is called.
+
+        * runtime/RegExp.cpp:
+        (JSC::RegExp::finishCreation):
+        (JSC::RegExp::byteCodeCompileIfNecessary):
+        (JSC::RegExp::compile):
+        (JSC::RegExp::matchConcurrently):
+        (JSC::RegExp::compileMatchOnly):
+        * runtime/RegExp.h:
+        * runtime/RegExpInlines.h:
+        (JSC::RegExp::matchInline):
+        (JSC::PatternContextBufferHolder::PatternContextBufferHolder): Deleted.
+        (JSC::PatternContextBufferHolder::~PatternContextBufferHolder): Deleted.
+        (JSC::PatternContextBufferHolder::buffer): Deleted.
+        (JSC::PatternContextBufferHolder::size): Deleted.
+        (): Deleted.
+        * yarr/Yarr.h:
+        * yarr/YarrInterpreter.cpp:
+        (JSC::Yarr::Interpreter::matchDisjunction):
+        (JSC::Yarr::Interpreter::isSafeToRecurse):
+        * yarr/YarrJIT.cpp:
+        (JSC::Yarr::MatchingContextHolder::MatchingContextHolder):
+        (JSC::Yarr::MatchingContextHolder::~MatchingContextHolder):
+        (JSC::Yarr::YarrGenerator::initParenContextFreeList):
+        (JSC::Yarr::YarrGenerator::alignCallFrameSizeInBytes):
+        (JSC::Yarr::YarrGenerator::compile):
+        (JSC::Yarr::YarrGenerator::initCallFrame): Deleted.
+        * yarr/YarrJIT.h:
+        (JSC::Yarr::MatchingContextHolder::offsetOfStackLimit):
+        (JSC::Yarr::MatchingContextHolder::offsetOfPatternContextBuffer):
+        (JSC::Yarr::MatchingContextHolder::offsetOfPatternContextBufferSize):
+        (JSC::Yarr::YarrCodeBlock::execute):
+        * yarr/YarrPattern.cpp:
+        (JSC::Yarr::YarrPatternConstructor::YarrPatternConstructor):
+        (JSC::Yarr::YarrPatternConstructor::isSafeToRecurse):
+        (JSC::Yarr::YarrPattern::compile):
+        (JSC::Yarr::YarrPattern::YarrPattern):
+        (JSC::Yarr::YarrPatternConstructor::isSafeToRecurse const): Deleted.
+        * yarr/YarrPattern.h:
+
 2020-03-26  Keith Miller  <keith_mil...@apple.com>
 
         TypedArrays should more gracefully handle OOM during slowDownAndWasteMemory

Modified: trunk/Source/_javascript_Core/runtime/RegExp.cpp (259091 => 259092)


--- trunk/Source/_javascript_Core/runtime/RegExp.cpp	2020-03-26 23:10:36 UTC (rev 259091)
+++ trunk/Source/_javascript_Core/runtime/RegExp.cpp	2020-03-26 23:27:57 UTC (rev 259092)
@@ -170,7 +170,7 @@
 void RegExp::finishCreation(VM& vm)
 {
     Base::finishCreation(vm);
-    Yarr::YarrPattern pattern(m_patternString, m_flags, m_constructionErrorCode, vm.stackLimit());
+    Yarr::YarrPattern pattern(m_patternString, m_flags, m_constructionErrorCode);
     if (!isValid()) {
         m_state = ParseError;
         return;
@@ -227,13 +227,10 @@
     if (m_regExpBytecode)
         return;
 
-    Yarr::YarrPattern pattern(m_patternString, m_flags, m_constructionErrorCode, vm->stackLimit());
+    Yarr::YarrPattern pattern(m_patternString, m_flags, m_constructionErrorCode);
     if (hasError(m_constructionErrorCode)) {
-        RELEASE_ASSERT_NOT_REACHED();
-#if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE)
         m_state = ParseError;
         return;
-#endif
     }
     ASSERT(m_numSubpatterns == pattern.m_numSubpatterns);
 
@@ -248,7 +245,7 @@
 {
     auto locker = holdLock(cellLock());
     
-    Yarr::YarrPattern pattern(m_patternString, m_flags, m_constructionErrorCode, vm->stackLimit());
+    Yarr::YarrPattern pattern(m_patternString, m_flags, m_constructionErrorCode);
     if (hasError(m_constructionErrorCode)) {
         m_state = ParseError;
         return;
@@ -302,7 +299,9 @@
     if (!hasCodeFor(s.is8Bit() ? Yarr::Char8 : Yarr::Char16))
         return false;
 
-    position = match(vm, s, startOffset, ovector);
+    position = matchInline<Vector<int>&, Yarr::MatchFrom::CompilerThread>(vm, s, startOffset, ovector);
+    if (m_state == ParseError)
+        return false;
     return true;
 }
 
@@ -310,7 +309,7 @@
 {
     auto locker = holdLock(cellLock());
     
-    Yarr::YarrPattern pattern(m_patternString, m_flags, m_constructionErrorCode, vm->stackLimit());
+    Yarr::YarrPattern pattern(m_patternString, m_flags, m_constructionErrorCode);
     if (hasError(m_constructionErrorCode)) {
         m_state = ParseError;
         return;
@@ -363,7 +362,7 @@
     if (!hasMatchOnlyCodeFor(s.is8Bit() ? Yarr::Char8 : Yarr::Char16))
         return false;
 
-    result = match(vm, s, startOffset);
+    result = matchInline<Yarr::MatchFrom::CompilerThread>(vm, s, startOffset);
     return true;
 }
 

Modified: trunk/Source/_javascript_Core/runtime/RegExp.h (259091 => 259092)


--- trunk/Source/_javascript_Core/runtime/RegExp.h	2020-03-26 23:10:36 UTC (rev 259091)
+++ trunk/Source/_javascript_Core/runtime/RegExp.h	2020-03-26 23:27:57 UTC (rev 259092)
@@ -86,8 +86,9 @@
     bool matchConcurrently(VM&, const String&, unsigned startOffset, MatchResult&);
 
     // Call these versions of the match functions if you're desperate for performance.
-    template<typename VectorType>
+    template<typename VectorType, Yarr::MatchFrom thread = Yarr::MatchFrom::VMThread>
     int matchInline(VM&, const String&, unsigned startOffset, VectorType& ovector);
+    template<Yarr::MatchFrom thread = Yarr::MatchFrom::VMThread>
     MatchResult matchInline(VM&, const String&, unsigned startOffset);
     
     unsigned numSubpatterns() const { return m_numSubpatterns; }

Modified: trunk/Source/_javascript_Core/runtime/RegExpInlines.h (259091 => 259092)


--- trunk/Source/_javascript_Core/runtime/RegExpInlines.h	2020-03-26 23:10:36 UTC (rev 259091)
+++ trunk/Source/_javascript_Core/runtime/RegExpInlines.h	2020-03-26 23:27:57 UTC (rev 259092)
@@ -86,38 +86,6 @@
     return false;
 }
 
-class PatternContextBufferHolder {
-    WTF_FORBID_HEAP_ALLOCATION;
-public:
-    PatternContextBufferHolder(VM& vm, bool needBuffer)
-        : m_vm(vm)
-    {
-#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
-        if (needBuffer)
-            m_buffer = m_vm.acquireRegExpPatternContexBuffer();
-#else
-        UNUSED_PARAM(needBuffer);
-#endif
-    }
-
-    ~PatternContextBufferHolder()
-    {
-#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
-        if (buffer())
-            m_vm.releaseRegExpPatternContexBuffer();
-#else
-        UNUSED_PARAM(m_vm);
-#endif
-    }
-
-    void* buffer() { return m_buffer; }
-    unsigned size() { return buffer() ? VM::patternContextBufferSize : 0; }
-
-private:
-    VM& m_vm;
-    void* m_buffer { nullptr };
-};
-
 ALWAYS_INLINE void RegExp::compileIfNecessary(VM& vm, Yarr::YarrCharSize charSize)
 {
     if (hasCodeFor(charSize))
@@ -129,7 +97,7 @@
     compile(&vm, charSize);
 }
 
-template<typename VectorType>
+template<typename VectorType, Yarr::MatchFrom matchFrom>
 ALWAYS_INLINE int RegExp::matchInline(VM& vm, const String& s, unsigned startOffset, VectorType& ovector)
 {
 #if ENABLE(REGEXP_TRACING)
@@ -162,19 +130,22 @@
     if (m_state == JITCode) {
         {
             ASSERT(m_regExpJITCode);
-            PatternContextBufferHolder patternContextBufferHolder(vm, m_regExpJITCode->usesPatternContextBuffer());
+            Yarr::MatchingContextHolder regExpContext(vm, m_regExpJITCode.get(), matchFrom);
 
             if (s.is8Bit())
-                result = m_regExpJITCode->execute(s.characters8(), startOffset, s.length(), offsetVector, patternContextBufferHolder.buffer(), patternContextBufferHolder.size()).start;
+                result = m_regExpJITCode->execute(s.characters8(), startOffset, s.length(), offsetVector, regExpContext).start;
             else
-                result = m_regExpJITCode->execute(s.characters16(), startOffset, s.length(), offsetVector, patternContextBufferHolder.buffer(), patternContextBufferHolder.size()).start;
+                result = m_regExpJITCode->execute(s.characters16(), startOffset, s.length(), offsetVector, regExpContext).start;
         }
 
         if (result == Yarr::JSRegExpJITCodeFailure) {
             // JIT'ed code couldn't handle _expression_, so punt back to the interpreter.
             byteCodeCompileIfNecessary(&vm);
-            if (m_state == ParseError)
+            if (m_state == ParseError) {
+                if (matchFrom == Yarr::MatchFrom::CompilerThread)
+                    return -1;
                 return throwError();
+            }
             result = Yarr::interpret(m_regExpBytecode.get(), s, startOffset, reinterpret_cast<unsigned*>(offsetVector));
         }
 
@@ -260,6 +231,7 @@
     compileMatchOnly(&vm, charSize);
 }
 
+template<Yarr::MatchFrom matchFrom>
 ALWAYS_INLINE MatchResult RegExp::matchInline(VM& vm, const String& s, unsigned startOffset)
 {
 #if ENABLE(REGEXP_TRACING)
@@ -289,11 +261,12 @@
     if (m_state == JITCode) {
         {
             ASSERT(m_regExpJITCode);
-            PatternContextBufferHolder patternContextBufferHolder(vm, m_regExpJITCode->usesPatternContextBuffer());
+            Yarr::MatchingContextHolder regExpContext(vm, m_regExpJITCode.get(), matchFrom);
+
             if (s.is8Bit())
-                result = m_regExpJITCode->execute(s.characters8(), startOffset, s.length(), patternContextBufferHolder.buffer(), patternContextBufferHolder.size());
+                result = m_regExpJITCode->execute(s.characters8(), startOffset, s.length(), regExpContext);
             else
-                result = m_regExpJITCode->execute(s.characters16(), startOffset, s.length(), patternContextBufferHolder.buffer(), patternContextBufferHolder.size());
+                result = m_regExpJITCode->execute(s.characters16(), startOffset, s.length(), regExpContext);
         }
 
 #if ENABLE(REGEXP_TRACING)

Modified: trunk/Source/_javascript_Core/yarr/Yarr.h (259091 => 259092)


--- trunk/Source/_javascript_Core/yarr/Yarr.h	2020-03-26 23:10:36 UTC (rev 259091)
+++ trunk/Source/_javascript_Core/yarr/Yarr.h	2020-03-26 23:27:57 UTC (rev 259092)
@@ -49,6 +49,8 @@
 // avoid spending exponential time on complex regular expressions.
 static constexpr unsigned matchLimit = 1000000;
 
+enum MatchFrom { VMThread, CompilerThread };
+
 enum JSRegExpResult {
     JSRegExpMatch = 1,
     JSRegExpNoMatch = 0,

Modified: trunk/Source/_javascript_Core/yarr/YarrInterpreter.cpp (259091 => 259092)


--- trunk/Source/_javascript_Core/yarr/YarrInterpreter.cpp	2020-03-26 23:10:36 UTC (rev 259091)
+++ trunk/Source/_javascript_Core/yarr/YarrInterpreter.cpp	2020-03-26 23:27:57 UTC (rev 259092)
@@ -1272,6 +1272,9 @@
 #define currentTerm() (disjunction->terms[context->term])
     JSRegExpResult matchDisjunction(ByteDisjunction* disjunction, DisjunctionContext* context, bool btrack = false)
     {
+        if (UNLIKELY(!isSafeToRecurse()))
+            return JSRegExpErrorNoMemory;
+
         if (!--remainingMatchCount)
             return JSRegExpErrorHitLimit;
 
@@ -1667,10 +1670,13 @@
     }
 
 private:
+    inline bool isSafeToRecurse() { return m_stackCheck.isSafeToRecurse(); }
+
     BytecodePattern* pattern;
     bool unicode;
     unsigned* output;
     InputStream input;
+    StackCheck m_stackCheck;
     WTF::BumpPointerPool* allocatorPool { nullptr };
     unsigned startOffset;
     unsigned remainingMatchCount;

Modified: trunk/Source/_javascript_Core/yarr/YarrJIT.cpp (259091 => 259092)


--- trunk/Source/_javascript_Core/yarr/YarrJIT.cpp	2020-03-26 23:10:36 UTC (rev 259091)
+++ trunk/Source/_javascript_Core/yarr/YarrJIT.cpp	2020-03-26 23:27:57 UTC (rev 259092)
@@ -26,7 +26,6 @@
 #include "config.h"
 #include "YarrJIT.h"
 
-#include <wtf/ASCIICType.h>
 #include "LinkBuffer.h"
 #include "Options.h"
 #include "VM.h"
@@ -33,11 +32,42 @@
 #include "Yarr.h"
 #include "YarrCanonicalize.h"
 #include "YarrDisassembler.h"
+#include <wtf/ASCIICType.h>
+#include <wtf/Threading.h>
 
+
 #if ENABLE(YARR_JIT)
 
 namespace JSC { namespace Yarr {
 
+MatchingContextHolder::MatchingContextHolder(VM& vm, YarrCodeBlock* yarrCodeBlock, MatchFrom matchFrom)
+    : m_vm(vm)
+{
+    if (matchFrom == MatchFrom::VMThread)
+        m_stackLimit = vm.softStackLimit();
+    else {
+        StackBounds stack = Thread::current().stack();
+        m_stackLimit = stack.recursionLimit(Options::reservedZoneSize());
+    }
+
+#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
+    if (yarrCodeBlock->usesPatternContextBuffer()) {
+        m_patternContextBuffer = m_vm.acquireRegExpPatternContexBuffer();
+        m_patternContextBufferSize = VM::patternContextBufferSize;
+    }
+#else
+    UNUSED_PARAM(yarrCodeBlock);
+#endif
+}
+
+MatchingContextHolder::~MatchingContextHolder()
+{
+#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
+    if (m_patternContextBuffer)
+        m_vm.releaseRegExpPatternContexBuffer();
+#endif
+}
+
 template<YarrJITCompileMode compileMode>
 class YarrGenerator : public YarrJITInfo, private MacroAssembler {
 
@@ -60,7 +90,8 @@
     static const RegisterID index = ARM64Registers::x1;
     static const RegisterID length = ARM64Registers::x2;
     static const RegisterID output = ARM64Registers::x3;
-    static const RegisterID freelistRegister = ARM64Registers::x4;
+    static const RegisterID matchingContext = ARM64Registers::x4;
+    static const RegisterID freelistRegister = ARM64Registers::x4; // Loaded from the MatchingContextHolder in the prologue.
     static const RegisterID freelistSizeRegister = ARM64Registers::x5; // Only used during initialization.
 
     // Scratch registers
@@ -101,7 +132,8 @@
     static const RegisterID index = X86Registers::esi;
     static const RegisterID length = X86Registers::edx;
     static const RegisterID output = X86Registers::ecx;
-    static const RegisterID freelistRegister = X86Registers::r8;
+    static const RegisterID matchingContext = X86Registers::r8;
+    static const RegisterID freelistRegister = X86Registers::r8; // Loaded from the MatchingContextHolder in the prologue.
     static const RegisterID freelistSizeRegister = X86Registers::r9; // Only used during initialization.
 #else
     // If the return value doesn't fit in 64bits, its destination is pointed by rcx and the parameters are shifted.
@@ -220,6 +252,9 @@
             return;
         }
 
+        load32(Address(matchingContext, MatchingContextHolder::offsetOfPatternContextBufferSize()), freelistSizeRegister);
+        // Note that matchingContext and freelistRegister are likely the same register.
+        loadPtr(Address(matchingContext, MatchingContextHolder::offsetOfPatternContextBuffer()), freelistRegister);
         Jump emptyFreeList = branchTestPtr(Zero, freelistRegister);
         move(freelistRegister, parenContextPointer);
         addPtr(TrustedImm32(parenContextSize), freelistRegister, nextParenContextPointer);
@@ -635,12 +670,6 @@
         callFrameSize = (callFrameSize + 0x3f) & ~0x3f;
         return callFrameSize;
     }
-    void initCallFrame()
-    {
-        unsigned callFrameSizeInBytes = alignCallFrameSizeInBytes(m_pattern.m_body->m_callFrameSize);
-        if (callFrameSizeInBytes)
-            subPtr(Imm32(callFrameSizeInBytes), stackPointerRegister);
-    }
     void removeCallFrame()
     {
         unsigned callFrameSizeInBytes = alignCallFrameSizeInBytes(m_pattern.m_body->m_callFrameSize);
@@ -3851,6 +3880,30 @@
         generateFailReturn();
         hasInput.link(this);
 
+        unsigned callFrameSizeInBytes = alignCallFrameSizeInBytes(m_pattern.m_body->m_callFrameSize);
+        if (callFrameSizeInBytes) {
+            // Check stack size
+            addPtr(TrustedImm32(-callFrameSizeInBytes), stackPointerRegister, regT0);
+#if CPU(X86_64) && OS(WINDOWS)
+            // matchingContext is the 5th argument, it is found on the stack.
+            RegisterID matchingContext = regT1;
+            loadPtr(Address(X86Registers::ebp, 7 * sizeof(void*)), matchingContext);
+#elif CPU(ARM_THUMB2) || CPU(MIPS)
+            // matchingContext is the 5th argument, it is found on the stack.
+            RegisterID matchingContext = regT1;
+            loadPtr(Address(stackPointerRegister, 4 * sizeof(void*)), matchingContext);
+#endif
+            Jump stackOk = branchPtr(BelowOrEqual, Address(matchingContext, MatchingContextHolder::offsetOfStackLimit()), regT0);
+
+            // Exceeded stack limit, punt to the interpreter.
+            move(TrustedImmPtr((void*)static_cast<size_t>(JSRegExpJITCodeFailure)), returnRegister);
+            move(TrustedImm32(0), returnRegister2);
+            generateReturn();
+
+            stackOk.link(this);
+            move(regT0, stackPointerRegister);
+        }
+
 #ifdef JIT_UNICODE_EXPRESSIONS
         if (m_decodeSurrogatePairs)
             getEffectiveAddress(BaseIndex(input, length, TimesTwo), endOfStringAddress);
@@ -3869,8 +3922,6 @@
         if (!m_pattern.m_body->m_hasFixedSize)
             setMatchStart(index);
 
-        initCallFrame();
-
 #if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
         if (m_containsNestedSubpatterns) {
             initParenContextFreeList();

Modified: trunk/Source/_javascript_Core/yarr/YarrJIT.h (259091 => 259092)


--- trunk/Source/_javascript_Core/yarr/YarrJIT.h	2020-03-26 23:10:36 UTC (rev 259091)
+++ trunk/Source/_javascript_Core/yarr/YarrJIT.h	2020-03-26 23:27:57 UTC (rev 259092)
@@ -29,6 +29,7 @@
 
 #include "MacroAssemblerCodeRef.h"
 #include "MatchResult.h"
+#include "VM.h"
 #include "Yarr.h"
 #include "YarrPattern.h"
 
@@ -41,6 +42,8 @@
 
 namespace Yarr {
 
+class YarrCodeBlock;
+
 enum class JITFailureReason : uint8_t {
     DecodeSurrogatePair,
     BackReference,
@@ -52,15 +55,35 @@
     ExecutableMemoryAllocationFailure,
 };
 
+class MatchingContextHolder {
+    WTF_FORBID_HEAP_ALLOCATION;
+public:
+    MatchingContextHolder(VM&, YarrCodeBlock*, MatchFrom matchFrom = MatchFrom::VMThread);
+    ~MatchingContextHolder();
+
+    static ptrdiff_t offsetOfStackLimit() { return OBJECT_OFFSETOF(MatchingContextHolder, m_stackLimit); }
+#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
+    static ptrdiff_t offsetOfPatternContextBuffer() { return OBJECT_OFFSETOF(MatchingContextHolder, m_patternContextBuffer); }
+    static ptrdiff_t offsetOfPatternContextBufferSize() { return OBJECT_OFFSETOF(MatchingContextHolder, m_patternContextBufferSize); }
+#endif
+
+private:
+    VM& m_vm;
+    void* m_stackLimit;
+#if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
+    void* m_patternContextBuffer { nullptr };
+    unsigned m_patternContextBufferSize { 0 };
+#endif
+};
+
 class YarrCodeBlock {
     WTF_MAKE_FAST_ALLOCATED;
     WTF_MAKE_NONCOPYABLE(YarrCodeBlock);
 
-    // Technically freeParenContext and parenContextSize are only used if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS) is set. Fortunately, all the calling conventions we support have caller save argument registers.
-    using YarrJITCode8 = EncodedMatchResult (*)(const LChar* input, unsigned start, unsigned length, int* output, void* freeParenContext, unsigned parenContextSize) YARR_CALL;
-    using YarrJITCode16 = EncodedMatchResult (*)(const UChar* input, unsigned start, unsigned length, int* output, void* freeParenContext, unsigned parenContextSize) YARR_CALL;
-    using YarrJITCodeMatchOnly8 = EncodedMatchResult (*)(const LChar* input, unsigned start, unsigned length, void*, void* freeParenContext, unsigned parenContextSize) YARR_CALL;
-    using YarrJITCodeMatchOnly16 = EncodedMatchResult (*)(const UChar* input, unsigned start, unsigned length, void*, void* freeParenContext, unsigned parenContextSize) YARR_CALL;
+    using YarrJITCode8 = EncodedMatchResult (*)(const LChar* input, unsigned start, unsigned length, int* output, MatchingContextHolder& matchingContext) YARR_CALL;
+    using YarrJITCode16 = EncodedMatchResult (*)(const UChar* input, unsigned start, unsigned length, int* output, MatchingContextHolder& matchingContext) YARR_CALL;
+    using YarrJITCodeMatchOnly8 = EncodedMatchResult (*)(const LChar* input, unsigned start, unsigned length, void*, MatchingContextHolder& matchingContext) YARR_CALL;
+    using YarrJITCodeMatchOnly16 = EncodedMatchResult (*)(const UChar* input, unsigned start, unsigned length, void*, MatchingContextHolder& matchingContext) YARR_CALL;
 
 public:
     YarrCodeBlock() = default;
@@ -83,28 +106,28 @@
     void setUsesPatternContextBuffer() { m_usesPatternContextBuffer = true; }
 #endif
 
-    MatchResult execute(const LChar* input, unsigned start, unsigned length, int* output, void* freeParenContext, unsigned parenContextSize)
+    MatchResult execute(const LChar* input, unsigned start, unsigned length, int* output, MatchingContextHolder& matchingContext)
     {
         ASSERT(has8BitCode());
-        return MatchResult(untagCFunctionPtr<YarrJITCode8, Yarr8BitPtrTag>(m_ref8.code().executableAddress())(input, start, length, output, freeParenContext, parenContextSize));
+        return MatchResult(untagCFunctionPtr<YarrJITCode8, Yarr8BitPtrTag>(m_ref8.code().executableAddress())(input, start, length, output, matchingContext));
     }
 
-    MatchResult execute(const UChar* input, unsigned start, unsigned length, int* output, void* freeParenContext, unsigned parenContextSize)
+    MatchResult execute(const UChar* input, unsigned start, unsigned length, int* output, MatchingContextHolder& matchingContext)
     {
         ASSERT(has16BitCode());
-        return MatchResult(untagCFunctionPtr<YarrJITCode16, Yarr16BitPtrTag>(m_ref16.code().executableAddress())(input, start, length, output, freeParenContext, parenContextSize));
+        return MatchResult(untagCFunctionPtr<YarrJITCode16, Yarr16BitPtrTag>(m_ref16.code().executableAddress())(input, start, length, output, matchingContext));
     }
 
-    MatchResult execute(const LChar* input, unsigned start, unsigned length, void* freeParenContext, unsigned parenContextSize)
+    MatchResult execute(const LChar* input, unsigned start, unsigned length, MatchingContextHolder& matchingContext)
     {
         ASSERT(has8BitCodeMatchOnly());
-        return MatchResult(untagCFunctionPtr<YarrJITCodeMatchOnly8, YarrMatchOnly8BitPtrTag>(m_matchOnly8.code().executableAddress())(input, start, length, 0, freeParenContext, parenContextSize));
+        return MatchResult(untagCFunctionPtr<YarrJITCodeMatchOnly8, YarrMatchOnly8BitPtrTag>(m_matchOnly8.code().executableAddress())(input, start, length, 0, matchingContext));
     }
 
-    MatchResult execute(const UChar* input, unsigned start, unsigned length, void* freeParenContext, unsigned parenContextSize)
+    MatchResult execute(const UChar* input, unsigned start, unsigned length, MatchingContextHolder& matchingContext)
     {
         ASSERT(has16BitCodeMatchOnly());
-        return MatchResult(untagCFunctionPtr<YarrJITCodeMatchOnly16, YarrMatchOnly16BitPtrTag>(m_matchOnly16.code().executableAddress())(input, start, length, 0, freeParenContext, parenContextSize));
+        return MatchResult(untagCFunctionPtr<YarrJITCodeMatchOnly16, YarrMatchOnly16BitPtrTag>(m_matchOnly16.code().executableAddress())(input, start, length, 0, matchingContext));
     }
 
 #if ENABLE(REGEXP_TRACING)

Modified: trunk/Source/_javascript_Core/yarr/YarrPattern.cpp (259091 => 259092)


--- trunk/Source/_javascript_Core/yarr/YarrPattern.cpp	2020-03-26 23:10:36 UTC (rev 259091)
+++ trunk/Source/_javascript_Core/yarr/YarrPattern.cpp	2020-03-26 23:27:57 UTC (rev 259092)
@@ -33,7 +33,7 @@
 #include "YarrParser.h"
 #include <wtf/DataLog.h>
 #include <wtf/Optional.h>
-#include <wtf/StackPointer.h>
+#include <wtf/StackCheck.h>
 #include <wtf/Threading.h>
 #include <wtf/Vector.h>
 
@@ -436,10 +436,9 @@
 
 class YarrPatternConstructor {
 public:
-    YarrPatternConstructor(YarrPattern& pattern, void* stackLimit)
+    YarrPatternConstructor(YarrPattern& pattern)
         : m_pattern(pattern)
         , m_characterClassConstructor(pattern.ignoreCase(), pattern.unicode() ? CanonicalMode::Unicode : CanonicalMode::UCS2)
-        , m_stackLimit(stackLimit)
     {
         auto body = makeUnique<PatternDisjunction>();
         m_pattern.m_body = body.get();
@@ -1101,27 +1100,20 @@
     ErrorCode error() { return m_error; }
 
 private:
-    bool isSafeToRecurse() const
-    {
-        if (!m_stackLimit)
-            return true;
-        int8_t* curr = reinterpret_cast<int8_t*>(currentStackPointer());
-        int8_t* limit = reinterpret_cast<int8_t*>(m_stackLimit);
-        return curr >= limit;
-    }
+    inline bool isSafeToRecurse() { return m_stackCheck.isSafeToRecurse(); }
 
     YarrPattern& m_pattern;
     PatternAlternative* m_alternative;
     CharacterClassConstructor m_characterClassConstructor;
-    void* m_stackLimit;
+    StackCheck m_stackCheck;
     ErrorCode m_error { ErrorCode::NoError };
     bool m_invertCharacterClass;
     bool m_invertParentheticalAssertion { false };
 };
 
-ErrorCode YarrPattern::compile(const String& patternString, void* stackLimit)
+ErrorCode YarrPattern::compile(const String& patternString)
 {
-    YarrPatternConstructor constructor(*this, stackLimit);
+    YarrPatternConstructor constructor(*this);
 
     {
         ErrorCode error = parse(constructor, patternString, unicode());
@@ -1148,7 +1140,7 @@
     return ErrorCode::NoError;
 }
 
-YarrPattern::YarrPattern(const String& pattern, OptionSet<Flags> flags, ErrorCode& error, void* stackLimit)
+YarrPattern::YarrPattern(const String& pattern, OptionSet<Flags> flags, ErrorCode& error)
     : m_containsBackreferences(false)
     , m_containsBOL(false)
     , m_containsUnsignedLengthPattern(false)
@@ -1157,7 +1149,7 @@
     , m_flags(flags)
 {
     ASSERT(m_flags != Flags::DeletedValue);
-    error = compile(pattern, stackLimit);
+    error = compile(pattern);
 }
 
 void indentForNestingLevel(PrintStream& out, unsigned nestingDepth)

Modified: trunk/Source/_javascript_Core/yarr/YarrPattern.h (259091 => 259092)


--- trunk/Source/_javascript_Core/yarr/YarrPattern.h	2020-03-26 23:10:36 UTC (rev 259091)
+++ trunk/Source/_javascript_Core/yarr/YarrPattern.h	2020-03-26 23:27:57 UTC (rev 259092)
@@ -386,7 +386,7 @@
 
 
 struct YarrPattern {
-    JS_EXPORT_PRIVATE YarrPattern(const String& pattern, OptionSet<Flags>, ErrorCode&, void* stackLimit = nullptr);
+    JS_EXPORT_PRIVATE YarrPattern(const String& pattern, OptionSet<Flags>, ErrorCode&);
 
     void resetForReparsing()
     {
@@ -543,7 +543,7 @@
     HashMap<String, unsigned> m_namedGroupToParenIndex;
 
 private:
-    ErrorCode compile(const String& patternString, void* stackLimit);
+    ErrorCode compile(const String& patternString);
 
     CharacterClass* anycharCached { nullptr };
     CharacterClass* newlineCached { nullptr };
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to