Handlify JSObject::DeleteElement method.
authormstarzinger@chromium.org <mstarzinger@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 29 Aug 2013 18:01:45 +0000 (18:01 +0000)
committermstarzinger@chromium.org <mstarzinger@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 29 Aug 2013 18:01:45 +0000 (18:01 +0000)
R=verwaest@chromium.org

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

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

src/api.cc
src/objects.cc
src/objects.h

index 43c920d..643a5b4 100644 (file)
@@ -3571,7 +3571,7 @@ bool v8::Object::Delete(uint32_t index) {
   ENTER_V8(isolate);
   HandleScope scope(reinterpret_cast<Isolate*>(isolate));
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
-  return i::JSObject::DeleteElement(self, index)->IsTrue();
+  return i::JSReceiver::DeleteElement(self, index)->IsTrue();
 }
 
 
index 2d91712..8cf74ad 100644 (file)
@@ -5031,113 +5031,110 @@ Handle<Object> JSObject::DeletePropertyWithInterceptor(Handle<JSObject> object,
 }
 
 
-MaybeObject* JSObject::DeleteElementWithInterceptor(uint32_t index) {
-  Isolate* isolate = GetIsolate();
-  Heap* heap = isolate->heap();
-  HandleScope scope(isolate);
+// TODO(mstarzinger): Temporary wrapper until handlified.
+static Handle<Object> AccessorDelete(Handle<JSObject> object,
+                                     uint32_t index,
+                                     JSObject::DeleteMode mode) {
+  CALL_HEAP_FUNCTION(object->GetIsolate(),
+                     object->GetElementsAccessor()->Delete(*object,
+                                                           index,
+                                                           mode),
+                     Object);
+}
+
+
+Handle<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;
 
-  Handle<InterceptorInfo> interceptor(GetIndexedInterceptor());
-  if (interceptor->deleter()->IsUndefined()) return heap->false_value();
+  Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor());
+  if (interceptor->deleter()->IsUndefined()) return factory->false_value();
   v8::IndexedPropertyDeleterCallback deleter =
       v8::ToCData<v8::IndexedPropertyDeleterCallback>(interceptor->deleter());
-  Handle<JSObject> this_handle(this);
   LOG(isolate,
-      ApiIndexedPropertyAccess("interceptor-indexed-delete", this, index));
-  PropertyCallbackArguments args(isolate, interceptor->data(), this, this);
+      ApiIndexedPropertyAccess("interceptor-indexed-delete", *object, index));
+  PropertyCallbackArguments args(
+      isolate, interceptor->data(), *object, *object);
   v8::Handle<v8::Boolean> result = args.Call(deleter, index);
-  RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+  RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
   if (!result.IsEmpty()) {
     ASSERT(result->IsBoolean());
     Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
     result_internal->VerifyApiCallResultType();
-    return *result_internal;
+    // Rebox CustomArguments::kReturnValueOffset before returning.
+    return handle(*result_internal, isolate);
   }
-  MaybeObject* raw_result = this_handle->GetElementsAccessor()->Delete(
-      *this_handle,
-      index,
-      NORMAL_DELETION);
-  RETURN_IF_SCHEDULED_EXCEPTION(isolate);
-  return raw_result;
+  Handle<Object> delete_result = AccessorDelete(object, index, NORMAL_DELETION);
+  RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+  return delete_result;
 }
 
 
