Use LookupIterator for elements in the observed part of DefineAccessor

BUG=v8:4137
LOG=n

Review URL: https://codereview.chromium.org/1177103003

Cr-Commit-Position: refs/heads/master@{#28963}
This commit is contained in:
verwaest 2015-06-11 13:09:19 -07:00 committed by Commit bot
parent 2cdfd4daa9
commit 83abd09597

View File

@ -6396,21 +6396,6 @@ MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object,
Handle<Object> setter,
PropertyAttributes attributes) {
Isolate* isolate = object->GetIsolate();
// Check access rights if needed.
if (object->IsAccessCheckNeeded() && !isolate->MayAccess(object)) {
isolate->ReportFailedAccessCheck(object);
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return isolate->factory()->undefined_value();
}
if (object->IsJSGlobalProxy()) {
PrototypeIterator iter(isolate, object);
if (iter.IsAtEnd()) return isolate->factory()->undefined_value();
DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
DefineAccessor(Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)),
name, getter, setter, attributes);
return isolate->factory()->undefined_value();
}
// Make sure that the top context does not change when doing callbacks or
// interceptor calls.
@ -6420,39 +6405,36 @@ MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object,
if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
uint32_t index = 0;
bool is_element = name->AsArrayIndex(&index);
LookupIterator::Configuration c = LookupIterator::HIDDEN_SKIP_INTERCEPTOR;
LookupIterator it = name->AsArrayIndex(&index)
? LookupIterator(isolate, object, index, c)
: LookupIterator(object, name, c);
if (it.state() == LookupIterator::ACCESS_CHECK) {
if (!it.HasAccess()) {
isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>());
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return isolate->factory()->undefined_value();
}
it.Next();
}
Handle<Object> old_value = isolate->factory()->the_hole_value();
bool is_observed = object->map()->is_observed() &&
!isolate->IsInternallyUsedPropertyName(name);
bool preexists = false;
if (is_observed) {
if (is_element) {
Maybe<bool> maybe = HasOwnElement(object, index);
// Workaround for a GCC 4.4.3 bug which leads to "preexists may be used
// uninitialized in this function".
if (!maybe.IsJust()) {
DCHECK(false);
return isolate->factory()->undefined_value();
}
preexists = maybe.FromJust();
if (preexists && GetOwnElementAccessorPair(object, index).is_null()) {
old_value =
Object::GetElement(isolate, object, index).ToHandleChecked();
}
} else {
LookupIterator it(object, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
CHECK(GetPropertyAttributes(&it).IsJust());
preexists = it.IsFound();
if (preexists && (it.state() == LookupIterator::DATA ||
it.GetAccessors()->IsAccessorInfo())) {
old_value = GetProperty(&it).ToHandleChecked();
}
CHECK(GetPropertyAttributes(&it).IsJust());
preexists = it.IsFound();
if (preexists && (it.state() == LookupIterator::DATA ||
it.GetAccessors()->IsAccessorInfo())) {
old_value = GetProperty(&it).ToHandleChecked();
}
}
if (is_element) {
DefineElementAccessor(object, index, getter, setter, attributes);
if (it.IsElement()) {
DefineElementAccessor(it.GetStoreTarget(), index, getter, setter,
attributes);
} else {
DCHECK(getter->IsSpecFunction() || getter->IsUndefined() ||
getter->IsNull());
@ -6460,11 +6442,6 @@ MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object,
setter->IsNull());
// At least one of the accessors needs to be a new value.
DCHECK(!getter->IsNull() || !setter->IsNull());
LookupIterator it(object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
if (it.state() == LookupIterator::ACCESS_CHECK) {
// We already did an access check before. We do have access.
it.Next();
}
if (!getter->IsNull()) {
it.TransitionToAccessorProperty(ACCESSOR_GETTER, getter, attributes);
}