Add LookupIterator constructor for arbitrary Object keys
authorjkummerow <jkummerow@chromium.org>
Wed, 30 Sep 2015 14:51:45 +0000 (07:51 -0700)
committerJongsoo Yoon <join.yoon@samsung.com>
Fri, 20 Nov 2015 13:32:15 +0000 (22:32 +0900)
Continuing unification of properties/elements handling, the new
LookupIterator::PropertyOrElement(..., Handle<Object> key, ...) takes
any Object and does the required ToPrimitive/ToName/ToArrayIndex
conversions on it.

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

Cr-Commit-Position: refs/heads/master@{#31023}

src/api.cc
src/lookup.cc
src/lookup.h
src/runtime/runtime-object.cc

index cfc170e..01e1de2 100644 (file)
@@ -3526,20 +3526,12 @@ static i::MaybeHandle<i::Object> DefineObjectProperty(
     i::Handle<i::JSObject> js_object, i::Handle<i::Object> key,
     i::Handle<i::Object> value, PropertyAttributes attrs) {
   i::Isolate* isolate = js_object->GetIsolate();
-  // Check if the given key is an array index.
-  uint32_t index = 0;
-  if (key->ToArrayIndex(&index)) {
-    return i::JSObject::SetOwnElementIgnoreAttributes(js_object, index, value,
-                                                      attrs);
-  }
-
-  i::Handle<i::Name> name;
-  ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, name,
-                                   i::Object::ToName(isolate, key),
-                                   i::MaybeHandle<i::Object>());
+  bool success = false;
+  i::LookupIterator it = i::LookupIterator::PropertyOrElement(
+      isolate, js_object, key, &success, i::LookupIterator::OWN);
+  if (!success) return i::MaybeHandle<i::Object>();
 
-  return i::JSObject::DefinePropertyOrElementIgnoreAttributes(js_object, name,
-                                                              value, attrs);
+  return i::JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attrs);
 }
 
 
index 809c35e..5dcc045 100644 (file)
@@ -13,6 +13,38 @@ namespace v8 {
 namespace internal {
 
 
+// static
+LookupIterator LookupIterator::PropertyOrElement(Isolate* isolate,
+                                                 Handle<Object> receiver,
+                                                 Handle<Object> key,
+                                                 bool* success,
+                                                 Configuration configuration) {
+  uint32_t index = 0;
+  if (key->ToArrayIndex(&index)) {
+    *success = true;
+    return LookupIterator(isolate, receiver, index, configuration);
+  }
+
+  Handle<Name> name;
+  *success = Object::ToName(isolate, key).ToHandle(&name);
+  if (!*success) {
+    DCHECK(isolate->has_pending_exception());
+    // Return an unusable dummy.
+    return LookupIterator(receiver, isolate->factory()->empty_string());
+  }
+
+  if (name->AsArrayIndex(&index)) {
+    LookupIterator it(isolate, receiver, index, configuration);
+    // Here we try to avoid having to rebuild the string later
+    // by storing it on the indexed LookupIterator.
+    it.name_ = name;
+    return it;
+  }
+
+  return LookupIterator(receiver, name, configuration);
+}
+
+
 void LookupIterator::Next() {
   DCHECK_NE(JSPROXY, state_);
   DCHECK_NE(TRANSITION, state_);
index 8365cfc..b056443 100644 (file)
@@ -158,6 +158,10 @@ class LookupIterator final BASE_EMBEDDED {
     return it;
   }
 
+  static LookupIterator PropertyOrElement(
+      Isolate* isolate, Handle<Object> receiver, Handle<Object> key,
+      bool* success, Configuration configuration = DEFAULT);
+
   Isolate* isolate() const { return isolate_; }
   State state() const { return state_; }
 
index 4782a31..7aaf768 100644 (file)
@@ -26,26 +26,12 @@ MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
         Object);
   }
 
-  // Check if the given key is an array index.
-  uint32_t index = 0;
-  if (key->ToArrayIndex(&index)) {
-    return Object::GetElement(isolate, object, index, language_mode);
-  }
+  bool success = false;
+  LookupIterator it =
+      LookupIterator::PropertyOrElement(isolate, object, key, &success);
+  if (!success) return MaybeHandle<Object>();
 
-  // Convert the key to a name - possibly by calling back into JavaScript.
-  Handle<Name> name;
-  ASSIGN_RETURN_ON_EXCEPTION(isolate, name, Object::ToName(isolate, key),
-                             Object);
-
-  // Check if the name is trivially convertible to an index and get
-  // the element if so.
-  // TODO(verwaest): Make sure GetProperty(LookupIterator*) can handle this, and
-  // remove the special casing here.
-  if (name->AsArrayIndex(&index)) {
-    return Object::GetElement(isolate, object, index);
-  } else {
-    return Object::GetProperty(object, name, language_mode);
-  }
+  return Object::GetProperty(&it, language_mode);
 }
 
 
@@ -135,17 +121,12 @@ MaybeHandle<Object> Runtime::DeleteObjectProperty(Isolate* isolate,
                                                   Handle<JSReceiver> receiver,
                                                   Handle<Object> key,
                                                   LanguageMode language_mode) {
-  // Check if the given key is an array index.
-  uint32_t index = 0;
-  if (key->ToArrayIndex(&index)) {
-    return JSReceiver::DeleteElement(receiver, index, language_mode);
-  }
-
-  Handle<Name> name;
-  ASSIGN_RETURN_ON_EXCEPTION(isolate, name, Object::ToName(isolate, key),
-                             Object);
+  bool success = false;
+  LookupIterator it = LookupIterator::PropertyOrElement(
+      isolate, receiver, key, &success, LookupIterator::HIDDEN);
+  if (!success) return MaybeHandle<Object>();
 
-  return JSReceiver::DeletePropertyOrElement(receiver, name, language_mode);
+  return JSReceiver::DeleteProperty(&it, language_mode);
 }
 
 
@@ -162,16 +143,11 @@ MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate,
   }
 
   // Check if the given key is an array index.
-  uint32_t index = 0;
-  if (key->ToArrayIndex(&index)) {
-    return Object::SetElement(isolate, object, index, value, language_mode);
-  }
-
-  Handle<Name> name;
-  ASSIGN_RETURN_ON_EXCEPTION(isolate, name, Object::ToName(isolate, key),
-                             Object);
+  bool success = false;
+  LookupIterator it =
+      LookupIterator::PropertyOrElement(isolate, object, key, &success);
+  if (!success) return MaybeHandle<Object>();
 
-  LookupIterator it = LookupIterator::PropertyOrElement(isolate, object, name);
   return Object::SetProperty(&it, value, language_mode,
                              Object::MAY_BE_STORE_FROM_KEYED);
 }