Commit 768c5e21 authored by yangguo's avatar yangguo Committed by Commit bot

[api] Expose instanceof through v8::Value::InstanceOf.

This is requested for Node.js N-API. Tests to be added.

Review-Url: https://codereview.chromium.org/2812613002
Cr-Commit-Position: refs/heads/master@{#44641}
parent 4433ac29
......@@ -2317,6 +2317,8 @@ class V8_EXPORT Value : public Data {
Local<String> TypeOf(Isolate*);
Maybe<bool> InstanceOf(Local<Context> context, Local<Object> object);
private:
V8_INLINE bool QuickIsUndefined() const;
V8_INLINE bool QuickIsNull() const;
......
......@@ -4181,6 +4181,18 @@ Local<String> Value::TypeOf(v8::Isolate* external_isolate) {
return Utils::ToLocal(i::Object::TypeOf(isolate, Utils::OpenHandle(this)));
}
Maybe<bool> Value::InstanceOf(v8::Local<v8::Context> context,
v8::Local<v8::Object> object) {
PREPARE_FOR_EXECUTION_PRIMITIVE(context, Value, InstanceOf, bool);
auto left = Utils::OpenHandle(this);
auto right = Utils::OpenHandle(*object);
i::Handle<i::Object> result;
has_pending_exception =
!i::Object::InstanceOf(isolate, left, right).ToHandle(&result);
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
return Just(result->IsTrue(isolate));
}
Maybe<bool> v8::Object::Set(v8::Local<v8::Context> context,
v8::Local<Value> key, v8::Local<Value> value) {
PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, Set, bool);
......@@ -5374,7 +5386,6 @@ Local<v8::Value> Function::GetBoundFunction() const {
return v8::Undefined(reinterpret_cast<v8::Isolate*>(self->GetIsolate()));
}
int Name::GetIdentityHash() {
auto self = Utils::OpenHandle(this);
return static_cast<int>(self->Hash());
......
......@@ -679,6 +679,7 @@ class RuntimeCallTimer final {
V(UnboundScript_GetName) \
V(UnboundScript_GetSourceMappingURL) \
V(UnboundScript_GetSourceURL) \
V(Value_InstanceOf) \
V(Value_TypeOf) \
V(ValueDeserializer_ReadHeader) \
V(ValueDeserializer_ReadValue) \
......
......@@ -6224,6 +6224,63 @@ THREADED_TEST(TypeOf) {
.FromJust());
}
THREADED_TEST(InstanceOf) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
CompileRun(
"var A = {};"
"var B = {};"
"var C = {};"
"B.__proto__ = A;"
"C.__proto__ = B;"
"function F() {}"
"F.prototype = A;"
"var G = { [Symbol.hasInstance] : null};"
"var H = { [Symbol.hasInstance] : () => { throw new Error(); } };"
"var J = { [Symbol.hasInstance] : () => true };"
"class K {}"
"var D = new K;"
"class L extends K {}"
"var E = new L");
v8::Local<v8::Object> f = v8::Local<v8::Object>::Cast(CompileRun("F"));
v8::Local<v8::Object> g = v8::Local<v8::Object>::Cast(CompileRun("G"));
v8::Local<v8::Object> h = v8::Local<v8::Object>::Cast(CompileRun("H"));
v8::Local<v8::Object> j = v8::Local<v8::Object>::Cast(CompileRun("J"));
v8::Local<v8::Object> k = v8::Local<v8::Object>::Cast(CompileRun("K"));
v8::Local<v8::Object> l = v8::Local<v8::Object>::Cast(CompileRun("L"));
v8::Local<v8::Value> a = v8::Local<v8::Value>::Cast(CompileRun("A"));
v8::Local<v8::Value> b = v8::Local<v8::Value>::Cast(CompileRun("B"));
v8::Local<v8::Value> c = v8::Local<v8::Value>::Cast(CompileRun("C"));
v8::Local<v8::Value> d = v8::Local<v8::Value>::Cast(CompileRun("D"));
v8::Local<v8::Value> e = v8::Local<v8::Value>::Cast(CompileRun("E"));
v8::TryCatch try_catch(env->GetIsolate());
CHECK(!a->InstanceOf(env.local(), f).ToChecked());
CHECK(b->InstanceOf(env.local(), f).ToChecked());
CHECK(c->InstanceOf(env.local(), f).ToChecked());
CHECK(!d->InstanceOf(env.local(), f).ToChecked());
CHECK(!e->InstanceOf(env.local(), f).ToChecked());
CHECK(!try_catch.HasCaught());
CHECK(a->InstanceOf(env.local(), g).IsNothing());
CHECK(try_catch.HasCaught());
try_catch.Reset();
CHECK(b->InstanceOf(env.local(), h).IsNothing());
CHECK(try_catch.HasCaught());
try_catch.Reset();
CHECK(v8_num(1)->InstanceOf(env.local(), j).ToChecked());
CHECK(!try_catch.HasCaught());
CHECK(d->InstanceOf(env.local(), k).ToChecked());
CHECK(e->InstanceOf(env.local(), k).ToChecked());
CHECK(!d->InstanceOf(env.local(), l).ToChecked());
CHECK(e->InstanceOf(env.local(), l).ToChecked());
CHECK(!try_catch.HasCaught());
}
THREADED_TEST(MultiRun) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment