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
parent b1373531
......@@ -124,6 +124,15 @@ typedef ZoneList<Handle<Object> > ZoneObjectList;
} \
} while (false)
#define RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, T) \
do { \
Isolate* __isolate__ = (isolate); \
if (__isolate__->has_scheduled_exception()) { \
__isolate__->PromoteScheduledException(); \
return Handle<T>::null(); \
} \
} while (false)
#define RETURN_IF_EMPTY_HANDLE_VALUE(isolate, call, value) \
do { \
if ((call).is_null()) { \
......
......@@ -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<NameDictionary> NameDictionaryShrink(Handle<NameDictionary> dict,
Handle<Name> name) {
CALL_HEAP_FUNCTION(dict->GetIsolate(), dict->Shrink(*name), NameDictionary);
}
static void CellSetValueInferType(Handle<PropertyCell> cell,
Handle<Object> value) {
CALL_HEAP_FUNCTION_VOID(cell->GetIsolate(), cell->SetValueInferType(*value));
}
Handle<Object> JSObject::DeleteNormalizedProperty(Handle<JSObject> object,
Handle<Name> name,
DeleteMode mode) {
ASSERT(!object->HasFastProperties());
Isolate* isolate = object->GetIsolate();
Handle<NameDictionary> 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<Map> 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<PropertyCell> 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<Object> deleted(dictionary->DeleteProperty(entry, mode), isolate);
if (*deleted == isolate->heap()->true_value()) {
Handle<NameDictionary> 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<JSProxy> receiver(this);
Handle<Object> name(name_raw, isolate);
Handle<Object> JSProxy::DeletePropertyWithHandler(
Handle<JSProxy> object, Handle<Name> 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<Object> args[] = { name };
Handle<Object> result = CallTrap(
"delete", Handle<Object>(), ARRAY_SIZE(args), args);
if (isolate->has_pending_exception()) return Failure::Exception();
Handle<Object> result = object->CallTrap(
"delete", Handle<Object>(), ARRAY_SIZE(args), args);
if (isolate->has_pending_exception()) return Handle<Object>();
bool result_bool = result->BooleanValue();
if (mode == STRICT_DELETION && !result_bool) {
Handle<Object> handler(receiver->handler(), isolate);
Handle<Object> handler(object->handler(), isolate);
Handle<String> trap_name = isolate->factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("delete"));
Handle<Object> args[] = { handler, trap_name };
Handle<Object> error = isolate->factory()->NewTypeError(
"handler_failed", HandleVector(args, ARRAY_SIZE(args)));
isolate->Throw(*error);
return Failure::Exception();
return Handle<Object>();
}
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<Object> JSProxy::DeleteElementWithHandler(
Handle<JSProxy> object, uint32_t index, DeleteMode mode) {
Isolate* isolate = object->GetIsolate();
Handle<String> 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<Object> JSObject::DeletePropertyPostInterceptor(Handle<JSObject> object,
Handle<Name> 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<Object> JSObject::DeletePropertyWithInterceptor(Handle<JSObject> object,
Handle<Name> 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<InterceptorInfo> interceptor(GetNamedInterceptor());
Handle<String> name_handle(String::cast(name));
Handle<JSObject> this_handle(this);
Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor());
if (!interceptor->deleter()->IsUndefined()) {
v8::NamedPropertyDeleter deleter =
v8::ToCData<v8::NamedPropertyDeleter>(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<v8::Boolean> result =
args.Call(deleter, v8::Utils::ToLocal(name_handle));
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
args.Call(deleter, v8::Utils::ToLocal(Handle<String>::cast(name)));
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->DeletePropertyPostInterceptor(*name_handle, NORMAL_DELETION);
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
return raw_result;
Handle<Object> 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<Object> JSObject::DeleteElement(Handle<JSObject> 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<Object> JSObject::DeleteProperty(Handle<JSObject> obj,
Handle<Name> prop) {
CALL_HEAP_FUNCTION(obj->GetIsolate(),
obj->DeleteProperty(*prop, JSObject::NORMAL_DELETION),
Object);
}
MaybeObject* JSObject::DeleteProperty(Name* name, DeleteMode mode) {
Isolate* isolate = GetIsolate();
Handle<Object> JSObject::DeleteProperty(Handle<JSObject> object,
Handle<Name> 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<Object> args[2] = { Handle<Object>(name, isolate),
Handle<Object>(this, isolate) };
return isolate->Throw(*isolate->factory()->NewTypeError(
"strict_delete_property", HandleVector(args, 2)));
Handle<Object> args[2] = { name, object };
Handle<Object> error = isolate->factory()->NewTypeError(
"strict_delete_property", HandleVector(args, ARRAY_SIZE(args)));
isolate->Throw(*error);
return Handle<Object>();
}
return isolate->heap()->false_value();
return isolate->factory()->false_value();
}
// From this point on everything needs to be handlified.
HandleScope scope(isolate);
Handle<JSObject> self(this);
Handle<Name> hname(name);
Handle<Object> 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<Object> 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<Object> 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<Object> JSReceiver::DeleteElement(Handle<JSReceiver> object,
uint32_t index,
DeleteMode mode) {
if (object->IsJSProxy()) {
return JSProxy::DeleteElementWithHandler(
Handle<JSProxy>::cast(object), index, mode);
}
return JSObject::cast(this)->DeleteElement(index, mode);
return JSObject::DeleteElement(Handle<JSObject>::cast(object), index, mode);
}
MaybeObject* JSReceiver::DeleteProperty(Name* name, DeleteMode mode) {
if (IsJSProxy()) {
return JSProxy::cast(this)->DeletePropertyWithHandler(name, mode);
Handle<Object> JSReceiver::DeleteProperty(Handle<JSReceiver> object,
Handle<Name> name,
DeleteMode mode) {
if (object->IsJSProxy()) {
return JSProxy::DeletePropertyWithHandler(
Handle<JSProxy>::cast(object), name, mode);
}
return JSObject::cast(this)->DeleteProperty(name, mode);
return JSObject::DeleteProperty(Handle<JSObject>::cast(object), name, mode);
}
......@@ -6511,6 +6506,11 @@ MaybeObject* Map::CopyNormalized(PropertyNormalizationMode mode,
}
Handle<Map> Map::CopyDropDescriptors(Handle<Map> map) {
CALL_HEAP_FUNCTION(map->GetIsolate(), map->CopyDropDescriptors(), Map);
}
MaybeObject* Map::CopyDropDescriptors() {
Map* result;
MaybeObject* maybe_result = RawCopy(instance_size());
......
......@@ -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<Object> DeleteProperty(Handle<JSReceiver> object,
Handle<Name> name,
DeleteMode mode = NORMAL_DELETION);
static Handle<Object> DeleteElement(Handle<JSReceiver> 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<JSObject> 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<Object> DeleteProperty(Handle<JSObject> obj,
Handle<Name> name);
// Can cause GC.
MUST_USE_RESULT MaybeObject* DeleteProperty(Name* name, DeleteMode mode);
static Handle<Object> DeleteElement(Handle<JSObject> obj, uint32_t index);
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();
......@@ -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<Object> DeleteProperty(Handle<JSObject> object,
Handle<Name> name,
DeleteMode mode);
static Handle<Object> DeletePropertyPostInterceptor(Handle<JSObject> object,
Handle<Name> name,
DeleteMode mode);
static Handle<Object> DeletePropertyWithInterceptor(Handle<JSObject> object,
Handle<Name> name);
// Deletes the named property in a normalized object.
static Handle<Object> DeleteNormalizedProperty(Handle<JSObject> object,
Handle<Name> 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<Map> CopyDropDescriptors(Handle<Map> 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<Object> DeletePropertyWithHandler(Handle<JSProxy> object,
Handle<Name> name,
DeleteMode mode);
static Handle<Object> DeleteElementWithHandler(Handle<JSProxy> object,
uint32_t index,
DeleteMode mode);
DISALLOW_IMPLICIT_CONSTRUCTORS(JSProxy);
};
......
......@@ -5159,7 +5159,9 @@ MaybeObject* Runtime::DeleteObjectProperty(Isolate* isolate,
return isolate->heap()->true_value();
}
return receiver->DeleteElement(index, mode);
Handle<Object> result = JSReceiver::DeleteElement(receiver, index, mode);
RETURN_IF_EMPTY_HANDLE(isolate, result);
return *result;
}
Handle<Name> name;
......@@ -5174,7 +5176,9 @@ MaybeObject* Runtime::DeleteObjectProperty(Isolate* isolate,
}
if (name->IsString()) Handle<String>::cast(name)->TryFlatten();
return receiver->DeleteProperty(*name, mode);
Handle<Object> 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<Object> 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<JSObject> object = Handle<JSObject>::cast(holder);
return object->DeleteProperty(*name, JSReceiver::NORMAL_DELETION);
Handle<Object> result = JSReceiver::DeleteProperty(object, name);
RETURN_IF_EMPTY_HANDLE(isolate, result);
return *result;
}
......
......@@ -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));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment