mirror of
https://github.com/nodejs/node.git
synced 2024-12-01 16:10:02 +01:00
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__ {
|
||||
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__() {
|
||||
last_exception.Reset();
|
||||
has_instance.Reset();
|
||||
}
|
||||
v8::Isolate* isolate;
|
||||
v8::Persistent<v8::Value> last_exception;
|
||||
v8::Persistent<v8::Value> has_instance;
|
||||
bool has_instance_available;
|
||||
napi_extended_error_info last_error;
|
||||
};
|
||||
|
||||
@ -2156,28 +2160,43 @@ napi_status napi_instanceof(napi_env env,
|
||||
return napi_set_last_error(env, napi_function_expected);
|
||||
}
|
||||
|
||||
napi_value value, js_result;
|
||||
napi_status status;
|
||||
napi_valuetype value_type;
|
||||
if (env->has_instance_available) {
|
||||
napi_value value, js_result, has_instance = nullptr;
|
||||
napi_status status;
|
||||
napi_valuetype value_type;
|
||||
|
||||
// Get "Symbol" from the global object
|
||||
status = napi_get_global(env, &value);
|
||||
if (status != napi_ok) return status;
|
||||
status = napi_get_named_property(env, value, "Symbol", &value);
|
||||
if (status != napi_ok) return status;
|
||||
status = napi_typeof(env, value, &value_type);
|
||||
if (status != napi_ok) return status;
|
||||
// Get "Symbol" from the global object
|
||||
if (env->has_instance.IsEmpty()) {
|
||||
status = napi_get_global(env, &value);
|
||||
if (status != napi_ok) return status;
|
||||
status = napi_get_named_property(env, value, "Symbol", &value);
|
||||
if (status != napi_ok) return status;
|
||||
status = napi_typeof(env, value, &value_type);
|
||||
if (status != napi_ok) return status;
|
||||
|
||||
// Get "hasInstance" from Symbol
|
||||
if (value_type == napi_function) {
|
||||
status = napi_get_named_property(env, value, "hasInstance", &value);
|
||||
if (status != napi_ok) return status;
|
||||
status = napi_typeof(env, value, &value_type);
|
||||
if (status != napi_ok) return status;
|
||||
// Get "hasInstance" from Symbol
|
||||
if (value_type == napi_function) {
|
||||
status = napi_get_named_property(env, value, "hasInstance", &value);
|
||||
if (status != napi_ok) return status;
|
||||
status = napi_typeof(env, value, &value_type);
|
||||
if (status != napi_ok) return status;
|
||||
|
||||
// Retrieve the function at the Symbol(hasInstance) key of the constructor
|
||||
if (value_type == napi_symbol) {
|
||||
status = napi_get_property(env, constructor, value, &value);
|
||||
// Store Symbol.hasInstance in a global persistent reference
|
||||
if (value_type == napi_symbol) {
|
||||
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;
|
||||
status = napi_typeof(env, value, &value_type);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
env->has_instance_available = false;
|
||||
}
|
||||
|
||||
// If running constructor[Symbol.hasInstance](object) did not work, we perform
|
||||
|
Loading…
Reference in New Issue
Block a user