StackOverflow stack unwinding should stop at native frames.
https://bugs.webkit.org/show_bug.cgi?id=148749
Reviewed by Michael Saboff.
In the present code, after ping-pong'ing back and forth between native and JS
code a few times, if we have a stack overflow on re-entry into the VM to run
JS code's whose stack frame would overflow the JS stack, the code will end up
unwinding past the native function that is making the call to re-enter the VM.
As a result, any clean up code (e.g. destructors for stack variables) in the
skipped native function frame (and its chain of native function callers) will
not be called.
This patch is based on the Michael Saboff's fix of this issue landed on the
jsc-tailcall branch: http://trac.webkit.org/changeset/188555
We now check for the case where there are no JS frames to unwind since the
last native frame, and treat the exception as an unhandled exception. The
native function is responsible for further propagating the exception if needed.
Other supporting work:
- Remove vm->vmEntryFrameForThrow. It should always be the same as
vm->topVMEntryFrame.
- Change operationThrowStackOverflowError() to use the throwStackOverflowError()
helper function instead of rolling its own.
- In the LLINT vm entry, set vm->topVMEntryFrame as soon as the entry frame is
fully initialized (instead of waiting). With this, we can always reliably
tell which VMEntryFrame is on top.
- Added a test that exercises this edge case. The test should not hang or crash.
- API/tests/PingPongStackOverflowTest.cpp: Added.
(PingPongStackOverflowObject_hasInstance):
(testPingPongStackOverflow):
- API/tests/PingPongStackOverflowTest.h: Added.
- API/tests/testapi.c:
(main):
- JavaScriptCore.xcodeproj/project.pbxproj:
- interpreter/Interpreter.cpp:
(JSC::unwindCallFrame):
(JSC::getStackFrameCodeType):
(JSC::UnwindFunctor::UnwindFunctor):
(JSC::UnwindFunctor::operator()):
(JSC::Interpreter::unwind):
- interpreter/Interpreter.h:
(JSC::NativeCallFrameTracer::NativeCallFrameTracer):
(JSC::NativeCallFrameTracerWithRestore::NativeCallFrameTracerWithRestore):
(JSC::NativeCallFrameTracerWithRestore::~NativeCallFrameTracerWithRestore):
(JSC::Interpreter::sampler):
(JSC::CCallHelpers::jumpToExceptionHandler):
(JSC::genericUnwind):
- jit/JITExceptions.h:
- jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_catch):
(JSC::JIT::emit_op_catch):
- jit/JITOperations.cpp:
- llint/LowLevelInterpreter32_64.asm:
- llint/LowLevelInterpreter64.asm:
- runtime/VM.h:
(JSC::VM::exceptionOffset):
(JSC::VM::callFrameForThrowOffset):
(JSC::VM::vmEntryFrameForThrowOffset): Deleted.
(JSC::VM::topVMEntryFrameOffset): Deleted.