From 11a76d417fe859a08b0641783401bb7bea358e02 Mon Sep 17 00:00:00 2001 From: Anna Antipina Date: Mon, 14 Aug 2023 19:10:33 +0300 Subject: [PATCH] Initialize frame-allocator region with iframe stack size to be able to throw only one exception when initializing the frame (only StackOverFlow, not OutOfMemory) Signed-off-by: Anna Antipina --- runtime/interpreter/ecma-interpreter-inl.h | 30 +++++++++++++--------- runtime/interpreter/js_frame-inl.h | 3 +++ runtime/js_thread.cpp | 13 ++++++++++ runtime/js_thread.h | 3 +++ 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/runtime/interpreter/ecma-interpreter-inl.h b/runtime/interpreter/ecma-interpreter-inl.h index be6c0ae1f..0b488acb9 100644 --- a/runtime/interpreter/ecma-interpreter-inl.h +++ b/runtime/interpreter/ecma-interpreter-inl.h @@ -562,18 +562,24 @@ public: Frame *frame = JSFrame::CreateNativeFrame(thread, method, thread->GetCurrentFrame(), num_args, num_actual_args); - JSCopyArgumets(this->GetJSThread(), prev_frame, ctor.GetRawData(), - prev_inst, frame, 0, num_actual_args); - frame->GetVReg(0 + js_method_args::THIS_IDX).SetValue(JSTaggedValue::VALUE_UNDEFINED); - - // Call native method - thread->SetCurrentFrame(frame); - JSTaggedValue ret_value = JSFrame::ExecuteNativeMethod(thread, frame, method, num_actual_args); - ASSERT(thread->GetCurrentFrame() == frame); - thread->SetCurrentFrameIsCompiled(false); - thread->SetCurrentFrame(prev_frame); - - JSFrame::DestroyNativeFrame(thread, frame); + JSTaggedValue ret_value; + if (UNLIKELY(frame == nullptr)) { + ret_value = JSTaggedValue::Exception(); + } else { + JSCopyArgumets(this->GetJSThread(), prev_frame, ctor.GetRawData(), + prev_inst, frame, 0, num_actual_args); + frame->GetVReg(0 + js_method_args::THIS_IDX).SetValue(JSTaggedValue::VALUE_UNDEFINED); + + // Call native method + thread->SetCurrentFrame(frame); + ret_value = JSFrame::ExecuteNativeMethod(thread, frame, method, num_actual_args); + + ASSERT(thread->GetCurrentFrame() == frame); + thread->SetCurrentFrameIsCompiled(false); + thread->SetCurrentFrame(prev_frame); + JSFrame::DestroyNativeFrame(thread, frame); + } + if (UNLIKELY(thread->HasPendingException())) { this->MoveToExceptionHandler(); return; diff --git a/runtime/interpreter/js_frame-inl.h b/runtime/interpreter/js_frame-inl.h index d513663a0..3f529b5e3 100644 --- a/runtime/interpreter/js_frame-inl.h +++ b/runtime/interpreter/js_frame-inl.h @@ -20,6 +20,9 @@ inline Frame *JSFrame::CreateNativeFrame(JSThread *js_thread, Method *method, Fr Frame *new_frame = CreateFrame(js_thread->GetStackFrameAllocator(), nregs, method, prev_frame, nregs, num_actual_args); + if (UNLIKELY(new_frame == nullptr)) { + return nullptr; + } LOG_IF(new_frame == nullptr, FATAL, ECMASCRIPT) << "Cannot allocate native frame"; new_frame->SetInvoke(); new_frame->SetDynamic(); diff --git a/runtime/js_thread.cpp b/runtime/js_thread.cpp index 415753971..9101caa20 100644 --- a/runtime/js_thread.cpp +++ b/runtime/js_thread.cpp @@ -216,4 +216,17 @@ void JSThread::ResetGuardians() { stable_array_elements_guardians_ = true; } + +void JSThread::DisableStackOverflowCheck() +{ + GetStackFrameAllocator()->UseWholeMemory(); + ManagedThread::DisableStackOverflowCheck(); +} + +void JSThread::EnableStackOverflowCheck() +{ + GetStackFrameAllocator()->ReserveMemory(); + ManagedThread::EnableStackOverflowCheck(); +} + } // namespace panda::ecmascript diff --git a/runtime/js_thread.h b/runtime/js_thread.h index 552bc97fd..4e334bee0 100644 --- a/runtime/js_thread.h +++ b/runtime/js_thread.h @@ -231,6 +231,9 @@ public: return global_obj_; } + void DisableStackOverflowCheck() override; + void EnableStackOverflowCheck() override; + private: void IterateEcmascriptEnvironment(const RootVisitor &v0, const RootRangeVisitor &v1); -- Gitee