Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 06e4db5ff60294d01ba37742d37320d604d3f9e5..9cd1caf6a3108fb65b6a07de8eed172d2ffda4a9 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -6580,25 +6580,26 @@ MaybeHandle<Object> JSObject::GetAccessor(Handle<JSObject> object, |
// interceptor calls. |
AssertNoContextChange ncc(isolate); |
- // Check access rights if needed. |
- if (object->IsAccessCheckNeeded() && |
- !isolate->MayNamedAccess(object, name, v8::ACCESS_HAS)) { |
- isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS); |
- RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
- return isolate->factory()->undefined_value(); |
- } |
- |
// Make the lookup and include prototypes. |
uint32_t index = 0; |
if (name->AsArrayIndex(&index)) { |
for (PrototypeIterator iter(isolate, object, |
PrototypeIterator::START_AT_RECEIVER); |
!iter.IsAtEnd(); iter.Advance()) { |
- if (PrototypeIterator::GetCurrent(iter)->IsJSObject() && |
- JSObject::cast(*PrototypeIterator::GetCurrent(iter)) |
- ->HasDictionaryElements()) { |
- JSObject* js_object = |
- JSObject::cast(*PrototypeIterator::GetCurrent(iter)); |
+ Handle<Object> current = PrototypeIterator::GetCurrent(iter); |
+ // Check access rights if needed. |
+ if (current->IsAccessCheckNeeded() && |
+ !isolate->MayNamedAccess(Handle<JSObject>::cast(current), name, |
+ v8::ACCESS_HAS)) { |
+ isolate->ReportFailedAccessCheck(Handle<JSObject>::cast(current), |
+ v8::ACCESS_HAS); |
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
+ return isolate->factory()->undefined_value(); |
+ } |
+ |
+ if (current->IsJSObject() && |
+ Handle<JSObject>::cast(current)->HasDictionaryElements()) { |
+ JSObject* js_object = JSObject::cast(*current); |
SeededNumberDictionary* dictionary = js_object->element_dictionary(); |
int entry = dictionary->FindEntry(index); |
if (entry != SeededNumberDictionary::kNotFound) { |
@@ -6612,21 +6613,38 @@ MaybeHandle<Object> JSObject::GetAccessor(Handle<JSObject> object, |
} |
} |
} else { |
- for (PrototypeIterator iter(isolate, object, |
- PrototypeIterator::START_AT_RECEIVER); |
- !iter.IsAtEnd(); iter.Advance()) { |
- LookupResult result(isolate); |
- JSReceiver::cast(*PrototypeIterator::GetCurrent(iter)) |
- ->LookupOwn(name, &result); |
- if (result.IsFound()) { |
- if (result.IsReadOnly()) return isolate->factory()->undefined_value(); |
- if (result.IsPropertyCallbacks()) { |
- Object* obj = result.GetCallbackObject(); |
- if (obj->IsAccessorPair()) { |
- return handle(AccessorPair::cast(obj)->GetComponent(component), |
- isolate); |
+ LookupIterator it(object, name, |
+ LookupIterator::CHECK_DERIVED_SKIP_INTERCEPTOR); |
+ for (; it.IsFound(); it.Next()) { |
+ switch (it.state()) { |
+ case LookupIterator::NOT_FOUND: |
+ case LookupIterator::INTERCEPTOR: |
+ UNREACHABLE(); |
+ |
+ case LookupIterator::ACCESS_CHECK: |
+ if (it.HasAccess(v8::ACCESS_HAS)) continue; |
+ isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>(), |
+ v8::ACCESS_HAS); |
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
+ return isolate->factory()->undefined_value(); |
+ |
+ case LookupIterator::JSPROXY: |
+ return isolate->factory()->undefined_value(); |
+ |
+ case LookupIterator::PROPERTY: |
+ if (!it.HasProperty()) continue; |
+ switch (it.property_kind()) { |
+ case LookupIterator::DATA: |
+ continue; |
+ case LookupIterator::ACCESSOR: { |
+ Handle<Object> maybe_pair = it.GetAccessors(); |
+ if (maybe_pair->IsAccessorPair()) { |
+ return handle( |
+ AccessorPair::cast(*maybe_pair)->GetComponent(component), |
+ isolate); |
+ } |
+ } |
} |
- } |
} |
} |
} |