@@ -706,6 +706,45 @@ bool FindWrapper(v8::Local<v8::Object> obj,
706706 return true ;
707707}
708708
709+ static void DeleteEnv (napi_env env, void * data, void * hint) {
710+ delete env;
711+ }
712+
713+ napi_env GetEnv (v8::Local<v8::Context> context) {
714+ napi_env result;
715+
716+ auto isolate = context->GetIsolate ();
717+ auto global = context->Global ();
718+
719+ // In the case of the string for which we grab the private and the value of
720+ // the private on the global object we can call .ToLocalChecked() directly
721+ // because we need to stop hard if either of them is empty.
722+ //
723+ // Re https://github.com/nodejs/node/pull/14217#discussion_r128775149
724+ auto key = v8::Private::ForApi (isolate,
725+ v8::String::NewFromOneByte (isolate,
726+ reinterpret_cast <const uint8_t *>(" N-API Environment" ),
727+ v8::NewStringType::kInternalized ).ToLocalChecked ());
728+ auto value = global->GetPrivate (context, key).ToLocalChecked ();
729+
730+ if (value->IsExternal ()) {
731+ result = static_cast <napi_env>(value.As <v8::External>()->Value ());
732+ } else {
733+ result = new napi_env__ (isolate);
734+ auto external = v8::External::New (isolate, result);
735+
736+ // We must also stop hard if the result of assigning the env to the global
737+ // is either nothing or false.
738+ CHECK (global->SetPrivate (context, key, external).FromJust ());
739+
740+ // Create a self-destructing reference to external that will get rid of the
741+ // napi_env when external goes out of scope.
742+ Reference::New (result, external, 0 , true , DeleteEnv, nullptr , nullptr );
743+ }
744+
745+ return result;
746+ }
747+
709748} // end of namespace v8impl
710749
711750// Intercepts the Node-V8 module registration callback. Converts parameters
@@ -717,9 +756,9 @@ void napi_module_register_cb(v8::Local<v8::Object> exports,
717756 void * priv) {
718757 napi_module* mod = static_cast <napi_module*>(priv);
719758
720- // Create a new napi_env for this module. Once module unloading is supported
721- // we shall have to call delete on this object from there .
722- napi_env env = new napi_env__ (context-> GetIsolate () );
759+ // Create a new napi_env for this module or reference one if a pre-existing
760+ // one is found .
761+ napi_env env = v8impl::GetEnv (context);
723762
724763 mod->nm_register_func (
725764 env,
0 commit comments