@@ -707,6 +707,45 @@ bool FindWrapper(v8::Local<v8::Object> obj,
707
707
return true ;
708
708
}
709
709
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
+
710
749
} // end of namespace v8impl
711
750
712
751
// Intercepts the Node-V8 module registration callback. Converts parameters
@@ -718,9 +757,9 @@ void napi_module_register_cb(v8::Local<v8::Object> exports,
718
757
void * priv) {
719
758
napi_module* mod = static_cast <napi_module*>(priv);
720
759
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);
724
763
725
764
mod->nm_register_func (
726
765
env,
0 commit comments