mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
N-API: Reuse ObjectTemplate instances
V8 caches and does not subsequently release `ObjectTemplate` instances. Thus, we need to store the `ObjectTemplate` from which we derive object instances we use for `napi_wrap()` and function/accessor context in a persistent in the `napi_env`. https://github.com/nodejs/node-addon-api/pull/70#discussion_r124998408 PR-URL: https://github.com/nodejs/node/pull/13999 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.co> Reviewed-By: Hitesh Kanwathirtha <digitalinfinity@gmail.com>
This commit is contained in:
committed by
Michael Dawson
parent
f651e40350
commit
29df1a87fa
@@ -34,14 +34,32 @@ struct napi_env__ {
|
||||
~napi_env__() {
|
||||
last_exception.Reset();
|
||||
has_instance.Reset();
|
||||
wrap_template.Reset();
|
||||
function_data_template.Reset();
|
||||
accessor_data_template.Reset();
|
||||
}
|
||||
v8::Isolate* isolate;
|
||||
v8::Persistent<v8::Value> last_exception;
|
||||
v8::Persistent<v8::Value> has_instance;
|
||||
v8::Persistent<v8::ObjectTemplate> wrap_template;
|
||||
v8::Persistent<v8::ObjectTemplate> function_data_template;
|
||||
v8::Persistent<v8::ObjectTemplate> accessor_data_template;
|
||||
bool has_instance_available;
|
||||
napi_extended_error_info last_error;
|
||||
};
|
||||
|
||||
#define ENV_OBJECT_TEMPLATE(env, prefix, destination, field_count) \
|
||||
do { \
|
||||
if ((env)->prefix ## _template.IsEmpty()) { \
|
||||
(destination) = v8::ObjectTemplate::New(isolate); \
|
||||
(destination)->SetInternalFieldCount((field_count)); \
|
||||
(env)->prefix ## _template.Reset(isolate, (destination)); \
|
||||
} else { \
|
||||
(destination) = env->prefix ## _template.Get(isolate); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define RETURN_STATUS_IF_FALSE(env, condition, status) \
|
||||
do { \
|
||||
if (!(condition)) { \
|
||||
@@ -603,8 +621,8 @@ v8::Local<v8::Object> CreateFunctionCallbackData(napi_env env,
|
||||
v8::Isolate* isolate = env->isolate;
|
||||
v8::Local<v8::Context> context = isolate->GetCurrentContext();
|
||||
|
||||
v8::Local<v8::ObjectTemplate> otpl = v8::ObjectTemplate::New(isolate);
|
||||
otpl->SetInternalFieldCount(v8impl::kFunctionFieldCount);
|
||||
v8::Local<v8::ObjectTemplate> otpl;
|
||||
ENV_OBJECT_TEMPLATE(env, function_data, otpl, v8impl::kFunctionFieldCount);
|
||||
v8::Local<v8::Object> cbdata = otpl->NewInstance(context).ToLocalChecked();
|
||||
|
||||
cbdata->SetInternalField(
|
||||
@@ -629,8 +647,8 @@ v8::Local<v8::Object> CreateAccessorCallbackData(napi_env env,
|
||||
v8::Isolate* isolate = env->isolate;
|
||||
v8::Local<v8::Context> context = isolate->GetCurrentContext();
|
||||
|
||||
v8::Local<v8::ObjectTemplate> otpl = v8::ObjectTemplate::New(isolate);
|
||||
otpl->SetInternalFieldCount(v8impl::kAccessorFieldCount);
|
||||
v8::Local<v8::ObjectTemplate> otpl;
|
||||
ENV_OBJECT_TEMPLATE(env, accessor_data, otpl, v8impl::kAccessorFieldCount);
|
||||
v8::Local<v8::Object> cbdata = otpl->NewInstance(context).ToLocalChecked();
|
||||
|
||||
cbdata->SetInternalField(
|
||||
@@ -2008,11 +2026,10 @@ napi_status napi_wrap(napi_env env,
|
||||
v8::Local<v8::Object> obj = value.As<v8::Object>();
|
||||
|
||||
// Create a wrapper object with an internal field to hold the wrapped pointer.
|
||||
v8::Local<v8::ObjectTemplate> wrapperTemplate =
|
||||
v8::ObjectTemplate::New(isolate);
|
||||
wrapperTemplate->SetInternalFieldCount(1);
|
||||
v8::Local<v8::ObjectTemplate> wrapper_template;
|
||||
ENV_OBJECT_TEMPLATE(env, wrap, wrapper_template, 1);
|
||||
v8::Local<v8::Object> wrapper =
|
||||
wrapperTemplate->NewInstance(context).ToLocalChecked();
|
||||
wrapper_template->NewInstance(context).ToLocalChecked();
|
||||
wrapper->SetInternalField(0, v8::External::New(isolate, native_object));
|
||||
|
||||
// Insert the wrapper into the object's prototype chain.
|
||||
|
||||
Reference in New Issue
Block a user