Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(964)

Unified Diff: src/objects.cc

Issue 1157093003: Handle Delete of element with LookupIterator (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase, fix all strong-mode handling Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index b547128a1be3098946a935e218e4476e707b115d..63dd59071091ad5303a9a4e8b0d602e85427297a 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -3939,14 +3939,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();
@@ -5029,23 +5021,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>();
@@ -5057,116 +5066,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());
@@ -5196,121 +5095,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);
}
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698