Handle Delete of element with LookupIterator
authorverwaest <verwaest@chromium.org>
Tue, 2 Jun 2015 11:52:30 +0000 (04:52 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 2 Jun 2015 11:52:41 +0000 (11:52 +0000)
BUG=v8:4137
LOG=n

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

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

src/elements.cc
src/elements.h
src/lookup.h
src/objects-inl.h
src/objects.cc
src/objects.h

index bad3c5ba8b12c535d3d061c67df11cd1832fba13..cf55a202b4689f6b57598abfd0ebef6fc6d2450f 100644 (file)
@@ -669,9 +669,8 @@ class ElementsAccessorBase : public ElementsAccessor {
     UNIMPLEMENTED();
   }
 
-  MUST_USE_RESULT virtual MaybeHandle<Object> Delete(
-      Handle<JSObject> obj, uint32_t key,
-      LanguageMode language_mode) override = 0;
+  virtual void Delete(Handle<JSObject> obj, uint32_t key,
+                      LanguageMode language_mode) override = 0;
 
   static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
                                FixedArrayBase* to, ElementsKind from_kind,
@@ -919,17 +918,16 @@ class FastElementsAccessor
     return length_object;
   }
 
-  static MaybeHandle<Object> DeleteCommon(Handle<JSObject> obj, uint32_t key,
-                                          LanguageMode language_mode) {
+  static void DeleteCommon(Handle<JSObject> obj, uint32_t key,
+                           LanguageMode language_mode) {
     DCHECK(obj->HasFastSmiOrObjectElements() ||
            obj->HasFastDoubleElements() ||
            obj->HasFastArgumentsElements());
     Isolate* isolate = obj->GetIsolate();
     Heap* heap = obj->GetHeap();
     Handle<FixedArrayBase> elements(obj->elements());
-    if (*elements == heap->empty_fixed_array()) {
-      return isolate->factory()->true_value();
-    }
+    if (*elements == heap->empty_fixed_array()) return;
+
     Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements);
     bool is_sloppy_arguments_elements_map =
         backing_store->map() == heap->sloppy_arguments_elements_map();
@@ -943,16 +941,6 @@ class FastElementsAccessor
         ? Smi::cast(Handle<JSArray>::cast(obj)->length())->value()
         : backing_store->length());
     if (key < length) {
-      if (obj->map()->is_strong() && !backing_store->is_the_hole(key)) {
-        if (is_strict(language_mode)) {
-          Handle<Object> name = isolate->factory()->NewNumberFromUint(key);
-          THROW_NEW_ERROR(
-              isolate,
-              NewTypeError(MessageTemplate::kStrongDeleteProperty, obj, name),
-              Object);
-        }
-        return isolate->factory()->false_value();
-      }
       if (!is_sloppy_arguments_elements_map) {
         ElementsKind kind = KindTraits::Kind;
         if (IsFastPackedElementsKind(kind)) {
@@ -984,12 +972,11 @@ class FastElementsAccessor
         }
       }
     }
-    return isolate->factory()->true_value();
   }
 
