summaryrefslogtreecommitdiff
path: root/src/node_api.cc
diff options
context:
space:
mode:
authorGabriel Schulhof <gabriel.schulhof@intel.com>2017-07-13 11:35:55 +0300
committerTimothy Gu <timothygu99@gmail.com>2017-07-27 07:55:48 +0800
commit9926dfebc88c22a1a9bdef55f7530c74124f63aa (patch)
tree8bb372ceb8146e1e860181b05f876229b01e4971 /src/node_api.cc
parent012206e92dafa216d4082c5991d5599dc504cb50 (diff)
downloadandroid-node-v8-9926dfebc88c22a1a9bdef55f7530c74124f63aa.tar.gz
android-node-v8-9926dfebc88c22a1a9bdef55f7530c74124f63aa.tar.bz2
android-node-v8-9926dfebc88c22a1a9bdef55f7530c74124f63aa.zip
n-api: re-use napi_env between modules
Store the `napi_env` on the global object at a private key. This gives us one `napi_env` per context. Refs: https://github.com/nodejs/node/issues/14367 PR-URL: https://github.com/nodejs/node/pull/14217 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Timothy Gu <timothygu99@gmail.com>
Diffstat (limited to 'src/node_api.cc')
-rw-r--r--src/node_api.cc45
1 files changed, 42 insertions, 3 deletions
diff --git a/src/node_api.cc b/src/node_api.cc
index 59bac3a9c1..7a0332848b 100644
--- a/src/node_api.cc
+++ b/src/node_api.cc
@@ -707,6 +707,45 @@ bool FindWrapper(v8::Local<v8::Object> obj,
return true;
}
+static void DeleteEnv(napi_env env, void* data, void* hint) {
+ delete env;
+}
+
+napi_env GetEnv(v8::Local<v8::Context> context) {
+ napi_env result;
+
+ auto isolate = context->GetIsolate();
+ auto global = context->Global();
+
+ // In the case of the string for which we grab the private and the value of
+ // the private on the global object we can call .ToLocalChecked() directly
+ // because we need to stop hard if either of them is empty.
+ //
+ // Re https://github.com/nodejs/node/pull/14217#discussion_r128775149
+ auto key = v8::Private::ForApi(isolate,
+ v8::String::NewFromOneByte(isolate,
+ reinterpret_cast<const uint8_t*>("N-API Environment"),
+ v8::NewStringType::kInternalized).ToLocalChecked());
+ auto value = global->GetPrivate(context, key).ToLocalChecked();
+
+ if (value->IsExternal()) {
+ result = static_cast<napi_env>(value.As<v8::External>()->Value());
+ } else {
+ result = new napi_env__(isolate);
+ auto external = v8::External::New(isolate, result);
+
+ // We must also stop hard if the result of assigning the env to the global
+ // is either nothing or false.
+ CHECK(global->SetPrivate(context, key, external).FromJust());
+
+ // Create a self-destructing reference to external that will get rid of the
+ // napi_env when external goes out of scope.
+ Reference::New(result, external, 0, true, DeleteEnv, nullptr, nullptr);
+ }
+
+ return result;
+}
+
} // end of namespace v8impl
// Intercepts the Node-V8 module registration callback. Converts parameters
@@ -718,9 +757,9 @@ void napi_module_register_cb(v8::Local<v8::Object> exports,
void* priv) {
napi_module* mod = static_cast<napi_module*>(priv);
- // Create a new napi_env for this module. Once module unloading is supported
- // we shall have to call delete on this object from there.
- napi_env env = new napi_env__(context->GetIsolate());
+ // Create a new napi_env for this module or reference one if a pre-existing
+ // one is found.
+ napi_env env = v8impl::GetEnv(context);
mod->nm_register_func(
env,