From dfc945d5943cff21f20d10c7d0a6931b885794df Mon Sep 17 00:00:00 2001 From: "mstarzinger@chromium.org" Date: Wed, 17 Jul 2013 16:38:49 +0000 Subject: [PATCH] Handlify JSReceiver/JSObject::DeleteProperty method. R=verwaest@chromium.org Review URL: https://codereview.chromium.org/18774002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15730 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/isolate.h | 9 ++ src/objects.cc | 254 +++++++++++++++++++++++------------------------ src/objects.h | 55 ++++++---- src/runtime.cc | 27 +++-- test/cctest/test-heap.cc | 10 +- 5 files changed, 191 insertions(+), 164 deletions(-) diff --git a/src/isolate.h b/src/isolate.h index a0aecd8..c0ea772 100644 --- a/src/isolate.h +++ b/src/isolate.h @@ -124,6 +124,15 @@ typedef ZoneList > ZoneObjectList; } \ } while (false) +#define RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, T) \ + do { \ + Isolate* __isolate__ = (isolate); \ + if (__isolate__->has_scheduled_exception()) { \ + __isolate__->PromoteScheduledException(); \ + return Handle::null(); \ + } \ + } while (false) + #define RETURN_IF_EMPTY_HANDLE_VALUE(isolate, call, value) \ do { \ if ((call).is_null()) { \ diff --git a/src/objects.cc b/src/objects.cc index 8bbbd3e..bb6b4fd 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -715,46 +715,54 @@ MaybeObject* JSObject::SetNormalizedProperty(Name* name, } -MaybeObject* JSObject::DeleteNormalizedProperty(Name* name, DeleteMode mode) { - ASSERT(!HasFastProperties()); - NameDictionary* dictionary = property_dictionary(); - int entry = dictionary->FindEntry(name); +// TODO(mstarzinger): Temporary wrapper until target is handlified. +Handle NameDictionaryShrink(Handle dict, + Handle name) { + CALL_HEAP_FUNCTION(dict->GetIsolate(), dict->Shrink(*name), NameDictionary); +} + + +static void CellSetValueInferType(Handle cell, + Handle value) { + CALL_HEAP_FUNCTION_VOID(cell->GetIsolate(), cell->SetValueInferType(*value)); +} + + +Handle JSObject::DeleteNormalizedProperty(Handle object, + Handle name, + DeleteMode mode) { + ASSERT(!object->HasFastProperties()); + Isolate* isolate = object->GetIsolate(); + Handle dictionary(object->property_dictionary()); + int entry = dictionary->FindEntry(*name); if (entry != NameDictionary::kNotFound) { // If we have a global object set the cell to the hole. - if (IsGlobalObject()) { + if (object->IsGlobalObject()) { PropertyDetails details = dictionary->DetailsAt(entry); if (details.IsDontDelete()) { - if (mode != FORCE_DELETION) return GetHeap()->false_value(); + if (mode != FORCE_DELETION) return isolate->factory()->false_value(); // When forced to delete global properties, we have to make a // map change to invalidate any ICs that think they can load // from the DontDelete cell without checking if it contains // the hole value. - Map* new_map; - MaybeObject* maybe_new_map = map()->CopyDropDescriptors(); - if (!maybe_new_map->To(&new_map)) return maybe_new_map; - + Handle new_map = Map::CopyDropDescriptors(handle(object->map())); ASSERT(new_map->is_dictionary_map()); - set_map(new_map); + object->set_map(*new_map); } - PropertyCell* cell = PropertyCell::cast(dictionary->ValueAt(entry)); - MaybeObject* maybe_type = - cell->SetValueInferType(cell->GetHeap()->the_hole_value()); - if (maybe_type->IsFailure()) return maybe_type; + Handle cell(PropertyCell::cast(dictionary->ValueAt(entry))); + CellSetValueInferType(cell, isolate->factory()->the_hole_value()); dictionary->DetailsAtPut(entry, details.AsDeleted()); } else { - Object* deleted = dictionary->DeleteProperty(entry, mode); - if (deleted == GetHeap()->true_value()) { - FixedArray* new_properties = NULL; - MaybeObject* maybe_properties = dictionary->Shrink(name); - if (!maybe_properties->To(&new_properties)) { - return maybe_properties; - } - set_properties(new_properties); + Handle deleted(dictionary->DeleteProperty(entry, mode), isolate); + if (*deleted == isolate->heap()->true_value()) { + Handle new_properties = + NameDictionaryShrink(dictionary, name); + object->set_properties(*new_properties); } return deleted; } } - return GetHeap()->true_value(); + return isolate->factory()->true_value(); } @@ -3535,43 +3543,38 @@ MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyViaPrototypesWithHandler( } -MUST_USE_RESULT MaybeObject* JSProxy::DeletePropertyWithHandler( - Name* name_raw, DeleteMode mode) { - Isolate* isolate = GetIsolate(); - HandleScope scope(isolate); - Handle receiver(this); - Handle name(name_raw, isolate); +Handle JSProxy::DeletePropertyWithHandler( + Handle object, Handle name, DeleteMode mode) { + Isolate* isolate = object->GetIsolate(); // TODO(rossberg): adjust once there is a story for symbols vs proxies. - if (name->IsSymbol()) return isolate->heap()->false_value(); + if (name->IsSymbol()) return isolate->factory()->false_value(); Handle args[] = { name }; - Handle result = CallTrap( - "delete", Handle(), ARRAY_SIZE(args), args); - if (isolate->has_pending_exception()) return Failure::Exception(); + Handle result = object->CallTrap( + "delete", Handle(), ARRAY_SIZE(args), args); + if (isolate->has_pending_exception()) return Handle(); bool result_bool = result->BooleanValue(); if (mode == STRICT_DELETION && !result_bool) { - Handle handler(receiver->handler(), isolate); + Handle handler(object->handler(), isolate); Handle trap_name = isolate->factory()->InternalizeOneByteString( STATIC_ASCII_VECTOR("delete")); Handle args[] = { handler, trap_name }; Handle error = isolate->factory()->NewTypeError( "handler_failed", HandleVector(args, ARRAY_SIZE(args))); isolate->Throw(*error); - return Failure::Exception(); + return Handle(); } - return isolate->heap()->ToBoolean(result_bool); + return isolate->factory()->ToBoolean(result_bool); } -MUST_USE_RESULT MaybeObject* JSProxy::DeleteElementWithHandler( - uint32_t index, - DeleteMode mode) { - Isolate* isolate = GetIsolate(); - HandleScope scope(isolate); +Handle JSProxy::DeleteElementWithHandler( + Handle object, uint32_t index, DeleteMode mode) { + Isolate* isolate = object->GetIsolate(); Handle name = isolate->factory()->Uint32ToString(index); - return JSProxy::DeletePropertyWithHandler(*name, mode); + return JSProxy::DeletePropertyWithHandler(object, name, mode); } @@ -4972,52 +4975,52 @@ MaybeObject* JSObject::SetHiddenPropertiesHashTable(Object* value) { } -MaybeObject* JSObject::DeletePropertyPostInterceptor(Name* name, - DeleteMode mode) { +Handle JSObject::DeletePropertyPostInterceptor(Handle object, + Handle name, + DeleteMode mode) { // Check local property, ignore interceptor. - LookupResult result(GetIsolate()); - LocalLookupRealNamedProperty(name, &result); - if (!result.IsFound()) return GetHeap()->true_value(); + Isolate* isolate = object->GetIsolate(); + LookupResult result(isolate); + object->LocalLookupRealNamedProperty(*name, &result); + if (!result.IsFound()) return isolate->factory()->true_value(); // Normalize object if needed. - Object* obj; - { MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); - if (!maybe_obj->ToObject(&obj)) return maybe_obj; - } + NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); - return DeleteNormalizedProperty(name, mode); + return DeleteNormalizedProperty(object, name, mode); } -MaybeObject* JSObject::DeletePropertyWithInterceptor(Name* name) { +Handle JSObject::DeletePropertyWithInterceptor(Handle object, + Handle name) { + Isolate* isolate = object->GetIsolate(); + // TODO(rossberg): Support symbols in the API. - if (name->IsSymbol()) return GetHeap()->false_value(); + if (name->IsSymbol()) return isolate->factory()->false_value(); - Isolate* isolate = GetIsolate(); - HandleScope scope(isolate); - Handle interceptor(GetNamedInterceptor()); - Handle name_handle(String::cast(name)); - Handle this_handle(this); + Handle interceptor(object->GetNamedInterceptor()); if (!interceptor->deleter()->IsUndefined()) { v8::NamedPropertyDeleter deleter = v8::ToCData(interceptor->deleter()); LOG(isolate, - ApiNamedPropertyAccess("interceptor-named-delete", *this_handle, name)); - PropertyCallbackArguments args(isolate, interceptor->data(), this, this); + ApiNamedPropertyAccess("interceptor-named-delete", *object, *name)); + PropertyCallbackArguments args( + isolate, interceptor->data(), *object, *object); v8::Handle result = - args.Call(deleter, v8::Utils::ToLocal(name_handle)); - RETURN_IF_SCHEDULED_EXCEPTION(isolate); + args.Call(deleter, v8::Utils::ToLocal(Handle::cast(name))); + RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); if (!result.IsEmpty()) { ASSERT(result->IsBoolean()); Handle 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->DeletePropertyPostInterceptor(*name_handle, NORMAL_DELETION); - RETURN_IF_SCHEDULED_EXCEPTION(isolate); - return raw_result; + Handle result = + DeletePropertyPostInterceptor(object, name, NORMAL_DELETION); + RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); + return result; } @@ -5054,9 +5057,10 @@ MaybeObject* JSObject::DeleteElementWithInterceptor(uint32_t index) { Handle JSObject::DeleteElement(Handle obj, - uint32_t index) { + uint32_t index, + DeleteMode mode) { CALL_HEAP_FUNCTION(obj->GetIsolate(), - obj->DeleteElement(index, JSObject::NORMAL_DELETION), + obj->DeleteElement(index, mode), Object); } @@ -5128,108 +5132,99 @@ MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) { } -Handle JSObject::DeleteProperty(Handle obj, - Handle prop) { - CALL_HEAP_FUNCTION(obj->GetIsolate(), - obj->DeleteProperty(*prop, JSObject::NORMAL_DELETION), - Object); -} - - -MaybeObject* JSObject::DeleteProperty(Name* name, DeleteMode mode) { - Isolate* isolate = GetIsolate(); +Handle JSObject::DeleteProperty(Handle object, + Handle name, + DeleteMode mode) { + Isolate* isolate = object->GetIsolate(); // ECMA-262, 3rd, 8.6.2.5 ASSERT(name->IsName()); // Check access rights if needed. - if (IsAccessCheckNeeded() && - !isolate->MayNamedAccess(this, name, v8::ACCESS_DELETE)) { - isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE); - RETURN_IF_SCHEDULED_EXCEPTION(isolate); - return isolate->heap()->false_value(); + if (object->IsAccessCheckNeeded() && + !isolate->MayNamedAccess(*object, *name, v8::ACCESS_DELETE)) { + isolate->ReportFailedAccessCheck(*object, v8::ACCESS_DELETE); + RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); + return isolate->factory()->false_value(); } - if (IsJSGlobalProxy()) { - Object* proto = GetPrototype(); - if (proto->IsNull()) return isolate->heap()->false_value(); + if (object->IsJSGlobalProxy()) { + Object* proto = object->GetPrototype(); + if (proto->IsNull()) return isolate->factory()->false_value(); ASSERT(proto->IsJSGlobalObject()); - return JSGlobalObject::cast(proto)->DeleteProperty(name, mode); + return JSGlobalObject::DeleteProperty( + handle(JSGlobalObject::cast(proto)), name, mode); } uint32_t index = 0; if (name->AsArrayIndex(&index)) { - return DeleteElement(index, mode); + return DeleteElement(object, index, mode); } LookupResult lookup(isolate); - LocalLookup(name, &lookup, true); - if (!lookup.IsFound()) return isolate->heap()->true_value(); + object->LocalLookup(*name, &lookup, true); + if (!lookup.IsFound()) return isolate->factory()->true_value(); // Ignore attributes if forcing a deletion. if (lookup.IsDontDelete() && mode != FORCE_DELETION) { if (mode == STRICT_DELETION) { // Deleting a non-configurable property in strict mode. - HandleScope scope(isolate); - Handle args[2] = { Handle(name, isolate), - Handle(this, isolate) }; - return isolate->Throw(*isolate->factory()->NewTypeError( - "strict_delete_property", HandleVector(args, 2))); + Handle args[2] = { name, object }; + Handle error = isolate->factory()->NewTypeError( + "strict_delete_property", HandleVector(args, ARRAY_SIZE(args))); + isolate->Throw(*error); + return Handle(); } - return isolate->heap()->false_value(); + return isolate->factory()->false_value(); } - // From this point on everything needs to be handlified. - HandleScope scope(isolate); - Handle self(this); - Handle hname(name); - Handle old_value = isolate->factory()->the_hole_value(); - bool is_observed = FLAG_harmony_observation && self->map()->is_observed(); + bool is_observed = FLAG_harmony_observation && object->map()->is_observed(); if (is_observed && lookup.IsDataProperty()) { - old_value = Object::GetProperty(self, hname); + old_value = Object::GetProperty(object, name); } - MaybeObject* result; + Handle result; // Check for interceptor. if (lookup.IsInterceptor()) { // Skip interceptor if forcing a deletion. if (mode == FORCE_DELETION) { - result = self->DeletePropertyPostInterceptor(*hname, mode); + result = DeletePropertyPostInterceptor(object, name, mode); } else { - result = self->DeletePropertyWithInterceptor(*hname); + result = DeletePropertyWithInterceptor(object, name); } } else { // Normalize object if needed. - Object* obj; - result = self->NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); - if (!result->To(&obj)) return result; + NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); // Make sure the properties are normalized before removing the entry. - result = self->DeleteNormalizedProperty(*hname, mode); + result = DeleteNormalizedProperty(object, name, mode); } - Handle hresult; - if (!result->ToHandle(&hresult, isolate)) return result; - - if (is_observed && !self->HasLocalProperty(*hname)) { - EnqueueChangeRecord(self, "deleted", hname, old_value); + if (is_observed && !object->HasLocalProperty(*name)) { + EnqueueChangeRecord(object, "deleted", name, old_value); } - return *hresult; + return result; } -MaybeObject* JSReceiver::DeleteElement(uint32_t index, DeleteMode mode) { - if (IsJSProxy()) { - return JSProxy::cast(this)->DeleteElementWithHandler(index, mode); +Handle JSReceiver::DeleteElement(Handle object, + uint32_t index, + DeleteMode mode) { + if (object->IsJSProxy()) { + return JSProxy::DeleteElementWithHandler( + Handle::cast(object), index, mode); } - return JSObject::cast(this)->DeleteElement(index, mode); + return JSObject::DeleteElement(Handle::cast(object), index, mode); } -MaybeObject* JSReceiver::DeleteProperty(Name* name, DeleteMode mode) { - if (IsJSProxy()) { - return JSProxy::cast(this)->DeletePropertyWithHandler(name, mode); +Handle JSReceiver::DeleteProperty(Handle object, + Handle name, + DeleteMode mode) { + if (object->IsJSProxy()) { + return JSProxy::DeletePropertyWithHandler( + Handle::cast(object), name, mode); } - return JSObject::cast(this)->DeleteProperty(name, mode); + return JSObject::DeleteProperty(Handle::cast(object), name, mode); } @@ -6511,6 +6506,11 @@ MaybeObject* Map::CopyNormalized(PropertyNormalizationMode mode, } +Handle Map::CopyDropDescriptors(Handle map) { + CALL_HEAP_FUNCTION(map->GetIsolate(), map->CopyDropDescriptors(), Map); +} + + MaybeObject* Map::CopyDropDescriptors() { Map* result; MaybeObject* maybe_result = RawCopy(instance_size()); diff --git a/src/objects.h b/src/objects.h index 9530e4d..3f8ff36 100644 --- a/src/objects.h +++ b/src/objects.h @@ -1666,8 +1666,12 @@ class JSReceiver: public HeapObject { MUST_USE_RESULT MaybeObject* SetPropertyWithDefinedSetter(JSReceiver* setter, Object* value); - MUST_USE_RESULT MaybeObject* DeleteProperty(Name* name, DeleteMode mode); - MUST_USE_RESULT MaybeObject* DeleteElement(uint32_t index, DeleteMode mode); + static Handle DeleteProperty(Handle object, + Handle name, + DeleteMode mode = NORMAL_DELETION); + static Handle DeleteElement(Handle object, + uint32_t index, + DeleteMode mode); // Set the index'th array element. // Can cause GC, or return failure if GC is required. @@ -1911,10 +1915,6 @@ class JSObject: public JSReceiver { Object* value, PropertyDetails details); - // Deletes the named property in a normalized object. - MUST_USE_RESULT MaybeObject* DeleteNormalizedProperty(Name* name, - DeleteMode mode); - static void OptimizeAsPrototype(Handle object); MUST_USE_RESULT MaybeObject* OptimizeAsPrototype(); @@ -2005,12 +2005,9 @@ class JSObject: public JSReceiver { MUST_USE_RESULT MaybeObject* GetIdentityHash(CreationFlag flag); MUST_USE_RESULT MaybeObject* SetIdentityHash(Smi* hash, CreationFlag flag); - static Handle DeleteProperty(Handle obj, - Handle name); - // Can cause GC. - MUST_USE_RESULT MaybeObject* DeleteProperty(Name* name, DeleteMode mode); - - static Handle DeleteElement(Handle obj, uint32_t index); + static Handle DeleteElement(Handle obj, + uint32_t index, + DeleteMode mode = NORMAL_DELETION); MUST_USE_RESULT MaybeObject* DeleteElement(uint32_t index, DeleteMode mode); inline void ValidateElements(); @@ -2443,6 +2440,7 @@ class JSObject: public JSReceiver { private: friend class DictionaryElementsAccessor; + friend class JSReceiver; MUST_USE_RESULT MaybeObject* GetElementWithCallback(Object* receiver, Object* structure, @@ -2488,9 +2486,19 @@ class JSObject: public JSReceiver { StrictModeFlag strict_mode, bool* done); - MUST_USE_RESULT MaybeObject* DeletePropertyPostInterceptor(Name* name, - DeleteMode mode); - MUST_USE_RESULT MaybeObject* DeletePropertyWithInterceptor(Name* name); + static Handle DeleteProperty(Handle object, + Handle name, + DeleteMode mode); + static Handle DeletePropertyPostInterceptor(Handle object, + Handle name, + DeleteMode mode); + static Handle DeletePropertyWithInterceptor(Handle object, + Handle name); + + // Deletes the named property in a normalized object. + static Handle DeleteNormalizedProperty(Handle object, + Handle name, + DeleteMode mode); MUST_USE_RESULT MaybeObject* DeleteElementWithInterceptor(uint32_t index); @@ -5460,6 +5468,7 @@ class Map: public HeapObject { MUST_USE_RESULT MaybeObject* RawCopy(int instance_size); MUST_USE_RESULT MaybeObject* CopyWithPreallocatedFieldDescriptors(); + static Handle CopyDropDescriptors(Handle map); MUST_USE_RESULT MaybeObject* CopyDropDescriptors(); MUST_USE_RESULT MaybeObject* CopyReplaceDescriptors( DescriptorArray* descriptors, @@ -8739,13 +8748,6 @@ class JSProxy: public JSReceiver { StrictModeFlag strict_mode, bool* done); - MUST_USE_RESULT MaybeObject* DeletePropertyWithHandler( - Name* name, - DeleteMode mode); - MUST_USE_RESULT MaybeObject* DeleteElementWithHandler( - uint32_t index, - DeleteMode mode); - MUST_USE_RESULT PropertyAttributes GetPropertyAttributeWithHandler( JSReceiver* receiver, Name* name); @@ -8789,6 +8791,15 @@ class JSProxy: public JSReceiver { kSize> BodyDescriptor; private: + friend class JSReceiver; + + static Handle DeletePropertyWithHandler(Handle object, + Handle name, + DeleteMode mode); + static Handle DeleteElementWithHandler(Handle object, + uint32_t index, + DeleteMode mode); + DISALLOW_IMPLICIT_CONSTRUCTORS(JSProxy); }; diff --git a/src/runtime.cc b/src/runtime.cc index c894363..c22a7f6 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -5159,7 +5159,9 @@ MaybeObject* Runtime::DeleteObjectProperty(Isolate* isolate, return isolate->heap()->true_value(); } - return receiver->DeleteElement(index, mode); + Handle result = JSReceiver::DeleteElement(receiver, index, mode); + RETURN_IF_EMPTY_HANDLE(isolate, result); + return *result; } Handle name; @@ -5174,7 +5176,9 @@ MaybeObject* Runtime::DeleteObjectProperty(Isolate* isolate, } if (name->IsString()) Handle::cast(name)->TryFlatten(); - return receiver->DeleteProperty(*name, mode); + Handle result = JSReceiver::DeleteProperty(receiver, name, mode); + RETURN_IF_EMPTY_HANDLE(isolate, result); + return *result; } @@ -5387,15 +5391,16 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IgnoreAttributesAndSetProperty) { RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteProperty) { - SealHandleScope shs(isolate); + HandleScope scope(isolate); ASSERT(args.length() == 3); - - CONVERT_ARG_CHECKED(JSReceiver, object, 0); - CONVERT_ARG_CHECKED(Name, key, 1); + CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); + CONVERT_ARG_HANDLE_CHECKED(Name, key, 1); CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2); - return object->DeleteProperty(key, (strict_mode == kStrictMode) - ? JSReceiver::STRICT_DELETION - : JSReceiver::NORMAL_DELETION); + JSReceiver::DeleteMode delete_mode = (strict_mode == kStrictMode) + ? JSReceiver::STRICT_DELETION : JSReceiver::NORMAL_DELETION; + Handle result = JSReceiver::DeleteProperty(object, key, delete_mode); + RETURN_IF_EMPTY_HANDLE(isolate, result); + return *result; } @@ -8968,7 +8973,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteContextSlot) { // the global object, or the subject of a with. Try to delete it // (respecting DONT_DELETE). Handle object = Handle::cast(holder); - return object->DeleteProperty(*name, JSReceiver::NORMAL_DELETION); + Handle result = JSReceiver::DeleteProperty(object, name); + RETURN_IF_EMPTY_HANDLE(isolate, result); + return *result; } diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc index 7fb77a1..bac579e 100644 --- a/test/cctest/test-heap.cc +++ b/test/cctest/test-heap.cc @@ -661,7 +661,7 @@ TEST(ObjectProperties) { CHECK(obj->HasLocalProperty(*first)); // delete first - CHECK(obj->DeleteProperty(*first, JSObject::NORMAL_DELETION)); + JSReceiver::DeleteProperty(obj, first, JSReceiver::NORMAL_DELETION); CHECK(!obj->HasLocalProperty(*first)); // add first and then second @@ -673,9 +673,9 @@ TEST(ObjectProperties) { CHECK(obj->HasLocalProperty(*second)); // delete first and then second - CHECK(obj->DeleteProperty(*first, JSObject::NORMAL_DELETION)); + JSReceiver::DeleteProperty(obj, first, JSReceiver::NORMAL_DELETION); CHECK(obj->HasLocalProperty(*second)); - CHECK(obj->DeleteProperty(*second, JSObject::NORMAL_DELETION)); + JSReceiver::DeleteProperty(obj, second, JSReceiver::NORMAL_DELETION); CHECK(!obj->HasLocalProperty(*first)); CHECK(!obj->HasLocalProperty(*second)); @@ -688,9 +688,9 @@ TEST(ObjectProperties) { CHECK(obj->HasLocalProperty(*second)); // delete second and then first - CHECK(obj->DeleteProperty(*second, JSObject::NORMAL_DELETION)); + JSReceiver::DeleteProperty(obj, second, JSReceiver::NORMAL_DELETION); CHECK(obj->HasLocalProperty(*first)); - CHECK(obj->DeleteProperty(*first, JSObject::NORMAL_DELETION)); + JSReceiver::DeleteProperty(obj, first, JSReceiver::NORMAL_DELETION); CHECK(!obj->HasLocalProperty(*first)); CHECK(!obj->HasLocalProperty(*second)); -- 2.7.4