| Index: src/builtins.cc
|
| diff --git a/src/builtins.cc b/src/builtins.cc
|
| index 961cfcdf7ccff08c7fb4753109e786fc3f4ef361..18f398d7d6192fdb8f9ed8a90f60309dbaa4e5bc 100644
|
| --- a/src/builtins.cc
|
| +++ b/src/builtins.cc
|
| @@ -352,6 +352,83 @@ BUILTIN(Illegal) {
|
|
|
| BUILTIN(EmptyFunction) { return isolate->heap()->undefined_value(); }
|
|
|
| +// ES6 7.3.11
|
| +BUILTIN(ObjectHasOwnProperty) {
|
| + HandleScope scope(isolate);
|
| +
|
| + Handle<Object> property = args.atOrUndefined(isolate, 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.receiver();
|
| +
|
| + 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, c)
|
| + : LookupIterator(js_obj, key, 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, c)
|
| + : LookupIterator(js_obj, key, 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();
|
| +}
|
|
|
| BUILTIN(ArrayPush) {
|
| HandleScope scope(isolate);
|
|
|