From: verwaest@chromium.org Date: Mon, 18 Aug 2014 14:46:38 +0000 (+0000) Subject: Rewrite DeleteProperty using the LookupIterator X-Git-Tag: upstream/4.7.83~7581 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6867595ce7f705b5e5e8b902fcacc3efdc5651d9;p=platform%2Fupstream%2Fv8.git Rewrite DeleteProperty using the LookupIterator BUG= R=jkummerow@chromium.org Review URL: https://codereview.chromium.org/468073002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23166 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/objects.cc b/src/objects.cc index 623e159..d265eab 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -4855,56 +4855,32 @@ Handle JSObject::SetHiddenPropertiesHashTable(Handle object, } -Handle JSObject::DeletePropertyPostInterceptor(Handle object, - Handle name, - DeleteMode delete_mode) { - // Check own property, ignore interceptor. - Isolate* isolate = object->GetIsolate(); - LookupResult lookup(isolate); - object->LookupOwnRealNamedProperty(name, &lookup); - if (!lookup.IsFound()) return isolate->factory()->true_value(); - - PropertyNormalizationMode mode = object->map()->is_prototype_map() - ? KEEP_INOBJECT_PROPERTIES - : CLEAR_INOBJECT_PROPERTIES; - // Normalize object if needed. - NormalizeProperties(object, mode, 0); - - Handle result = DeleteNormalizedProperty(object, name, delete_mode); - ReoptimizeIfPrototype(object); - return result; -} - - MaybeHandle JSObject::DeletePropertyWithInterceptor( - Handle object, Handle name) { - Isolate* isolate = object->GetIsolate(); + Handle holder, Handle receiver, Handle name) { + Isolate* isolate = holder->GetIsolate(); // TODO(rossberg): Support symbols in the API. - if (name->IsSymbol()) return isolate->factory()->false_value(); + if (name->IsSymbol()) return MaybeHandle(); - Handle interceptor(object->GetNamedInterceptor()); - if (!interceptor->deleter()->IsUndefined()) { - v8::NamedPropertyDeleterCallback deleter = - v8::ToCData(interceptor->deleter()); - LOG(isolate, - ApiNamedPropertyAccess("interceptor-named-delete", *object, *name)); - PropertyCallbackArguments args( - isolate, interceptor->data(), *object, *object); - v8::Handle result = - args.Call(deleter, v8::Utils::ToLocal(Handle::cast(name))); - RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); - if (!result.IsEmpty()) { - DCHECK(result->IsBoolean()); - Handle result_internal = v8::Utils::OpenHandle(*result); - result_internal->VerifyApiCallResultType(); - // Rebox CustomArguments::kReturnValueOffset before returning. - return handle(*result_internal, isolate); - } - } - Handle result = - DeletePropertyPostInterceptor(object, name, NORMAL_DELETION); - return result; + Handle interceptor(holder->GetNamedInterceptor()); + if (interceptor->deleter()->IsUndefined()) return MaybeHandle(); + + v8::NamedPropertyDeleterCallback deleter = + v8::ToCData(interceptor->deleter()); + LOG(isolate, + ApiNamedPropertyAccess("interceptor-named-delete", *holder, *name)); + PropertyCallbackArguments args(isolate, interceptor->data(), *receiver, + *holder); + v8::Handle result = + args.Call(deleter, v8::Utils::ToLocal(Handle::cast(name))); + RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); + if (result.IsEmpty()) return MaybeHandle(); + + DCHECK(result->IsBoolean()); + Handle result_internal = v8::Utils::OpenHandle(*result); + result_internal->VerifyApiCallResultType(); + // Rebox CustomArguments::kReturnValueOffset before returning. + return handle(*result_internal, isolate); } @@ -5020,87 +4996,89 @@ MaybeHandle JSObject::DeleteElement(Handle object, MaybeHandle JSObject::DeleteProperty(Handle object, Handle name, DeleteMode delete_mode) { - Isolate* isolate = object->GetIsolate(); // ECMA-262, 3rd, 8.6.2.5 DCHECK(name->IsName()); - // Check access rights if needed. - if (object->IsAccessCheckNeeded() && - !isolate->MayNamedAccess(object, name, v8::ACCESS_DELETE)) { - isolate->ReportFailedAccessCheck(object, v8::ACCESS_DELETE); - RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); - return isolate->factory()->false_value(); - } - - if (object->IsJSGlobalProxy()) { - PrototypeIterator iter(isolate, object); - if (iter.IsAtEnd()) return isolate->factory()->false_value(); - DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); - return JSGlobalObject::DeleteProperty( - Handle::cast(PrototypeIterator::GetCurrent(iter)), name, - delete_mode); - } - uint32_t index = 0; if (name->AsArrayIndex(&index)) { return DeleteElement(object, index, delete_mode); } - LookupResult lookup(isolate); - object->LookupOwn(name, &lookup, true); - if (!lookup.IsFound()) return isolate->factory()->true_value(); - // Ignore attributes if forcing a deletion. - if (lookup.IsDontDelete() && delete_mode != FORCE_DELETION) { - if (delete_mode == STRICT_DELETION) { - // Deleting a non-configurable property in strict mode. - 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->factory()->false_value(); - } + // Skip interceptors on FORCE_DELETION. + LookupIterator::Configuration config = + delete_mode == FORCE_DELETION ? LookupIterator::CHECK_HIDDEN_ACCESS + : LookupIterator::CHECK_OWN; + + LookupIterator it(object, name, config); - Handle old_value = isolate->factory()->the_hole_value(); bool is_observed = object->map()->is_observed() && - *name != isolate->heap()->hidden_string(); - if (is_observed && lookup.IsDataProperty()) { - old_value = Object::GetPropertyOrElement(object, name).ToHandleChecked(); - } - Handle result; + *name != it.isolate()->heap()->hidden_string(); - // Check for interceptor. - if (lookup.IsInterceptor()) { - // Skip interceptor if forcing a deletion. - if (delete_mode == FORCE_DELETION) { - result = DeletePropertyPostInterceptor(object, name, delete_mode); - } else { - ASSIGN_RETURN_ON_EXCEPTION( - isolate, result, - DeletePropertyWithInterceptor(object, name), - Object); - } - } else { - PropertyNormalizationMode mode = object->map()->is_prototype_map() - ? KEEP_INOBJECT_PROPERTIES - : CLEAR_INOBJECT_PROPERTIES; - // Normalize object if needed. - NormalizeProperties(object, mode, 0); - // Make sure the properties are normalized before removing the entry. - result = DeleteNormalizedProperty(object, name, delete_mode); - ReoptimizeIfPrototype(object); - } + for (; it.IsFound(); it.Next()) { + switch (it.state()) { + case LookupIterator::NOT_FOUND: + case LookupIterator::JSPROXY: + UNREACHABLE(); + case LookupIterator::ACCESS_CHECK: + if (it.HasAccess(v8::ACCESS_DELETE)) break; + it.isolate()->ReportFailedAccessCheck(it.GetHolder(), + v8::ACCESS_DELETE); + RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it.isolate(), Object); + return it.isolate()->factory()->false_value(); + case LookupIterator::INTERCEPTOR: { + MaybeHandle maybe_result = + JSObject::DeletePropertyWithInterceptor(it.GetHolder(), + object, it.name()); + // 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; + break; + } + case LookupIterator::PROPERTY: { + if (!it.HasProperty()) continue; + if (delete_mode != FORCE_DELETION && !it.IsConfigurable()) { + // Fail if the property is not configurable. + if (delete_mode == STRICT_DELETION) { + Handle args[2] = {name, object}; + Handle error = it.isolate()->factory()->NewTypeError( + "strict_delete_property", HandleVector(args, ARRAY_SIZE(args))); + it.isolate()->Throw(*error); + return Handle(); + } + return it.isolate()->factory()->false_value(); + } - if (is_observed) { - Maybe maybe = HasOwnProperty(object, name); - if (!maybe.has_value) return MaybeHandle(); - if (!maybe.value) { - EnqueueChangeRecord(object, "delete", name, old_value); + Handle old_value; + if (is_observed) { + switch (it.property_kind()) { + case LookupIterator::ACCESSOR: + old_value = it.isolate()->factory()->the_hole_value(); + break; + case LookupIterator::DATA: + old_value = it.GetDataValue(); + } + } + + PropertyNormalizationMode mode = object->map()->is_prototype_map() + ? KEEP_INOBJECT_PROPERTIES + : CLEAR_INOBJECT_PROPERTIES; + Handle holder = it.GetHolder(); + NormalizeProperties(holder, mode, 0); + Handle result = + DeleteNormalizedProperty(holder, name, delete_mode); + ReoptimizeIfPrototype(holder); + + if (is_observed) { + EnqueueChangeRecord(object, "delete", name, old_value); + } + + return result; + } } } - return result; + return it.isolate()->factory()->true_value(); } diff --git a/src/objects.h b/src/objects.h index b2b73d0..cd71c34 100644 --- a/src/objects.h +++ b/src/objects.h @@ -2692,12 +2692,8 @@ class JSObject: public JSReceiver { Handle object, Handle name, DeleteMode mode); - static Handle DeletePropertyPostInterceptor(Handle object, - Handle name, - DeleteMode mode); MUST_USE_RESULT static MaybeHandle DeletePropertyWithInterceptor( - Handle object, - Handle name); + Handle holder, Handle receiver, Handle name); // Deletes the named property in a normalized object. static Handle DeleteNormalizedProperty(Handle object,