summaryrefslogtreecommitdiff
path: root/deps/v8/src/runtime/runtime-object.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/runtime/runtime-object.cc')
-rw-r--r--deps/v8/src/runtime/runtime-object.cc230
1 files changed, 132 insertions, 98 deletions
diff --git a/deps/v8/src/runtime/runtime-object.cc b/deps/v8/src/runtime/runtime-object.cc
index 45a49925bd..5bdb08541f 100644
--- a/deps/v8/src/runtime/runtime-object.cc
+++ b/deps/v8/src/runtime/runtime-object.cc
@@ -125,6 +125,82 @@ Maybe<bool> Runtime::DeleteObjectProperty(Isolate* isolate,
return JSReceiver::DeleteProperty(&it, language_mode);
}
+// ES6 19.1.3.2
+RUNTIME_FUNCTION(Runtime_ObjectHasOwnProperty) {
+ HandleScope scope(isolate);
+ Handle<Object> property = args.at<Object>(1);
+
+ Handle<Name> key;
+ uint32_t index;
+ bool key_is_array_index = property->ToArrayIndex(&index);
+
+ if (!key_is_array_index) {
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key,
+ Object::ToName(isolate, property));
+ key_is_array_index = key->AsArrayIndex(&index);
+ }
+
+ Handle<Object> object = args.at<Object>(0);
+
+ if (object->IsJSObject()) {
+ Handle<JSObject> js_obj = Handle<JSObject>::cast(object);
+ // Fast case: either the key is a real named property or it is not
+ // an array index and there are no interceptors or hidden
+ // prototypes.
+ // TODO(jkummerow): Make JSReceiver::HasOwnProperty fast enough to
+ // handle all cases directly (without this custom fast path).
+ {
+ LookupIterator::Configuration c = LookupIterator::OWN_SKIP_INTERCEPTOR;
+ LookupIterator it =
+ key_is_array_index ? LookupIterator(isolate, js_obj, index, js_obj, c)
+ : LookupIterator(js_obj, key, js_obj, c);
+ Maybe<bool> maybe = JSReceiver::HasProperty(&it);
+ if (maybe.IsNothing()) return isolate->heap()->exception();
+ DCHECK(!isolate->has_pending_exception());
+ if (maybe.FromJust()) return isolate->heap()->true_value();
+ }
+
+ Map* map = js_obj->map();
+ if (!map->has_hidden_prototype() &&
+ (key_is_array_index ? !map->has_indexed_interceptor()
+ : !map->has_named_interceptor())) {
+ return isolate->heap()->false_value();
+ }
+
+ // Slow case.
+ LookupIterator::Configuration c = LookupIterator::HIDDEN;
+ LookupIterator it = key_is_array_index
+ ? LookupIterator(isolate, js_obj, index, js_obj, c)
+ : LookupIterator(js_obj, key, js_obj, c);
+
+ Maybe<bool> maybe = JSReceiver::HasProperty(&it);
+ if (maybe.IsNothing()) return isolate->heap()->exception();
+ DCHECK(!isolate->has_pending_exception());
+ return isolate->heap()->ToBoolean(maybe.FromJust());
+
+ } else if (object->IsJSProxy()) {
+ if (key.is_null()) {
+ DCHECK(key_is_array_index);
+ key = isolate->factory()->Uint32ToString(index);
+ }
+
+ Maybe<bool> result =
+ JSReceiver::HasOwnProperty(Handle<JSProxy>::cast(object), key);
+ if (!result.IsJust()) return isolate->heap()->exception();
+ return isolate->heap()->ToBoolean(result.FromJust());
+
+ } else if (object->IsString()) {
+ return isolate->heap()->ToBoolean(
+ key_is_array_index
+ ? index < static_cast<uint32_t>(String::cast(*object)->length())
+ : key->Equals(isolate->heap()->length_string()));
+ } else if (object->IsNull() || object->IsUndefined()) {
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate, NewTypeError(MessageTemplate::kUndefinedOrNullToObject));
+ }
+
+ return isolate->heap()->false_value();
+}
MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate,
Handle<Object> object,
@@ -205,7 +281,7 @@ MUST_USE_RESULT static MaybeHandle<Object> GetOwnProperty(Isolate* isolate,
Factory* factory = isolate->factory();
// Get attributes.
- LookupIterator it = LookupIterator::PropertyOrElement(isolate, obj, name,
+ LookupIterator it = LookupIterator::PropertyOrElement(isolate, obj, name, obj,
LookupIterator::HIDDEN);
Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(&it);
@@ -293,7 +369,7 @@ RUNTIME_FUNCTION(Runtime_LoadGlobalViaContext) {
Handle<Name> name(scope_info->ContextSlotName(slot), isolate);
Handle<JSGlobalObject> global_object(script_context->global_object(),
isolate);
- LookupIterator it(global_object, name, LookupIterator::HIDDEN);
+ LookupIterator it(global_object, name, global_object, LookupIterator::HIDDEN);
// Switch to fast mode only if there is a data property and it's not on
// a hidden prototype.
@@ -328,7 +404,7 @@ Object* StoreGlobalViaContext(Isolate* isolate, int slot, Handle<Object> value,
Handle<Name> name(scope_info->ContextSlotName(slot), isolate);
Handle<JSGlobalObject> global_object(script_context->global_object(),
isolate);
- LookupIterator it(global_object, name, LookupIterator::HIDDEN);
+ LookupIterator it(global_object, name, global_object, LookupIterator::HIDDEN);
// Switch to fast mode only if there is a data property and it's not on
// a hidden prototype.
@@ -413,7 +489,7 @@ RUNTIME_FUNCTION(Runtime_AddNamedProperty) {
#ifdef DEBUG
uint32_t index = 0;
DCHECK(!name->ToArrayIndex(&index));
- LookupIterator it(object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
+ LookupIterator it(object, name, object, LookupIterator::OWN_SKIP_INTERCEPTOR);
Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
if (!maybe.IsJust()) return isolate->heap()->exception();
RUNTIME_ASSERT(!it.IsFound());
@@ -441,7 +517,7 @@ RUNTIME_FUNCTION(Runtime_AddElement) {
CHECK(key->ToArrayIndex(&index));
#ifdef DEBUG
- LookupIterator it(isolate, object, index,
+ LookupIterator it(isolate, object, index, object,
LookupIterator::OWN_SKIP_INTERCEPTOR);
Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
if (!maybe.IsJust()) return isolate->heap()->exception();
@@ -532,85 +608,6 @@ RUNTIME_FUNCTION(Runtime_DeleteProperty_Strict) {
}
-static Object* HasOwnPropertyImplementation(Isolate* isolate,
- Handle<JSObject> object,
- Handle<Name> key) {
- Maybe<bool> maybe = JSReceiver::HasOwnProperty(object, key);
- if (!maybe.IsJust()) return isolate->heap()->exception();
- if (maybe.FromJust()) return isolate->heap()->true_value();
- // Handle hidden prototypes. If there's a hidden prototype above this thing
- // then we have to check it for properties, because they are supposed to
- // look like they are on this object.
- if (object->map()->has_hidden_prototype()) {
- PrototypeIterator iter(isolate, object);
- DCHECK(!iter.IsAtEnd());
-
- // TODO(verwaest): The recursion is not necessary for keys that are array
- // indices. Removing this.
- // Casting to JSObject is fine because JSProxies are never used as
- // hidden prototypes.
- return HasOwnPropertyImplementation(
- isolate, PrototypeIterator::GetCurrent<JSObject>(iter), key);
- }
- RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
- return isolate->heap()->false_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_HasOwnProperty) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 2);
- CONVERT_ARG_HANDLE_CHECKED(Object, object, 0)
- CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
-
- uint32_t index;
- const bool key_is_array_index = key->AsArrayIndex(&index);
-
- // Only JS objects can have properties.
- if (object->IsJSObject()) {
- Handle<JSObject> js_obj = Handle<JSObject>::cast(object);
- // Fast case: either the key is a real named property or it is not
- // an array index and there are no interceptors or hidden
- // prototypes.
- // TODO(jkummerow): Make JSReceiver::HasOwnProperty fast enough to
- // handle all cases directly (without this custom fast path).
- Maybe<bool> maybe = Nothing<bool>();
- if (key_is_array_index) {
- LookupIterator it(js_obj->GetIsolate(), js_obj, index,
- LookupIterator::HIDDEN);
- maybe = JSReceiver::HasProperty(&it);
- } else {
- maybe = JSObject::HasRealNamedProperty(js_obj, key);
- }
- if (!maybe.IsJust()) return isolate->heap()->exception();
- DCHECK(!isolate->has_pending_exception());
- if (maybe.FromJust()) {
- return isolate->heap()->true_value();
- }
- Map* map = js_obj->map();
- if (!key_is_array_index && !map->has_named_interceptor() &&
- !map->has_hidden_prototype()) {
- return isolate->heap()->false_value();
- }
- // Slow case.
- return HasOwnPropertyImplementation(isolate, Handle<JSObject>(js_obj),
- Handle<Name>(key));
- } else if (object->IsString() && key_is_array_index) {
- // Well, there is one exception: Handle [] on strings.
- Handle<String> string = Handle<String>::cast(object);
- if (index < static_cast<uint32_t>(string->length())) {
- return isolate->heap()->true_value();
- }
- } else if (object->IsJSProxy()) {
- Maybe<bool> result =
- JSReceiver::HasOwnProperty(Handle<JSProxy>::cast(object), key);
- if (!result.IsJust()) return isolate->heap()->exception();
- return isolate->heap()->ToBoolean(result.FromJust());
- }
- return isolate->heap()->false_value();
-}
-
-
// ES6 section 12.9.3, operator in.
RUNTIME_FUNCTION(Runtime_HasProperty) {
HandleScope scope(isolate);
@@ -840,8 +837,8 @@ RUNTIME_FUNCTION(Runtime_DefineDataPropertyUnchecked) {
CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
- LookupIterator it = LookupIterator::PropertyOrElement(isolate, object, name,
- LookupIterator::OWN);
+ LookupIterator it = LookupIterator::PropertyOrElement(
+ isolate, object, name, object, LookupIterator::OWN);
if (it.state() == LookupIterator::ACCESS_CHECK && !it.HasAccess()) {
return isolate->heap()->undefined_value();
}
@@ -869,8 +866,8 @@ RUNTIME_FUNCTION(Runtime_DefineDataPropertyInLiteral) {
isolate->factory()->empty_string());
}
- LookupIterator it = LookupIterator::PropertyOrElement(isolate, object, name,
- LookupIterator::OWN);
+ LookupIterator it = LookupIterator::PropertyOrElement(
+ isolate, object, name, object, LookupIterator::OWN);
// Cannot fail since this should only be called when
// creating an object literal.
CHECK(JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attrs,
@@ -915,15 +912,6 @@ RUNTIME_FUNCTION(Runtime_IsJSReceiver) {
}
-RUNTIME_FUNCTION(Runtime_IsStrong) {
- SealHandleScope shs(isolate);
- DCHECK(args.length() == 1);
- CONVERT_ARG_CHECKED(Object, obj, 0);
- return isolate->heap()->ToBoolean(obj->IsJSReceiver() &&
- JSReceiver::cast(obj)->map()->is_strong());
-}
-
-
RUNTIME_FUNCTION(Runtime_ClassOf) {
SealHandleScope shs(isolate);
DCHECK(args.length() == 1);
@@ -1118,6 +1106,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());
@@ -1146,7 +1137,50 @@ RUNTIME_FUNCTION(Runtime_InstanceOf) {
Handle<Object> prototype;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, prototype,
- Object::GetProperty(callable, isolate->factory()->prototype_string()));
+ 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_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,