-Handle<Object> JSObject::DeleteElement(Handle<JSObject> obj,
+Handle<Object> JSObject::DeleteElement(Handle<JSObject> object,
                                        uint32_t index,
                                        DeleteMode mode) {
-  CALL_HEAP_FUNCTION(obj->GetIsolate(),
-                     obj->DeleteElement(index, mode),
-                     Object);
-}
-
+  Isolate* isolate = object->GetIsolate();
+  Factory* factory = isolate->factory();
 
-MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) {
-  Isolate* isolate = GetIsolate();
   // Check access rights if needed.
-  if (IsAccessCheckNeeded() &&
-      !isolate->MayIndexedAccess(this, index, v8::ACCESS_DELETE)) {
-    isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE);
-    RETURN_IF_SCHEDULED_EXCEPTION(isolate);
-    return isolate->heap()->false_value();
+  if (object->IsAccessCheckNeeded() &&
+      !isolate->MayIndexedAccess(*object, index, v8::ACCESS_DELETE)) {
+    isolate->ReportFailedAccessCheck(*object, v8::ACCESS_DELETE);
+    RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+    return factory->false_value();
   }
 
-  if (IsStringObjectWithCharacterAt(index)) {
+  if (object->IsStringObjectWithCharacterAt(index)) {
     if (mode == STRICT_DELETION) {
       // Deleting a non-configurable property in strict mode.
-      HandleScope scope(isolate);
-      Handle<Object> holder(this, isolate);
-      Handle<Object> name = isolate->factory()->NewNumberFromUint(index);
-      Handle<Object> args[2] = { name, holder };
+      Handle<Object> name = factory->NewNumberFromUint(index);
+      Handle<Object> args[2] = { name, object };
       Handle<Object> error =
-          isolate->factory()->NewTypeError("strict_delete_property",
-                                           HandleVector(args, 2));
-      return isolate->Throw(*error);
+          factory->NewTypeError("strict_delete_property",
+                                HandleVector(args, 2));
+      isolate->Throw(*error);
+      return Handle<Object>();
     }
-    return isolate->heap()->false_value();
+    return factory->false_value();
   }
 
-  if (IsJSGlobalProxy()) {
-    Object* proto = GetPrototype();
-    if (proto->IsNull()) return isolate->heap()->false_value();
+  if (object->IsJSGlobalProxy()) {
+    Handle<Object> proto(object->GetPrototype(), isolate);
+    if (proto->IsNull()) return factory->false_value();
     ASSERT(proto->IsJSGlobalObject());
-    return JSGlobalObject::cast(proto)->DeleteElement(index, mode);
+    return DeleteElement(Handle<JSObject>::cast(proto), index, mode);
   }
 
-  // From this point on everything needs to be handlified.
-  HandleScope scope(isolate);
-  Handle<JSObject> self(this);
-
   Handle<Object> old_value;
   bool should_enqueue_change_record = false;
-  if (FLAG_harmony_observation && self->map()->is_observed()) {
-    should_enqueue_change_record = self->HasLocalElement(index);
+  if (FLAG_harmony_observation && object->map()->is_observed()) {
+    should_enqueue_change_record = object->HasLocalElement(index);
     if (should_enqueue_change_record) {
-      old_value = self->GetLocalElementAccessorPair(index) != NULL
-          ? Handle<Object>::cast(isolate->factory()->the_hole_value())
-          : Object::GetElement(self, index);
+      old_value = object->GetLocalElementAccessorPair(index) != NULL
+          ? Handle<Object>::cast(factory->the_hole_value())
+          : Object::GetElement(object, index);
     }
   }
 
-  MaybeObject* result;
   // Skip interceptor if forcing deletion.
-  if (self->HasIndexedInterceptor() && mode != FORCE_DELETION) {
-    result = self->DeleteElementWithInterceptor(index);
+  Handle<Object> result;
+  if (object->HasIndexedInterceptor() && mode != FORCE_DELETION) {
+    result = DeleteElementWithInterceptor(object, index);
   } else {
-    result = self->GetElementsAccessor()->Delete(*self, index, mode);
+    result = AccessorDelete(object, index, mode);
   }
 
-  Handle<Object> hresult;
-  if (!result->ToHandle(&hresult, isolate)) return result;
-
-  if (should_enqueue_change_record && !self->HasLocalElement(index)) {
-    Handle<String> name = isolate->factory()->Uint32ToString(index);
-    EnqueueChangeRecord(self, "deleted", name, old_value);
+  if (should_enqueue_change_record && !object->HasLocalElement(index)) {
+    Handle<String> name = factory->Uint32ToString(index);
+    EnqueueChangeRecord(object, "deleted", name, old_value);
   }
 
-  return *hresult;
+  return result;
 }
 
 
index 040664d..d42b908 100644 (file)
@@ -1982,7 +1982,7 @@ class JSReceiver: public HeapObject {
                                        DeleteMode mode = NORMAL_DELETION);
   static Handle<Object> DeleteElement(Handle<JSReceiver> object,
                                       uint32_t index,
-                                      DeleteMode mode);
+                                      DeleteMode mode = NORMAL_DELETION);
 
   // Set the index'th array element.
   // Can cause GC, or return failure if GC is required.
@@ -2320,11 +2320,6 @@ class JSObject: public JSReceiver {
   MUST_USE_RESULT MaybeObject* GetIdentityHash(CreationFlag flag);
   MUST_USE_RESULT MaybeObject* SetIdentityHash(Smi* hash, CreationFlag flag);
 
-  static Handle<Object> DeleteElement(Handle<JSObject> obj,
-                                      uint32_t index,
-                                      DeleteMode mode = NORMAL_DELETION);
-  MUST_USE_RESULT MaybeObject* DeleteElement(uint32_t index, DeleteMode mode);
-
   inline void ValidateElements();
 
   // Makes sure that this object can contain HeapObject as elements.
@@ -2812,7 +2807,11 @@ class JSObject: public JSReceiver {
                                                  Handle<Name> name,
                                                  DeleteMode mode);
 
-  MUST_USE_RESULT MaybeObject* DeleteElementWithInterceptor(uint32_t index);
+  static Handle<Object> DeleteElement(Handle<JSObject> object,
+                                      uint32_t index,
+                                      DeleteMode mode);
+  static Handle<Object> DeleteElementWithInterceptor(Handle<JSObject> object,
+                                                     uint32_t index);
 
   MUST_USE_RESULT MaybeObject* DeleteFastElement(uint32_t index);
   MUST_USE_RESULT MaybeObject* DeleteDictionaryElement(uint32_t index,