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