| Index: src/runtime.cc
|
| diff --git a/src/runtime.cc b/src/runtime.cc
|
| index b32ae8a1b4b81a85c4d8e0d1737eea1b367d61b3..29d31dbdd544c5a8168bc3204de8f26917c126ac 100644
|
| --- a/src/runtime.cc
|
| +++ b/src/runtime.cc
|
| @@ -4166,25 +4166,33 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_HasLocalProperty) {
|
| ASSERT(args.length() == 2);
|
| CONVERT_CHECKED(String, key, args[1]);
|
|
|
| + uint32_t index;
|
| + const bool key_is_array_index = key->AsArrayIndex(&index);
|
| +
|
| Object* obj = args[0];
|
| // Only JS objects can have properties.
|
| if (obj->IsJSObject()) {
|
| JSObject* object = JSObject::cast(obj);
|
| - // Fast case - no interceptors.
|
| + // 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.
|
| if (object->HasRealNamedProperty(key)) return isolate->heap()->true_value();
|
| - // Slow case. Either it's not there or we have an interceptor. We should
|
| - // have handles for this kind of deal.
|
| + Map* map = object->map();
|
| + if (!key_is_array_index &&
|
| + !map->has_named_interceptor() &&
|
| + !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) {
|
| + return isolate->heap()->false_value();
|
| + }
|
| + // Slow case.
|
| HandleScope scope(isolate);
|
| return HasLocalPropertyImplementation(isolate,
|
| Handle<JSObject>(object),
|
| Handle<String>(key));
|
| - } else if (obj->IsString()) {
|
| + } else if (obj->IsString() && key_is_array_index) {
|
| // Well, there is one exception: Handle [] on strings.
|
| - uint32_t index;
|
| - if (key->AsArrayIndex(&index)) {
|
| - String* string = String::cast(obj);
|
| - if (index < static_cast<uint32_t>(string->length()))
|
| - return isolate->heap()->true_value();
|
| + String* string = String::cast(obj);
|
| + if (index < static_cast<uint32_t>(string->length())) {
|
| + return isolate->heap()->true_value();
|
| }
|
| }
|
| return isolate->heap()->false_value();
|
|
|