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:
parent
2cdfd4daa9
commit
83abd09597
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user