Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 9edbdc9623475e24b2cfbc622a8f12a40c9eccde..e90d28f084f60b32fbfdbf1e26da5eb51341236e 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -530,56 +530,6 @@ void JSObject::SetNormalizedProperty(Handle<JSObject> object, |
} |
-Handle<Object> JSObject::DeleteNormalizedProperty(Handle<JSObject> object, |
- Handle<Name> name, |
- DeleteMode mode) { |
- DCHECK(!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 (object->IsGlobalObject()) { |
- PropertyDetails details = dictionary->DetailsAt(entry); |
- if (!details.IsConfigurable()) { |
- 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 non-configurable cell without checking if it contains |
- // the hole value. |
- Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); |
- DCHECK(new_map->is_dictionary_map()); |
-#if TRACE_MAPS |
- if (FLAG_trace_maps) { |
- PrintF("[TraceMaps: GlobalDeleteNormalized from= %p to= %p ]\n", |
- reinterpret_cast<void*>(object->map()), |
- reinterpret_cast<void*>(*new_map)); |
- } |
-#endif |
- JSObject::MigrateToMap(object, new_map); |
- // Optimized code does not check for the hole value for non-configurable |
- // properties. |
- Deoptimizer::DeoptimizeGlobalObject(*object); |
- } |
- Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); |
- Handle<Object> value = isolate->factory()->the_hole_value(); |
- PropertyCell::SetValueInferType(cell, value); |
- dictionary->DetailsAtPut(entry, details.AsDeleted()); |
- } else { |
- Handle<Object> deleted( |
- NameDictionary::DeleteProperty(dictionary, entry, mode)); |
- if (*deleted == isolate->heap()->true_value()) { |
- Handle<NameDictionary> new_properties = |
- NameDictionary::Shrink(dictionary, name); |
- object->set_properties(*new_properties); |
- } |
- return deleted; |
- } |
- } |
- return isolate->factory()->true_value(); |
-} |
- |
- |
MaybeHandle<Object> Object::GetElementWithReceiver(Isolate* isolate, |
Handle<Object> object, |
Handle<Object> receiver, |
@@ -3543,8 +3493,9 @@ MaybeHandle<Object> JSProxy::SetPropertyViaPrototypesWithHandler( |
} |
-MaybeHandle<Object> JSProxy::DeletePropertyWithHandler( |
- Handle<JSProxy> proxy, Handle<Name> name, DeleteMode mode) { |
+MaybeHandle<Object> JSProxy::DeletePropertyWithHandler(Handle<JSProxy> proxy, |
+ Handle<Name> name, |
+ StrictMode strict_mode) { |
Isolate* isolate = proxy->GetIsolate(); |
// TODO(rossberg): adjust once there is a story for symbols vs proxies. |
@@ -3562,7 +3513,7 @@ MaybeHandle<Object> JSProxy::DeletePropertyWithHandler( |
Object); |
bool result_bool = result->BooleanValue(); |
- if (mode == STRICT_DELETION && !result_bool) { |
+ if (strict_mode == STRICT && !result_bool) { |
Handle<Object> handler(proxy->handler(), isolate); |
Handle<String> trap_name = isolate->factory()->InternalizeOneByteString( |
STATIC_CHAR_VECTOR("delete")); |
@@ -3575,11 +3526,12 @@ MaybeHandle<Object> JSProxy::DeletePropertyWithHandler( |
} |
-MaybeHandle<Object> JSProxy::DeleteElementWithHandler( |
- Handle<JSProxy> proxy, uint32_t index, DeleteMode mode) { |
+MaybeHandle<Object> JSProxy::DeleteElementWithHandler(Handle<JSProxy> proxy, |
+ uint32_t index, |
+ StrictMode strict_mode) { |
Isolate* isolate = proxy->GetIsolate(); |
Handle<String> name = isolate->factory()->Uint32ToString(index); |
- return JSProxy::DeletePropertyWithHandler(proxy, name, mode); |
+ return JSProxy::DeletePropertyWithHandler(proxy, name, strict_mode); |
} |
@@ -4857,15 +4809,16 @@ MaybeHandle<Object> JSObject::DeleteElementWithInterceptor( |
// Rebox CustomArguments::kReturnValueOffset before returning. |
return handle(*result_internal, isolate); |
} |
- MaybeHandle<Object> delete_result = object->GetElementsAccessor()->Delete( |
- object, index, NORMAL_DELETION); |
+ // 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, |
- DeleteMode mode) { |
+ StrictMode strict_mode) { |
Isolate* isolate = object->GetIsolate(); |
Factory* factory = isolate->factory(); |
@@ -4878,7 +4831,7 @@ MaybeHandle<Object> JSObject::DeleteElement(Handle<JSObject> object, |
} |
if (object->IsStringObjectWithCharacterAt(index)) { |
- if (mode == STRICT_DELETION) { |
+ if (strict_mode == STRICT) { |
// Deleting a non-configurable property in strict mode. |
Handle<Object> name = factory->NewNumberFromUint(index); |
Handle<Object> args[2] = { name, object }; |
@@ -4895,7 +4848,7 @@ MaybeHandle<Object> JSObject::DeleteElement(Handle<JSObject> object, |
DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
return DeleteElement( |
Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index, |
- mode); |
+ strict_mode); |
} |
Handle<Object> old_value; |
@@ -4916,10 +4869,11 @@ MaybeHandle<Object> JSObject::DeleteElement(Handle<JSObject> object, |
// Skip interceptor if forcing deletion. |
MaybeHandle<Object> maybe_result; |
- if (object->HasIndexedInterceptor() && mode != FORCE_DELETION) { |
+ if (object->HasIndexedInterceptor()) { |
maybe_result = DeleteElementWithInterceptor(object, index); |
} else { |
- maybe_result = object->GetElementsAccessor()->Delete(object, index, mode); |
+ maybe_result = |
+ object->GetElementsAccessor()->Delete(object, index, strict_mode); |
} |
Handle<Object> result; |
ASSIGN_RETURN_ON_EXCEPTION(isolate, result, maybe_result, Object); |
@@ -4939,23 +4893,44 @@ MaybeHandle<Object> JSObject::DeleteElement(Handle<JSObject> object, |
} |
+void JSObject::DeleteNormalizedProperty(Handle<JSObject> object, |
+ Handle<Name> name) { |
+ DCHECK(!object->HasFastProperties()); |
+ Isolate* isolate = object->GetIsolate(); |
+ Handle<NameDictionary> dictionary(object->property_dictionary()); |
+ int entry = dictionary->FindEntry(name); |
+ DCHECK_NE(NameDictionary::kNotFound, entry); |
+ |
+ // If we have a global object set the cell to the hole. |
+ if (object->IsGlobalObject()) { |
+ PropertyDetails details = dictionary->DetailsAt(entry); |
+ DCHECK(details.IsConfigurable()); |
+ Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); |
+ Handle<Object> value = isolate->factory()->the_hole_value(); |
+ PropertyCell::SetValueInferType(cell, value); |
+ dictionary->DetailsAtPut(entry, details.AsDeleted()); |
+ return; |
+ } |
+ |
+ NameDictionary::DeleteProperty(dictionary, entry); |
+ Handle<NameDictionary> new_properties = |
+ NameDictionary::Shrink(dictionary, name); |
+ object->set_properties(*new_properties); |
+} |
+ |
+ |
MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object, |
Handle<Name> name, |
- DeleteMode delete_mode) { |
+ StrictMode strict_mode) { |
// ECMA-262, 3rd, 8.6.2.5 |
DCHECK(name->IsName()); |
uint32_t index = 0; |
if (name->AsArrayIndex(&index)) { |
- return DeleteElement(object, index, delete_mode); |
+ return DeleteElement(object, index, strict_mode); |
} |
- // Skip interceptors on FORCE_DELETION. |
- LookupIterator::Configuration config = |
- delete_mode == FORCE_DELETION ? LookupIterator::HIDDEN_SKIP_INTERCEPTOR |
- : LookupIterator::HIDDEN; |
- |
- LookupIterator it(object, name, config); |
+ LookupIterator it(object, name, LookupIterator::HIDDEN); |
bool is_observed = object->map()->is_observed() && |
!it.isolate()->IsInternallyUsedPropertyName(name); |
@@ -4989,9 +4964,9 @@ MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object, |
} |
// Fall through. |
case LookupIterator::ACCESSOR: { |
- if (delete_mode != FORCE_DELETION && !it.IsConfigurable()) { |
+ if (!it.IsConfigurable()) { |
// Fail if the property is not configurable. |
- if (delete_mode == STRICT_DELETION) { |
+ if (strict_mode == STRICT) { |
Handle<Object> args[2] = {name, object}; |
THROW_NEW_ERROR(it.isolate(), |
NewTypeError("strict_delete_property", |
@@ -5011,9 +4986,9 @@ MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object, |
!(object->IsJSGlobalProxy() && holder->IsJSGlobalObject())) { |
return it.isolate()->factory()->true_value(); |
} |
+ |
NormalizeProperties(holder, mode, 0, "DeletingProperty"); |
- Handle<Object> result = |
- DeleteNormalizedProperty(holder, name, delete_mode); |
+ DeleteNormalizedProperty(holder, name); |
ReoptimizeIfPrototype(holder); |
if (is_observed) { |
@@ -5022,7 +4997,7 @@ MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object, |
EnqueueChangeRecord(object, "delete", name, old_value), Object); |
} |
- return result; |
+ return it.isolate()->factory()->true_value(); |
} |
} |
} |
@@ -5033,23 +5008,25 @@ MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object, |
MaybeHandle<Object> JSReceiver::DeleteElement(Handle<JSReceiver> object, |
uint32_t index, |
- DeleteMode mode) { |
+ StrictMode strict_mode) { |
if (object->IsJSProxy()) { |
- return JSProxy::DeleteElementWithHandler( |
- Handle<JSProxy>::cast(object), index, mode); |
+ return JSProxy::DeleteElementWithHandler(Handle<JSProxy>::cast(object), |
+ index, strict_mode); |
} |
- return JSObject::DeleteElement(Handle<JSObject>::cast(object), index, mode); |
+ return JSObject::DeleteElement(Handle<JSObject>::cast(object), index, |
+ strict_mode); |
} |
MaybeHandle<Object> JSReceiver::DeleteProperty(Handle<JSReceiver> object, |
Handle<Name> name, |
- DeleteMode mode) { |
+ StrictMode strict_mode) { |
if (object->IsJSProxy()) { |
- return JSProxy::DeletePropertyWithHandler( |
- Handle<JSProxy>::cast(object), name, mode); |
+ return JSProxy::DeletePropertyWithHandler(Handle<JSProxy>::cast(object), |
+ name, strict_mode); |
} |
- return JSObject::DeleteProperty(Handle<JSObject>::cast(object), name, mode); |
+ return JSObject::DeleteProperty(Handle<JSObject>::cast(object), name, |
+ strict_mode); |
} |
@@ -14469,11 +14446,11 @@ Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
template Handle<Object> |
Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::DeleteProperty( |
- Handle<NameDictionary>, int, JSObject::DeleteMode); |
+ Handle<NameDictionary>, int); |
template Handle<Object> |
-Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
- DeleteProperty(Handle<SeededNumberDictionary>, int, JSObject::DeleteMode); |
+Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, |
+ uint32_t>::DeleteProperty(Handle<SeededNumberDictionary>, int); |
template Handle<NameDictionary> |
HashTable<NameDictionary, NameDictionaryShape, Handle<Name> >:: |
@@ -15451,17 +15428,12 @@ Handle<Derived> Dictionary<Derived, Shape, Key>::EnsureCapacity( |
} |
-template<typename Derived, typename Shape, typename Key> |
+template <typename Derived, typename Shape, typename Key> |
Handle<Object> Dictionary<Derived, Shape, Key>::DeleteProperty( |
- Handle<Derived> dictionary, |
- int entry, |
- JSObject::DeleteMode mode) { |
+ Handle<Derived> dictionary, int entry) { |
Factory* factory = dictionary->GetIsolate()->factory(); |
PropertyDetails details = dictionary->DetailsAt(entry); |
- // Ignore attributes if forcing a deletion. |
- if (!details.IsConfigurable() && mode != JSReceiver::FORCE_DELETION) { |
- return factory->false_value(); |
- } |
+ if (!details.IsConfigurable()) return factory->false_value(); |
dictionary->SetEntry( |
entry, factory->the_hole_value(), factory->the_hole_value()); |