summaryrefslogtreecommitdiff
path: root/src/node_api.cc
diff options
context:
space:
mode:
authorYang Guo <yangguo@chromium.org>2017-10-11 11:55:40 +0200
committerFranziska Hinkelmann <franziska.hinkelmann@gmail.com>2017-10-16 09:25:41 +0200
commitc81fd7c5ea94685d6aaf175f24a547b3e95b5089 (patch)
tree5f3af204d07fa410b03c0f917d2fe3e7e185e272 /src/node_api.cc
parent7832e69eafb524dd1f022d3b37c7442179b0c7c7 (diff)
downloadandroid-node-v8-c81fd7c5ea94685d6aaf175f24a547b3e95b5089.tar.gz
android-node-v8-c81fd7c5ea94685d6aaf175f24a547b3e95b5089.tar.bz2
android-node-v8-c81fd7c5ea94685d6aaf175f24a547b3e95b5089.zip
n-api: reimplement instanceof using V8 API
This uses the v8::Value::InstanceOf API exposed in V8 6.0 and should be performance neutral, if not improve it. By using V8's API, there is no longer the need to cache Symbol.hasInstance. PR-URL: https://github.com/nodejs/node/pull/16143 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com> Reviewed-By: Timothy Gu <timothygu99@gmail.com>
Diffstat (limited to 'src/node_api.cc')
-rw-r--r--src/node_api.cc101
1 files changed, 6 insertions, 95 deletions
diff --git a/src/node_api.cc b/src/node_api.cc
index 5728ccc6b9..ea9bcfb980 100644
--- a/src/node_api.cc
+++ b/src/node_api.cc
@@ -29,21 +29,18 @@ napi_status napi_clear_last_error(napi_env env);
struct napi_env__ {
explicit napi_env__(v8::Isolate* _isolate): isolate(_isolate),
- has_instance_available(true), last_error() {}
+ last_error() {}
~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;
};
@@ -2693,98 +2690,12 @@ napi_status napi_instanceof(napi_env env,
return napi_set_last_error(env, napi_function_expected);
}
- if (env->has_instance_available) {
- napi_value value, js_result = nullptr, has_instance = nullptr;
- napi_status status = napi_generic_failure;
- napi_valuetype value_type;
-
- // 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;
-
- // Store Symbol.hasInstance in a global persistent reference
- if (value_type == napi_symbol) {
- env->has_instance.Reset(env->isolate,
- v8impl::V8LocalValueFromJsValue(value));
- has_instance = value;
- }
- }
- } else {
- has_instance = v8impl::JsValueFromV8LocalValue(
- v8::Local<v8::Value>::New(env->isolate, env->has_instance));
- }
-
- 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;
-
- // Call the function to determine whether the object is an instance of the
- // constructor
- if (value_type == napi_function) {
- status = napi_call_function(env, constructor, value, 1, &object,
- &js_result);
- if (status != napi_ok) return status;
- 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
- // a traditional instanceof (early Node.js 6.x).
-
- v8::Local<v8::String> prototype_string;
- CHECK_NEW_FROM_UTF8(env, prototype_string, "prototype");
-
- auto maybe_prototype = ctor->Get(context, prototype_string);
- CHECK_MAYBE_EMPTY(env, maybe_prototype, napi_generic_failure);
-
- v8::Local<v8::Value> prototype_property = maybe_prototype.ToLocalChecked();
- if (!prototype_property->IsObject()) {
- napi_throw_type_error(
- env,
- "ERR_NAPI_CONS_PROTOTYPE_OBJECT",
- "Constructor.prototype must be an object");
-
- return napi_set_last_error(env, napi_object_expected);
- }
-
- auto maybe_ctor = prototype_property->ToObject(context);
- CHECK_MAYBE_EMPTY(env, maybe_ctor, napi_generic_failure);
- ctor = maybe_ctor.ToLocalChecked();
-
- v8::Local<v8::Value> current_obj = v8impl::V8LocalValueFromJsValue(object);
- if (!current_obj->StrictEquals(ctor)) {
- for (v8::Local<v8::Value> original_obj = current_obj;
- !(current_obj->IsNull() || current_obj->IsUndefined());) {
- if (current_obj->StrictEquals(ctor)) {
- *result = !(original_obj->IsNumber() ||
- original_obj->IsBoolean() ||
- original_obj->IsString());
- break;
- }
- v8::Local<v8::Object> obj;
- CHECK_TO_OBJECT(env, context, obj, v8impl::JsValueFromV8LocalValue(
- current_obj));
- current_obj = obj->GetPrototype();
- }
- }
+ napi_status status = napi_generic_failure;
+ v8::Local<v8::Value> val = v8impl::V8LocalValueFromJsValue(object);
+ auto maybe_result = val->InstanceOf(context, ctor);
+ CHECK_MAYBE_NOTHING(env, maybe_result, status);
+ *result = maybe_result.FromJust();
return GET_RETURN_STATUS(env);
}