-  virtual MaybeHandle<Object> Delete(Handle<JSObject> obj, uint32_t key,
-                                     LanguageMode language_mode) final {
-    return DeleteCommon(obj, key, language_mode);
+  virtual void Delete(Handle<JSObject> obj, uint32_t key,
+                      LanguageMode language_mode) final {
+    DeleteCommon(obj, key, language_mode);
   }
 
   static bool HasElementImpl(
@@ -1306,10 +1293,9 @@ class TypedElementsAccessor
     return obj;
   }
 
-  MUST_USE_RESULT virtual MaybeHandle<Object> Delete(
-      Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) final {
+  virtual void Delete(Handle<JSObject> obj, uint32_t key,
+                      LanguageMode language_mode) final {
     // External arrays always ignore deletes.
-    return obj->GetIsolate()->factory()->true_value();
   }
 
   static bool HasElementImpl(Handle<JSObject> holder, uint32_t key,
@@ -1409,8 +1395,8 @@ class DictionaryElementsAccessor
     return length_object;
   }
 
-  MUST_USE_RESULT static MaybeHandle<Object> DeleteCommon(
-      Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) {
+  static void DeleteCommon(Handle<JSObject> obj, uint32_t key,
+                           LanguageMode language_mode) {
     Isolate* isolate = obj->GetIsolate();
     Handle<FixedArray> backing_store(FixedArray::cast(obj->elements()),
                                      isolate);
@@ -1423,28 +1409,10 @@ class DictionaryElementsAccessor
         Handle<SeededNumberDictionary>::cast(backing_store);
     int entry = dictionary->FindEntry(key);
     if (entry != SeededNumberDictionary::kNotFound) {
-      Handle<Object> result;
-      bool strong = obj->map()->is_strong();
-      if (!strong) {
-        result = SeededNumberDictionary::DeleteProperty(dictionary, entry);
-      }
-      if (strong || *result == *isolate->factory()->false_value()) {
-        // Fail if the property is not configurable, or on a strong object.
-        if (is_strict(language_mode)) {
-          Handle<Object> name = isolate->factory()->NewNumberFromUint(key);
-          if (strong) {
-            THROW_NEW_ERROR(
-                isolate,
-                NewTypeError(MessageTemplate::kStrongDeleteProperty, obj, name),
-                Object);
-          }
-          THROW_NEW_ERROR(
-              isolate,
-              NewTypeError(MessageTemplate::kStrictDeleteProperty, name, obj),
-              Object);
-        }
-        return isolate->factory()->false_value();
-      }
+      Handle<Object> result =
+          SeededNumberDictionary::DeleteProperty(dictionary, entry);
+      USE(result);
+      DCHECK(result->IsTrue());
       Handle<FixedArray> new_elements =
           SeededNumberDictionary::Shrink(dictionary, key);
 
@@ -1454,7 +1422,6 @@ class DictionaryElementsAccessor
         obj->set_elements(*new_elements);
       }
     }
-    return isolate->factory()->true_value();
   }
 
   static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
@@ -1469,9 +1436,9 @@ class DictionaryElementsAccessor
   friend class ElementsAccessorBase<DictionaryElementsAccessor,
                                     ElementsKindTraits<DICTIONARY_ELEMENTS> >;
 
-  MUST_USE_RESULT virtual MaybeHandle<Object> Delete(
-      Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) final {
-    return DeleteCommon(obj, key, language_mode);
+  virtual void Delete(Handle<JSObject> obj, uint32_t key,
+                      LanguageMode language_mode) final {
+    DeleteCommon(obj, key, language_mode);
   }
 
   static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key,
@@ -1631,8 +1598,8 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
     return obj;
   }
 
-  MUST_USE_RESULT virtual MaybeHandle<Object> Delete(
-      Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) final {
+  virtual void Delete(Handle<JSObject> obj, uint32_t key,
+                      LanguageMode language_mode) final {
     Isolate* isolate = obj->GetIsolate();
     Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements()));
     Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate);
@@ -1644,17 +1611,14 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
     } else {
       Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)));
       if (arguments->IsDictionary()) {
-        return DictionaryElementsAccessor::DeleteCommon(obj, key,
-                                                        language_mode);
+        DictionaryElementsAccessor::DeleteCommon(obj, key, language_mode);
       } else {
         // It's difficult to access the version of DeleteCommon that is declared
         // in the templatized super class, call the concrete implementation in
         // the class for the most generalized ElementsKind subclass.
-        return FastHoleyObjectElementsAccessor::DeleteCommon(obj, key,
-                                                             language_mode);
+        FastHoleyObjectElementsAccessor::DeleteCommon(obj, key, language_mode);
       }
     }
-    return isolate->factory()->true_value();
   }
 
   static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
index 1065b1f73df63aa492a766cefa3e309dbbf2bb64..49faeab0dbd04012b87de6d22067e5cb72040b10 100644 (file)
@@ -102,9 +102,9 @@ class ElementsAccessor {
       int capacity,
       int length) = 0;
 
-  // Deletes an element in an object, returning a new elements backing store.
-  MUST_USE_RESULT virtual MaybeHandle<Object> Delete(
-      Handle<JSObject> holder, uint32_t key, LanguageMode language_mode) = 0;
+  // Deletes an element in an object.
+  virtual void Delete(Handle<JSObject> holder, uint32_t key,
+                      LanguageMode language_mode) = 0;
 
   // If kCopyToEnd is specified as the copy_size to CopyElements, it copies all
   // of elements from source after source_start to the destination array.
