Index: src/lookup.cc |
diff --git a/src/lookup.cc b/src/lookup.cc |
index 3b11ebce798c56fa04ffc11b568348f75f727412..60506e75aad6ece4e6c19835453937b65e305b38 100644 |
--- a/src/lookup.cc |
+++ b/src/lookup.cc |
@@ -14,25 +14,28 @@ namespace internal { |
void LookupIterator::Next() { |
+ DCHECK_NE(JSPROXY, state_); |
+ DCHECK_NE(TRANSITION, state_); |
DisallowHeapAllocation no_gc; |
has_property_ = false; |
- JSReceiver* holder = NULL; |
+ JSReceiver* holder = |
+ maybe_holder_.is_null() ? NULL : *maybe_holder_.ToHandleChecked(); |
Map* map = *holder_map_; |
// Perform lookup on current holder. |
- state_ = LookupInHolder(map); |
+ state_ = LookupInHolder(map, holder); |
+ if (IsFound()) return; |
// Continue lookup if lookup on current holder failed. |
- while (!IsFound()) { |
+ do { |
JSReceiver* maybe_holder = NextHolder(map); |
if (maybe_holder == NULL) break; |
holder = maybe_holder; |
map = holder->map(); |
- state_ = LookupInHolder(map); |
- } |
+ state_ = LookupInHolder(map, holder); |
+ } while (!IsFound()); |
- // Either was found in the receiver, or the receiver has no prototype. |
if (holder == NULL) return; |
maybe_holder_ = handle(holder, isolate_); |
@@ -81,58 +84,15 @@ bool LookupIterator::HasAccess(v8::AccessType access_type) const { |
} |
-bool LookupIterator::HasProperty() { |
- DCHECK_EQ(PROPERTY, state_); |
- DCHECK(is_guaranteed_to_have_holder()); |
- |
- if (property_encoding_ == DICTIONARY) { |
- Handle<JSObject> holder = GetHolder<JSObject>(); |
- number_ = holder->property_dictionary()->FindEntry(name_); |
- if (number_ == NameDictionary::kNotFound) return false; |
- |
- property_details_ = holder->property_dictionary()->DetailsAt(number_); |
- // Holes in dictionary cells are absent values. |
- if (holder->IsGlobalObject() && |
- (property_details_.IsDeleted() || FetchValue()->IsTheHole())) { |
- return false; |
- } |
- } else { |
- // Can't use descriptor_number() yet because has_property_ is still false. |
- property_details_ = |
- holder_map_->instance_descriptors()->GetDetails(number_); |
- } |
- |
- LoadPropertyKind(); |
- |
- has_property_ = true; |
- return true; |
-} |
- |
- |
-void LookupIterator::LoadPropertyKind() { |
- switch (property_details_.type()) { |
- case v8::internal::FIELD: |
- case v8::internal::NORMAL: |
- case v8::internal::CONSTANT: |
- property_kind_ = DATA; |
- break; |
- case v8::internal::CALLBACKS: |
- property_kind_ = ACCESSOR; |
- break; |
- } |
-} |
- |
- |
void LookupIterator::ReloadPropertyInformation() { |
state_ = BEFORE_PROPERTY; |
- state_ = LookupInHolder(*holder_map_); |
- DCHECK(IsFound()); |
- HasProperty(); |
+ state_ = LookupInHolder(*holder_map_, *maybe_holder_.ToHandleChecked()); |
+ DCHECK(IsFound() || holder_map_->is_dictionary_map()); |
} |
void LookupIterator::PrepareForDataProperty(Handle<Object> value) { |
- DCHECK(has_property_); |
+ DCHECK(state_ == DATA || state_ == ACCESSOR); |
DCHECK(HolderIsReceiverOrHiddenPrototype()); |
if (property_encoding_ == DICTIONARY) return; |
holder_map_ = |
@@ -144,7 +104,7 @@ void LookupIterator::PrepareForDataProperty(Handle<Object> value) { |
void LookupIterator::ReconfigureDataProperty(Handle<Object> value, |
PropertyAttributes attributes) { |
- DCHECK(has_property_); |
+ DCHECK(state_ == DATA || state_ == ACCESSOR); |
DCHECK(HolderIsReceiverOrHiddenPrototype()); |
Handle<JSObject> holder = GetHolder<JSObject>(); |
if (property_encoding_ != DICTIONARY) { |
@@ -166,9 +126,9 @@ void LookupIterator::PrepareTransitionToDataProperty( |
Handle<Object> value, PropertyAttributes attributes, |
Object::StoreFromKeyed store_mode) { |
if (state_ == TRANSITION) return; |
- DCHECK(!has_property_ || property_kind_ != ACCESSOR); |
- DCHECK(!(has_property_ || state_ == JSPROXY) || |
- !HolderIsReceiverOrHiddenPrototype()); |
+ DCHECK(state_ != LookupIterator::ACCESSOR || |
+ GetAccessors()->IsDeclaredAccessorInfo()); |
+ DCHECK(state_ == NOT_FOUND || !HolderIsReceiverOrHiddenPrototype()); |
// Can only be called when the receiver is a JSObject. JSProxy has to be |
// handled via a trap. Adding properties to primitive values is not |
@@ -224,8 +184,7 @@ void LookupIterator::TransitionToAccessorProperty( |
// Install the accessor into the dictionary-mode object. |
PropertyDetails details(attributes, CALLBACKS, 0); |
Handle<AccessorPair> pair; |
- if (IsFound() && HasProperty() && property_kind() == ACCESSOR && |
- GetAccessors()->IsAccessorPair()) { |
+ if (state() == ACCESSOR && GetAccessors()->IsAccessorPair()) { |
pair = Handle<AccessorPair>::cast(GetAccessors()); |
// If the component and attributes are identical, nothing has to be done. |
if (pair->get(component) == *accessor) { |
@@ -331,15 +290,13 @@ Handle<PropertyCell> LookupIterator::GetPropertyCell() const { |
Handle<Object> LookupIterator::GetAccessors() const { |
- DCHECK(has_property_); |
- DCHECK_EQ(ACCESSOR, property_kind_); |
+ DCHECK_EQ(ACCESSOR, state_); |
return FetchValue(); |
} |
Handle<Object> LookupIterator::GetDataValue() const { |
- DCHECK(has_property_); |
- DCHECK_EQ(DATA, property_kind_); |
+ DCHECK_EQ(DATA, state_); |
Handle<Object> value = FetchValue(); |
return value; |
} |
@@ -347,7 +304,7 @@ Handle<Object> LookupIterator::GetDataValue() const { |
void LookupIterator::WriteDataValue(Handle<Object> value) { |
DCHECK(is_guaranteed_to_have_holder()); |
- DCHECK(has_property_); |
+ DCHECK_EQ(DATA, state_); |
Handle<JSObject> holder = GetHolder<JSObject>(); |
if (property_encoding_ == DICTIONARY) { |
NameDictionary* property_dictionary = holder->property_dictionary(); |