diff options
author | Gabriel Schulhof <gabriel.schulhof@intel.com> | 2017-07-13 11:35:55 +0300 |
---|---|---|
committer | Timothy Gu <timothygu99@gmail.com> | 2017-07-27 07:55:48 +0800 |
commit | 9926dfebc88c22a1a9bdef55f7530c74124f63aa (patch) | |
tree | 8bb372ceb8146e1e860181b05f876229b01e4971 /src/node_api.cc | |
parent | 012206e92dafa216d4082c5991d5599dc504cb50 (diff) | |
download | android-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.cc | 45 |
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, |