n-api: cache Symbol.hasInstance
This improves the performance of napi_instanceof() by retrieving Symbol.hasInstance from the global object once and then storing a persistent reference to it in the env. PR-URL: https://github.com/nodejs/node/pull/12246 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
This commit is contained in:
parent
ca8ccb9176
commit
8fbace163a
@ -23,12 +23,16 @@ void napi_clear_last_error(napi_env env);
|
|||||||
|
|
||||||
class napi_env__ {
|
class napi_env__ {
|
||||||
public:
|
public:
|
||||||
explicit napi_env__(v8::Isolate* _isolate): isolate(_isolate), last_error() {}
|
explicit napi_env__(v8::Isolate* _isolate): isolate(_isolate),
|
||||||
|
has_instance_available(true), last_error() {}
|
||||||
~napi_env__() {
|
~napi_env__() {
|
||||||
last_exception.Reset();
|
last_exception.Reset();
|
||||||
|
has_instance.Reset();
|
||||||
}
|
}
|
||||||
v8::Isolate* isolate;
|
v8::Isolate* isolate;
|
||||||
v8::Persistent<v8::Value> last_exception;
|
v8::Persistent<v8::Value> last_exception;
|
||||||
|
v8::Persistent<v8::Value> has_instance;
|
||||||
|
bool has_instance_available;
|
||||||
napi_extended_error_info last_error;
|
napi_extended_error_info last_error;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2156,11 +2160,13 @@ napi_status napi_instanceof(napi_env env,
|
|||||||
return napi_set_last_error(env, napi_function_expected);
|
return napi_set_last_error(env, napi_function_expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
napi_value value, js_result;
|
if (env->has_instance_available) {
|
||||||
|
napi_value value, js_result, has_instance = nullptr;
|
||||||
napi_status status;
|
napi_status status;
|
||||||
napi_valuetype value_type;
|
napi_valuetype value_type;
|
||||||
|
|
||||||
// Get "Symbol" from the global object
|
// Get "Symbol" from the global object
|
||||||
|
if (env->has_instance.IsEmpty()) {
|
||||||
status = napi_get_global(env, &value);
|
status = napi_get_global(env, &value);
|
||||||
if (status != napi_ok) return status;
|
if (status != napi_ok) return status;
|
||||||
status = napi_get_named_property(env, value, "Symbol", &value);
|
status = napi_get_named_property(env, value, "Symbol", &value);
|
||||||
@ -2175,9 +2181,22 @@ napi_status napi_instanceof(napi_env env,
|
|||||||
status = napi_typeof(env, value, &value_type);
|
status = napi_typeof(env, value, &value_type);
|
||||||
if (status != napi_ok) return status;
|
if (status != napi_ok) return status;
|
||||||
|
|
||||||
// Retrieve the function at the Symbol(hasInstance) key of the constructor
|
// Store Symbol.hasInstance in a global persistent reference
|
||||||
if (value_type == napi_symbol) {
|
if (value_type == napi_symbol) {
|
||||||
status = napi_get_property(env, constructor, value, &value);
|
env->has_instance.Reset(env->isolate,
|
||||||
|
v8impl::V8LocalValueFromJsValue(value));
|
||||||
|
if (status != napi_ok) return status;
|
||||||
|
has_instance = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
has_instance = v8impl::JsValueFromV8LocalValue(
|
||||||
|
v8::Local<v8::Value>::New(env->isolate, env->has_instance));
|
||||||
|
if (status != napi_ok) return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_instance) {
|
||||||
|
status = napi_get_property(env, constructor, has_instance, &value);
|
||||||
if (status != napi_ok) return status;
|
if (status != napi_ok) return status;
|
||||||
status = napi_typeof(env, value, &value_type);
|
status = napi_typeof(env, value, &value_type);
|
||||||
if (status != napi_ok) return status;
|
if (status != napi_ok) return status;
|
||||||
@ -2191,6 +2210,8 @@ napi_status napi_instanceof(napi_env env,
|
|||||||
return napi_get_value_bool(env, js_result, result);
|
return napi_get_value_bool(env, js_result, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
env->has_instance_available = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If running constructor[Symbol.hasInstance](object) did not work, we perform
|
// If running constructor[Symbol.hasInstance](object) did not work, we perform
|
||||||
|
Loading…
x
Reference in New Issue
Block a user