index ed54a7ef7306c7603f626f7b0c529f624a0590b6..29b7d77b270d26447f8190d651ba1c1704462834 100644 (file)
@@ -59,6 +59,12 @@ class LookupIterator final BASE_EMBEDDED {
         holder_map_(holder_->map(), isolate_),
         initial_holder_(holder_),
         number_(DescriptorArray::kNotFound) {
+#if 0  // TODO(verwaest): Enable once blocking hacks are removed.
+#ifdef DEBUG
+    uint32_t index;  // Assert that the name is not an array index.
+    DCHECK(!name->AsArrayIndex(&index));
+#endif  // DEBUG
+#endif
     Next();
   }
 
@@ -79,6 +85,12 @@ class LookupIterator final BASE_EMBEDDED {
         holder_map_(holder_->map(), isolate_),
         initial_holder_(holder_),
         number_(DescriptorArray::kNotFound) {
+#if 0  // TODO(verwaest): Enable once blocking hacks are removed.
+#ifdef DEBUG
+    uint32_t index;  // Assert that the name is not an array index.
+    DCHECK(!name->AsArrayIndex(&index));
+#endif  // DEBUG
+#endif
     Next();
   }
 
index 895d39fd8e7d9ef428dc8006de7dd7dd537f6550..b1808be3c405f3a475d12fa074f32d28f6b5cf43 100644 (file)
@@ -1193,11 +1193,6 @@ MaybeHandle<Object> Object::GetProperty(Isolate* isolate,
                                         Handle<Object> object,
                                         const char* name) {
   Handle<String> str = isolate->factory()->InternalizeUtf8String(name);
-  DCHECK(!str.is_null());
-#ifdef DEBUG
-  uint32_t index;  // Assert that the name is not an array index.
-  DCHECK(!str->AsArrayIndex(&index));
-#endif  // DEBUG
   return GetProperty(object, str);
 }
 
@@ -1213,14 +1208,6 @@ MaybeHandle<Object> JSProxy::SetElementWithHandler(Handle<JSProxy> proxy,
 }
 
 
-Maybe<bool> JSProxy::HasElementWithHandler(Handle<JSProxy> proxy,
-                                           uint32_t index) {
-  Isolate* isolate = proxy->GetIsolate();
-  Handle<String> name = isolate->factory()->Uint32ToString(index);
-  return HasPropertyWithHandler(proxy, name);
-}
-
-
 #define FIELD_ADDR(p, offset) \
   (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
 
index 661d769e5d8f9b54ae7293ab7aed297159c2acdd..2390802777914bfe9b110c9e724b47a76f6bdb76 100644 (file)
@@ -3941,14 +3941,6 @@ MaybeHandle<Object> JSProxy::DeletePropertyWithHandler(
 }
 
 
-MaybeHandle<Object> JSProxy::DeleteElementWithHandler(
-    Handle<JSProxy> proxy, uint32_t index, LanguageMode language_mode) {
-  Isolate* isolate = proxy->GetIsolate();
-  Handle<String> name = isolate->factory()->Uint32ToString(index);
-  return JSProxy::DeletePropertyWithHandler(proxy, name, language_mode);
-}
-
-
 Maybe<PropertyAttributes> JSProxy::GetPropertyAttributesWithHandler(
     Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name) {
   Isolate* isolate = proxy->GetIsolate();
@@ -5031,23 +5023,40 @@ Handle<Object> JSObject::SetHiddenPropertiesHashTable(Handle<JSObject> object,
 
 
 MaybeHandle<Object> JSObject::DeletePropertyWithInterceptor(
-    Handle<JSObject> holder, Handle<JSObject> receiver, Handle<Name> name) {
-  Isolate* isolate = holder->GetIsolate();
+    LookupIterator* it) {
+  Isolate* isolate = it->isolate();
+  // Make sure that the top context does not change when doing callbacks or
+  // interceptor calls.
+  AssertNoContextChange ncc(isolate);
 
-  Handle<InterceptorInfo> interceptor(holder->GetNamedInterceptor());
-  if (interceptor->deleter()->IsUndefined() ||
-      (name->IsSymbol() && !interceptor->can_intercept_symbols())) {
+  DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
+  Handle<InterceptorInfo> interceptor(it->GetInterceptor());
+  if (interceptor->deleter()->IsUndefined()) return MaybeHandle<Object>();
+
+  Handle<JSObject> holder = it->GetHolder<JSObject>();
+
+  PropertyCallbackArguments args(isolate, interceptor->data(),
+                                 *it->GetReceiver(), *holder);
+  v8::Handle<v8::Boolean> result;
+  if (it->IsElement()) {
+    uint32_t index = it->index();
+    v8::IndexedPropertyDeleterCallback deleter =
+        v8::ToCData<v8::IndexedPropertyDeleterCallback>(interceptor->deleter());
+    LOG(isolate,
+        ApiIndexedPropertyAccess("interceptor-indexed-delete", *holder, index));
+    result = args.Call(deleter, index);
+  } else if (it->name()->IsSymbol() && !interceptor->can_intercept_symbols()) {
     return MaybeHandle<Object>();
+  } else {
+    Handle<Name> name = it->name();
+    v8::GenericNamedPropertyDeleterCallback deleter =
+        v8::ToCData<v8::GenericNamedPropertyDeleterCallback>(
+            interceptor->deleter());
+    LOG(isolate,
+        ApiNamedPropertyAccess("interceptor-named-delete", *holder, *name));
+    result = args.Call(deleter, v8::Utils::ToLocal(name));
   }
 
-  v8::GenericNamedPropertyDeleterCallback deleter =
-      v8::ToCData<v8::GenericNamedPropertyDeleterCallback>(
-          interceptor->deleter());
-  LOG(isolate,
-      ApiNamedPropertyAccess("interceptor-named-delete", *holder, *name));
-  PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
-                                 *holder);
-  v8::Handle<v8::Boolean> result = args.Call(deleter, v8::Utils::ToLocal(name));
   RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
   if (result.IsEmpty()) return MaybeHandle<Object>();
 
@@ -5059,116 +5068,6 @@ MaybeHandle<Object> JSObject::DeletePropertyWithInterceptor(
 }
 
 
-MaybeHandle<Object> JSObject::DeleteElementWithInterceptor(
-    Handle<JSObject> object,
-    uint32_t index) {
-  Isolate* isolate = object->GetIsolate();
-  Factory* factory = isolate->factory();
-
-  // Make sure that the top context does not change when doing
-  // callbacks or interceptor calls.
-  AssertNoContextChange ncc(isolate);
-
-  Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor());
-  if (interceptor->deleter()->IsUndefined()) return factory->false_value();
-  v8::IndexedPropertyDeleterCallback deleter =
-      v8::ToCData<v8::IndexedPropertyDeleterCallback>(interceptor->deleter());
-  LOG(isolate,
-      ApiIndexedPropertyAccess("interceptor-indexed-delete", *object, index));
-  PropertyCallbackArguments args(
-      isolate, interceptor->data(), *object, *object);
-  v8::Handle<v8::Boolean> result = args.Call(deleter, index);
-  RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
-  if (!result.IsEmpty()) {
-    DCHECK(result->IsBoolean());
-    Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
-    result_internal->VerifyApiCallResultType();
-    // Rebox CustomArguments::kReturnValueOffset before returning.
-    return handle(*result_internal, isolate);
-  }
-  // TODO(verwaest): Shouldn't this be the mode that was passed in?
-  MaybeHandle<Object> delete_result =
-      object->GetElementsAccessor()->Delete(object, index, SLOPPY);
-  return delete_result;
-}
-
-
-MaybeHandle<Object> JSObject::DeleteElement(Handle<JSObject> object,
-                                            uint32_t index,
-                                            LanguageMode language_mode) {
-  Isolate* isolate = object->GetIsolate();
-  Factory* factory = isolate->factory();
-
-  // Check access rights if needed.
-  if (object->IsAccessCheckNeeded() && !isolate->MayAccess(object)) {
-    isolate->ReportFailedAccessCheck(object);
-    RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
-    return factory->false_value();
-  }
-
-  if (object->IsStringObjectWithCharacterAt(index)) {
-    if (is_strict(language_mode)) {
-      // Deleting a non-configurable property in strict mode.
-      Handle<Object> name = factory->NewNumberFromUint(index);
-      THROW_NEW_ERROR(
-          isolate,
-          NewTypeError(MessageTemplate::kStrictDeleteProperty, name, object),
-          Object);
-    }
-    return factory->false_value();
-  }
-
-  if (object->IsJSGlobalProxy()) {
-    PrototypeIterator iter(isolate, object);
-    if (iter.IsAtEnd()) return factory->false_value();
-    DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
-    return DeleteElement(
-        Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index,
-        language_mode);
-  }
-
-  Handle<Object> old_value;
-  bool should_enqueue_change_record = false;
-  if (object->map()->is_observed()) {
-    Maybe<bool> maybe = HasOwnElement(object, index);
-    if (!maybe.IsJust()) return MaybeHandle<Object>();
-    should_enqueue_change_record = maybe.FromJust();
-    if (should_enqueue_change_record) {
-      if (!GetOwnElementAccessorPair(object, index).is_null()) {
-        old_value = Handle<Object>::cast(factory->the_hole_value());
-      } else {
-        old_value = Object::GetElement(
-            isolate, object, index).ToHandleChecked();
-      }
-    }
-  }
-
-  // Skip interceptor if forcing deletion.
-  MaybeHandle<Object> maybe_result;
-  if (object->HasIndexedInterceptor()) {
-    maybe_result = DeleteElementWithInterceptor(object, index);
-  } else {
-    maybe_result =
-        object->GetElementsAccessor()->Delete(object, index, language_mode);
-  }
-  Handle<Object> result;
-  ASSIGN_RETURN_ON_EXCEPTION(isolate, result, maybe_result, Object);
-
-  if (should_enqueue_change_record) {
-    Maybe<bool> maybe = HasOwnElement(object, index);
-    if (!maybe.IsJust()) return MaybeHandle<Object>();
-    if (!maybe.FromJust()) {
-      Handle<String> name = factory->Uint32ToString(index);
-      RETURN_ON_EXCEPTION(
-          isolate, EnqueueChangeRecord(object, "delete", name, old_value),
-          Object);
-    }
-  }
-
-  return result;
-}
-
-
 void JSObject::DeleteNormalizedProperty(Handle<JSObject> object,
                                         Handle<Name> name) {
   DCHECK(!object->HasFastProperties());
@@ -5198,121 +5097,122 @@ void JSObject::DeleteNormalizedProperty(Handle<JSObject> object,
 }
 
 
-MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object,
-                                             Handle<Name> name,
-                                             LanguageMode language_mode) {
-  // ECMA-262, 3rd, 8.6.2.5
-  DCHECK(name->IsName());
-
-  uint32_t index = 0;
-  if (name->AsArrayIndex(&index)) {
-    return DeleteElement(object, index, language_mode);
+// ECMA-262, 3rd, 8.6.2.5
+MaybeHandle<Object> JSReceiver::DeleteProperty(LookupIterator* it,
+                                               LanguageMode language_mode) {
+  Isolate* isolate = it->isolate();
+  if (it->state() == LookupIterator::JSPROXY) {
+    return JSProxy::DeletePropertyWithHandler(it->GetHolder<JSProxy>(),
+                                              it->GetName(), language_mode);
   }
 
-  LookupIterator it(object, name, LookupIterator::HIDDEN);
+  Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver());
 
-  bool is_observed = object->map()->is_observed() &&
-                     !it.isolate()->IsInternallyUsedPropertyName(name);
-  Handle<Object> old_value = it.isolate()->factory()->the_hole_value();
+  bool is_observed =
+      receiver->map()->is_observed() &&
+      (it->IsElement() || !isolate->IsInternallyUsedPropertyName(it->name()));
 
-  for (; it.IsFound(); it.Next()) {
-    switch (it.state()) {
+  Handle<Object> old_value = it->factory()->the_hole_value();
+
+  for (; it->IsFound(); it->Next()) {
+    switch (it->state()) {
       case LookupIterator::JSPROXY:
       case LookupIterator::NOT_FOUND:
       case LookupIterator::TRANSITION:
         UNREACHABLE();
       case LookupIterator::ACCESS_CHECK:
-        if (it.HasAccess()) break;
-        it.isolate()->ReportFailedAccessCheck(it.GetHolder<JSObject>());
-        RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it.isolate(), Object);
-        return it.isolate()->factory()->false_value();
+        if (it->HasAccess()) break;
+        isolate->ReportFailedAccessCheck(it->GetHolder<JSObject>());
+        RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
+        return it->factory()->false_value();
       case LookupIterator::INTERCEPTOR: {
         MaybeHandle<Object> maybe_result =
-            JSObject::DeletePropertyWithInterceptor(it.GetHolder<JSObject>(),
-                                                    object, it.name());
+            JSObject::DeletePropertyWithInterceptor(it);
         // Delete with interceptor succeeded. Return result.
         if (!maybe_result.is_null()) return maybe_result;
         // An exception was thrown in the interceptor. Propagate.
-        if (it.isolate()->has_pending_exception()) return maybe_result;
+        if (isolate->has_pending_exception()) return maybe_result;
         break;
       }
       case LookupIterator::INTEGER_INDEXED_EXOTIC:
-        return it.isolate()->factory()->true_value();
+        return it->factory()->true_value();
       case LookupIterator::DATA:
         if (is_observed) {
-          old_value = it.GetDataValue();
+          old_value = it->GetDataValue();
         }
       // Fall through.
       case LookupIterator::ACCESSOR: {
-        if (!it.IsConfigurable() || object->map()->is_strong()) {
+        if (!it->IsConfigurable() || receiver->map()->is_strong()) {
           // Fail if the property is not configurable, or on a strong object.
           if (is_strict(language_mode)) {
-            if (object->map()->is_strong()) {
+            if (receiver->map()->is_strong()) {
               THROW_NEW_ERROR(
-                  it.isolate(),
-                  NewTypeError(MessageTemplate::kStrongDeleteProperty, object,
-                               name),
+                  isolate, NewTypeError(MessageTemplate::kStrongDeleteProperty,
+                                        receiver, it->GetName()),
                   Object);
             }
-            THROW_NEW_ERROR(it.isolate(),
+            THROW_NEW_ERROR(isolate,
                             NewTypeError(MessageTemplate::kStrictDeleteProperty,
-                                         name, object),
+                                         it->GetName(), receiver),
                             Object);
           }
-          return it.isolate()->factory()->false_value();
+          return it->factory()->false_value();
         }
 
-        PropertyNormalizationMode mode = object->map()->is_prototype_map()
-                                             ? KEEP_INOBJECT_PROPERTIES
-                                             : CLEAR_INOBJECT_PROPERTIES;
-        Handle<JSObject> holder = it.GetHolder<JSObject>();
+        Handle<JSObject> holder = it->GetHolder<JSObject>();
         // TODO(verwaest): Remove this temporary compatibility hack when blink
         // tests are updated.
-        if (!holder.is_identical_to(object) &&
-            !(object->IsJSGlobalProxy() && holder->IsJSGlobalObject())) {
-          return it.isolate()->factory()->true_value();
+        if (!holder.is_identical_to(receiver) &&
+            !(receiver->IsJSGlobalProxy() && holder->IsJSGlobalObject())) {
+          return it->factory()->true_value();
         }
 
-        NormalizeProperties(holder, mode, 0, "DeletingProperty");
-        DeleteNormalizedProperty(holder, name);
-        ReoptimizeIfPrototype(holder);
+        if (it->IsElement()) {
+          ElementsAccessor* accessor = holder->GetElementsAccessor();
+          accessor->Delete(holder, it->index(), language_mode);
+        } else {
+          PropertyNormalizationMode mode = holder->map()->is_prototype_map()
+                                               ? KEEP_INOBJECT_PROPERTIES
+                                               : CLEAR_INOBJECT_PROPERTIES;
+
+          JSObject::NormalizeProperties(holder, mode, 0, "DeletingProperty");
+          JSObject::DeleteNormalizedProperty(holder, it->name());
+          JSObject::ReoptimizeIfPrototype(holder);
+        }
 
         if (is_observed) {
-          RETURN_ON_EXCEPTION(
-              it.isolate(),
-              EnqueueChangeRecord(object, "delete", name, old_value), Object);
+          RETURN_ON_EXCEPTION(isolate,
+                              JSObject::EnqueueChangeRecord(
+                                  receiver, "delete", it->GetName(), old_value),
+                              Object);
         }
 
-        return it.isolate()->factory()->true_value();
+        return it->factory()->true_value();
       }
     }
   }
 
-  return it.isolate()->factory()->true_value();
+  return it->factory()->true_value();
 }
 
 
 MaybeHandle<Object> JSReceiver::DeleteElement(Handle<JSReceiver> object,
                                               uint32_t index,
                                               LanguageMode language_mode) {
-  if (object->IsJSProxy()) {
-    return JSProxy::DeleteElementWithHandler(Handle<JSProxy>::cast(object),
-                                             index, language_mode);
-  }
-  return JSObject::DeleteElement(Handle<JSObject>::cast(object), index,
-                                 language_mode);
+  LookupIterator it(object->GetIsolate(), object, index);
+  return DeleteProperty(&it, language_mode);
 }
 
 
 MaybeHandle<Object> JSReceiver::DeleteProperty(Handle<JSReceiver> object,
                                                Handle<Name> name,
                                                LanguageMode language_mode) {
-  if (object->IsJSProxy()) {
-    return JSProxy::DeletePropertyWithHandler(Handle<JSProxy>::cast(object),
-                                              name, language_mode);
-  }
-  return JSObject::DeleteProperty(Handle<JSObject>::cast(object), name,
-                                  language_mode);
+  uint32_t index;
+  LookupIterator::Configuration c = LookupIterator::HIDDEN;
+  LookupIterator it = name->AsArrayIndex(&index)
+                          ? LookupIterator(name->GetIsolate(), object, index, c)
+                          : LookupIterator(object, name, c);
+  return JSObject::DeleteProperty(&it, language_mode);
 }
 
 
index 1a1cb0932f66fe6b14d09ba2704f72d26ec54c62..4f78eb16bce0fda15784457623c551a70f2ca5c6 100644 (file)
@@ -1658,6 +1658,8 @@ class JSReceiver: public HeapObject {
   MUST_USE_RESULT static MaybeHandle<Object> DeleteProperty(
       Handle<JSReceiver> object, Handle<Name> name,
       LanguageMode language_mode = SLOPPY);
+  MUST_USE_RESULT static MaybeHandle<Object> DeleteProperty(
+      LookupIterator* it, LanguageMode language_mode);
   MUST_USE_RESULT static MaybeHandle<Object> DeleteElement(
       Handle<JSReceiver> object, uint32_t index,
       LanguageMode language_mode = SLOPPY);
@@ -2325,21 +2327,13 @@ class JSObject: public JSReceiver {
                               Handle<Object> value,
                               PropertyAttributes attributes);
 
-  MUST_USE_RESULT static MaybeHandle<Object> DeleteProperty(
-      Handle<JSObject> object, Handle<Name> name, LanguageMode language_mode);
   MUST_USE_RESULT static MaybeHandle<Object> DeletePropertyWithInterceptor(
-      Handle<JSObject> holder, Handle<JSObject> receiver, Handle<Name> name);
+      LookupIterator* it);
 
   // Deletes an existing named property in a normalized object.
   static void DeleteNormalizedProperty(Handle<JSObject> object,
                                        Handle<Name> name);
 
-  MUST_USE_RESULT static MaybeHandle<Object> DeleteElement(
-      Handle<JSObject> object, uint32_t index, LanguageMode language_mode);
-  MUST_USE_RESULT static MaybeHandle<Object> DeleteElementWithInterceptor(
-      Handle<JSObject> object,
-      uint32_t index);
-
   bool ReferencesObjectFromElements(FixedArray* elements,
                                     ElementsKind kind,
                                     Object* object);
@@ -10032,13 +10026,9 @@ class JSProxy: public JSReceiver {
 
   MUST_USE_RESULT static Maybe<bool> HasPropertyWithHandler(
       Handle<JSProxy> proxy, Handle<Name> name);
-  MUST_USE_RESULT static inline Maybe<bool> HasElementWithHandler(
-      Handle<JSProxy> proxy, uint32_t index);
 
   MUST_USE_RESULT static MaybeHandle<Object> DeletePropertyWithHandler(
       Handle<JSProxy> proxy, Handle<Name> name, LanguageMode language_mode);
-  MUST_USE_RESULT static MaybeHandle<Object> DeleteElementWithHandler(
-      Handle<JSProxy> proxy, uint32_t index, LanguageMode language_mode);
 
   MUST_USE_RESULT Object* GetIdentityHash();