Index: src/runtime/runtime-object.cc |
diff --git a/src/runtime/runtime-object.cc b/src/runtime/runtime-object.cc |
index 990ca1359141b865ff17d91234fd1ef5d48328ef..97d5e2be095d18b9b66b233c17838bab3f0f5967 100644 |
--- a/src/runtime/runtime-object.cc |
+++ b/src/runtime/runtime-object.cc |
@@ -1030,6 +1030,9 @@ RUNTIME_FUNCTION(Runtime_Compare) { |
RUNTIME_FUNCTION(Runtime_InstanceOf) { |
+ // TODO(4447): Remove this function when ES6 instanceof ships for good. |
+ DCHECK(!FLAG_harmony_instanceof); |
+ |
// ECMA-262, section 11.8.6, page 54. |
HandleScope shs(isolate); |
DCHECK_EQ(2, args.length()); |
@@ -1073,6 +1076,48 @@ RUNTIME_FUNCTION(Runtime_InstanceOf) { |
return isolate->heap()->ToBoolean(result.FromJust()); |
} |
+RUNTIME_FUNCTION(Runtime_OrdinaryHasInstance) { |
+ // ES6 section 19.2.3.6 Function.prototype[@@hasInstance](V) |
+ HandleScope shs(isolate); |
+ DCHECK_EQ(2, args.length()); |
+ DCHECK(args.length() == 2); |
+ CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); |
+ CONVERT_ARG_HANDLE_CHECKED(Object, callable, 1); |
+ // {callable} must have a [[Call]] internal method. |
+ if (!callable->IsCallable()) { |
+ return isolate->heap()->false_value(); |
+ } |
+ // If {object} is not a receiver, return false. |
+ if (!object->IsJSReceiver()) { |
+ return isolate->heap()->false_value(); |
+ } |
+ // Check if {callable} is bound, if so, get [[BoundTargetFunction]] from it |
+ // and use that instead of {callable}. |
+ while (callable->IsJSBoundFunction()) { |
+ callable = |
+ handle(Handle<JSBoundFunction>::cast(callable)->bound_target_function(), |
+ isolate); |
+ } |
+ DCHECK(callable->IsCallable()); |
+ // Get the "prototype" of {callable}; raise an error if it's not a receiver. |
+ Handle<Object> prototype; |
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
+ isolate, prototype, |
+ JSReceiver::GetProperty(Handle<JSReceiver>::cast(callable), |
+ isolate->factory()->prototype_string())); |
+ if (!prototype->IsJSReceiver()) { |
+ THROW_NEW_ERROR_RETURN_FAILURE( |
+ isolate, |
+ NewTypeError(MessageTemplate::kInstanceofNonobjectProto, prototype)); |
+ } |
+ // Return whether or not {prototype} is in the prototype chain of {object}. |
+ Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object); |
+ Maybe<bool> result = |
+ JSReceiver::HasInPrototypeChain(isolate, receiver, prototype); |
+ MAYBE_RETURN(result, isolate->heap()->exception()); |
+ return isolate->heap()->ToBoolean(result.FromJust()); |
+} |
+ |
RUNTIME_FUNCTION(Runtime_HasInPrototypeChain) { |
HandleScope scope(isolate); |