Rewrite GetAccessor using the LookupIterator
authorverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 14 Aug 2014 13:02:49 +0000 (13:02 +0000)
committerverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 14 Aug 2014 13:02:49 +0000 (13:02 +0000)
BUG=
R=jkummerow@chromium.org

Review URL: https://codereview.chromium.org/467293003

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23129 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/objects.cc

index 659d75d..874f6c3 100644 (file)
@@ -6874,25 +6874,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) {
@@ -6906,21 +6907,37 @@ 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::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);
+              }
+            }
           }
-        }
       }
     }
   }