diff --git a/src/env.cc b/src/env.cc index 4c9b0a25e56da9..9566ceb098b262 100644 --- a/src/env.cc +++ b/src/env.cc @@ -162,14 +162,17 @@ bool AsyncHooks::pop_async_context(double async_id) { } void AsyncHooks::clear_async_id_stack() { - Isolate* isolate = env()->isolate(); - HandleScope handle_scope(isolate); - if (!js_execution_async_resources_.IsEmpty()) { - USE(PersistentToLocal::Strong(js_execution_async_resources_) - ->Set(env()->context(), - env()->length_string(), - Integer::NewFromUnsigned(isolate, 0))); + if (env()->can_call_into_js()) { + Isolate* isolate = env()->isolate(); + HandleScope handle_scope(isolate); + if (!js_execution_async_resources_.IsEmpty()) { + USE(PersistentToLocal::Strong(js_execution_async_resources_) + ->Set(env()->context(), + env()->length_string(), + Integer::NewFromUnsigned(isolate, 0))); + } } + native_execution_async_resources_.clear(); native_execution_async_resources_.shrink_to_fit(); @@ -1157,7 +1160,13 @@ void Environment::RunAndClearNativeImmediates(bool only_refed) { TRACE_EVENT0(TRACING_CATEGORY_NODE1(environment), "RunAndClearNativeImmediates"); HandleScope handle_scope(isolate_); - InternalCallbackScope cb_scope(this, Object::New(isolate_), { 0, 0 }); + // In case the Isolate is no longer accessible just use an empty Local. This + // is not an issue for InternalCallbackScope as this case is already handled + // in its constructor but we avoid calls into v8 which can crash the process + // in debug builds. + Local obj = + can_call_into_js() ? Object::New(isolate_) : Local(); + InternalCallbackScope cb_scope(this, obj, {0, 0}); size_t ref_count = 0; diff --git a/src/node_http2.cc b/src/node_http2.cc index 8df924a29028e2..aaabfa11aae5d6 100644 --- a/src/node_http2.cc +++ b/src/node_http2.cc @@ -1120,13 +1120,14 @@ int Http2Session::OnStreamClose(nghttp2_session* handle, // It is possible for the stream close to occur before the stream is // ever passed on to the javascript side. If that happens, the callback // will return false. - Local arg = Integer::NewFromUnsigned(isolate, code); - MaybeLocal answer = - stream->MakeCallback(env->http2session_on_stream_close_function(), - 1, &arg); - if (answer.IsEmpty() || answer.ToLocalChecked()->IsFalse()) { - // Skip to destroy - stream->Destroy(); + if (env->can_call_into_js()) { + Local arg = Integer::NewFromUnsigned(isolate, code); + MaybeLocal answer = stream->MakeCallback( + env->http2session_on_stream_close_function(), 1, &arg); + if (answer.IsEmpty() || answer.ToLocalChecked()->IsFalse()) { + // Skip to destroy + stream->Destroy(); + } } return 0; } @@ -1629,9 +1630,11 @@ void Http2Session::MaybeScheduleWrite() { // Sending data may call arbitrary JS code, so keep track of // async context. - HandleScope handle_scope(env->isolate()); - InternalCallbackScope callback_scope(this); - SendPendingData(); + if (env->can_call_into_js()) { + HandleScope handle_scope(env->isolate()); + InternalCallbackScope callback_scope(this); + SendPendingData(); + } }); } } diff --git a/src/node_platform.cc b/src/node_platform.cc index eb918bdd559c40..c63c53943db6a1 100644 --- a/src/node_platform.cc +++ b/src/node_platform.cc @@ -401,6 +401,7 @@ int NodePlatform::NumberOfWorkerThreads() { } void PerIsolatePlatformData::RunForegroundTask(std::unique_ptr task) { + if (isolate_->IsExecutionTerminating()) return task->Run(); DebugSealHandleScope scope(isolate_); Environment* env = Environment::GetCurrent(isolate_); if (env != nullptr) {