diff --git a/src/env.h b/src/env.h index 73940ad0d483fc..cad03c45310467 100644 --- a/src/env.h +++ b/src/env.h @@ -474,6 +474,8 @@ class Environment { inline HandleWrapQueue* handle_wrap_queue() { return &handle_wrap_queue_; } inline ReqWrapQueue* req_wrap_queue() { return &req_wrap_queue_; } + static const int kContextEmbedderDataIndex = NODE_CONTEXT_EMBEDDER_DATA_INDEX; + private: static const int kIsolateSlot = NODE_ISOLATE_SLOT; @@ -482,10 +484,6 @@ class Environment { inline ~Environment(); inline IsolateData* isolate_data() const; - enum ContextEmbedderDataIndex { - kContextEmbedderDataIndex = NODE_CONTEXT_EMBEDDER_DATA_INDEX - }; - v8::Isolate* const isolate_; IsolateData* const isolate_data_; uv_check_t immediate_check_handle_; diff --git a/src/node_contextify.cc b/src/node_contextify.cc index 6985a33982d749..81d0388a35f390 100644 --- a/src/node_contextify.cc +++ b/src/node_contextify.cc @@ -233,10 +233,32 @@ class ContextifyContext { static void RunInDebugContext(const FunctionCallbackInfo& args) { + // Ensure that the debug context has an Environment assigned in case + // a fatal error is raised. The fatal exception handler in node.cc + // is not equipped to deal with contexts that don't have one and + // can't easily be taught that due to a deficiency in the V8 API: + // there is no way for the embedder to tell if the data index is + // in use. + struct ScopedEnvironment { + ScopedEnvironment(Local context, Environment* env) + : context_(context) { + const int index = Environment::kContextEmbedderDataIndex; + context->SetAlignedPointerInEmbedderData(index, env); + } + ~ScopedEnvironment() { + const int index = Environment::kContextEmbedderDataIndex; + context_->SetAlignedPointerInEmbedderData(index, nullptr); + } + Local context_; + }; + Local script_source(args[0]->ToString(args.GetIsolate())); if (script_source.IsEmpty()) return; // Exception pending. - Context::Scope context_scope(Debug::GetDebugContext()); + Local debug_context = Debug::GetDebugContext(); + Environment* env = Environment::GetCurrent(args); + ScopedEnvironment env_scope(debug_context, env); + Context::Scope context_scope(debug_context); Local