Title: [248951] trunk
Revision
248951
Author
msab...@apple.com
Date
2019-08-21 11:08:48 -0700 (Wed, 21 Aug 2019)

Log Message

[JSC] incorrent JIT lead to StackOverflow
https://bugs.webkit.org/show_bug.cgi?id=197823

Reviewed by Tadeu Zagallo.

JSTests:

New test.

* stress/bound-function-stack-overflow.js: Added.
(foo):
(catch):

Source/_javascript_Core:

Added stack overflow check to the bound function thunk generator.  Added a new C++ operation
throwStackOverflowErrorFromThunk() to throw the error.
        
* jit/JITOperations.cpp:
* jit/JITOperations.h:
* jit/ThunkGenerators.cpp:
(JSC::boundThisNoArgsFunctionCallGenerator):

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (248950 => 248951)


--- trunk/JSTests/ChangeLog	2019-08-21 18:02:02 UTC (rev 248950)
+++ trunk/JSTests/ChangeLog	2019-08-21 18:08:48 UTC (rev 248951)
@@ -1,3 +1,16 @@
+2019-08-21  Michael Saboff  <msab...@apple.com>
+
+        [JSC] incorrent JIT lead to StackOverflow
+        https://bugs.webkit.org/show_bug.cgi?id=197823
+
+        Reviewed by Tadeu Zagallo.
+
+        New test.
+
+        * stress/bound-function-stack-overflow.js: Added.
+        (foo):
+        (catch):
+
 2019-08-20  Justin Michaud  <justin_mich...@apple.com>
 
         Identify memcpy loops in b3

Added: trunk/JSTests/stress/bound-function-stack-overflow.js (0 => 248951)


--- trunk/JSTests/stress/bound-function-stack-overflow.js	                        (rev 0)
+++ trunk/JSTests/stress/bound-function-stack-overflow.js	2019-08-21 18:08:48 UTC (rev 248951)
@@ -0,0 +1,34 @@
+// This test verifies that we check for out of stack errors from recursively bound functions.
+// It should exit without any output.
+
+let expectedException = "RangeError: Maximum call stack size exceeded.";
+let actualException = false;
+
+function foo()
+{
+}
+
+for (var i = 0; i < 5000; ++i) {
+    foo = foo.bind(1);
+    Object.defineProperty(foo, "name", { value: "bar", writable: true, enumerable: true, writable: true });
+}
+
+try {
+    foo("x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", 
+        "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", 
+        "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", 
+        "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", 
+        "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", 
+        "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", 
+        "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", 
+        "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", 
+        "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", 
+        "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x");
+} catch (e) {
+    actualException = e;
+}
+
+if (!actualException)
+    throw "Expected \"" + expectedException + "\" exception, but no exceptoion was thrown";
+else if (actualException != expectedException)
+    throw "Expected \"" + expectedException + "\", but got \"" + actualException +"\"";

Modified: trunk/Source/_javascript_Core/ChangeLog (248950 => 248951)


--- trunk/Source/_javascript_Core/ChangeLog	2019-08-21 18:02:02 UTC (rev 248950)
+++ trunk/Source/_javascript_Core/ChangeLog	2019-08-21 18:08:48 UTC (rev 248951)
@@ -1,3 +1,18 @@
+2019-08-21  Michael Saboff  <msab...@apple.com>
+
+        [JSC] incorrent JIT lead to StackOverflow
+        https://bugs.webkit.org/show_bug.cgi?id=197823
+
+        Reviewed by Tadeu Zagallo.
+
+        Added stack overflow check to the bound function thunk generator.  Added a new C++ operation
+        throwStackOverflowErrorFromThunk() to throw the error.
+        
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * jit/ThunkGenerators.cpp:
+        (JSC::boundThisNoArgsFunctionCallGenerator):
+
 2019-08-21  Devin Rousso  <drou...@apple.com>
 
         Web Inspector: Page: re-add enable/disable after r248454

Modified: trunk/Source/_javascript_Core/jit/JITOperations.cpp (248950 => 248951)


--- trunk/Source/_javascript_Core/jit/JITOperations.cpp	2019-08-21 18:02:02 UTC (rev 248950)
+++ trunk/Source/_javascript_Core/jit/JITOperations.cpp	2019-08-21 18:08:48 UTC (rev 248951)
@@ -109,6 +109,15 @@
     throwStackOverflowError(exec, scope);
 }
 
+void JIT_OPERATION throwStackOverflowErrorFromThunk(VM* vm, ExecState* exec)
+{
+    auto scope = DECLARE_THROW_SCOPE(*vm);
+    NativeCallFrameTracer tracer(vm, exec);
+    throwStackOverflowError(exec, scope);
+    genericUnwind(vm, exec);
+    ASSERT(vm->targetMachinePCForThrow);
+}
+
 int32_t JIT_OPERATION operationCallArityCheck(ExecState* exec)
 {
     VM* vm = &exec->vm();

Modified: trunk/Source/_javascript_Core/jit/JITOperations.h (248950 => 248951)


--- trunk/Source/_javascript_Core/jit/JITOperations.h	2019-08-21 18:02:02 UTC (rev 248950)
+++ trunk/Source/_javascript_Core/jit/JITOperations.h	2019-08-21 18:08:48 UTC (rev 248951)
@@ -351,6 +351,7 @@
 void JIT_OPERATION lookupExceptionHandler(VM*, ExecState*) WTF_INTERNAL;
 void JIT_OPERATION lookupExceptionHandlerFromCallerFrame(VM*, ExecState*) WTF_INTERNAL;
 void JIT_OPERATION operationVMHandleException(ExecState*) WTF_INTERNAL;
+void JIT_OPERATION throwStackOverflowErrorFromThunk(VM*, ExecState*) WTF_INTERNAL;
 
 void JIT_OPERATION operationThrowStackOverflowError(ExecState*, CodeBlock*) WTF_INTERNAL;
 int32_t JIT_OPERATION operationCallArityCheck(ExecState*) WTF_INTERNAL;

Modified: trunk/Source/_javascript_Core/jit/ThunkGenerators.cpp (248950 => 248951)


--- trunk/Source/_javascript_Core/jit/ThunkGenerators.cpp	2019-08-21 18:02:02 UTC (rev 248950)
+++ trunk/Source/_javascript_Core/jit/ThunkGenerators.cpp	2019-08-21 18:08:48 UTC (rev 248951)
@@ -1189,11 +1189,24 @@
     if (extraStackNeeded)
         jit.add32(CCallHelpers::TrustedImm32(extraStackNeeded), GPRInfo::regT2);
     
-    // At this point regT1 has the actual argument count and regT2 has the amount of stack we will
-    // need.
+    // At this point regT1 has the actual argument count and regT2 has the amount of stack we will need.
+    // Check to see if we have enough stack space.
     
-    jit.subPtr(GPRInfo::regT2, CCallHelpers::stackPointerRegister);
+    jit.negPtr(GPRInfo::regT2);
+    jit.addPtr(CCallHelpers::stackPointerRegister, GPRInfo::regT2);
+    CCallHelpers::Jump haveStackSpace = jit.branchPtr(CCallHelpers::BelowOrEqual, CCallHelpers::AbsoluteAddress(vm->addressOfSoftStackLimit()), GPRInfo::regT2);
 
+    // Throw Stack Overflow exception
+    jit.copyCalleeSavesToEntryFrameCalleeSavesBuffer(vm->topEntryFrame);
+    jit.setupArguments<decltype(throwStackOverflowErrorFromThunk)>(CCallHelpers::TrustedImmPtr(vm), GPRInfo::callFrameRegister);
+    jit.move(CCallHelpers::TrustedImmPtr(tagCFunctionPtr<OperationPtrTag>(throwStackOverflowErrorFromThunk)), GPRInfo::nonArgGPR0);
+    emitPointerValidation(jit, GPRInfo::nonArgGPR0, OperationPtrTag);
+    jit.call(GPRInfo::nonArgGPR0, OperationPtrTag);
+    jit.jumpToExceptionHandler(*vm);
+
+    haveStackSpace.link(&jit);
+    jit.move(GPRInfo::regT2, CCallHelpers::stackPointerRegister);
+
     // Do basic callee frame setup, including 'this'.
     
     jit.loadCell(CCallHelpers::addressFor(CallFrameSlot::callee), GPRInfo::regT3);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to