Index: src/property.h |
diff --git a/src/property.h b/src/property.h |
index cfdf9c7c07562b690e842900087e6cbee0303a07..087e0a339c5750765b3bf1f44d26db5e4404dd8a 100644 |
--- a/src/property.h |
+++ b/src/property.h |
@@ -180,16 +180,15 @@ class LookupResult V8_FINAL BASE_EMBEDDED { |
bool CanHoldValue(Handle<Object> value) { |
if (IsNormal()) return true; |
- ASSERT(!IsTransition()); |
return value->FitsRepresentation(details_.representation()); |
} |
void TransitionResult(JSObject* holder, Map* target) { |
lookup_type_ = TRANSITION_TYPE; |
- details_ = PropertyDetails(NONE, TRANSITION, Representation::None()); |
+ number_ = target->LastAdded(); |
+ details_ = target->instance_descriptors()->GetDetails(number_); |
holder_ = holder; |
transition_ = target; |
- number_ = 0xAAAA; |
} |
void DictionaryResult(JSObject* holder, int entry) { |
@@ -239,20 +238,17 @@ class LookupResult V8_FINAL BASE_EMBEDDED { |
Representation representation() const { |
ASSERT(IsFound()); |
- ASSERT(!IsTransition()); |
ASSERT(details_.type() != NONEXISTENT); |
return details_.representation(); |
} |
PropertyAttributes GetAttributes() const { |
- ASSERT(!IsTransition()); |
ASSERT(IsFound()); |
ASSERT(details_.type() != NONEXISTENT); |
return details_.attributes(); |
} |
PropertyDetails GetPropertyDetails() const { |
- ASSERT(!IsTransition()); |
return details_; |
} |
@@ -264,38 +260,40 @@ class LookupResult V8_FINAL BASE_EMBEDDED { |
// Property callbacks does not include transitions to callbacks. |
bool IsPropertyCallbacks() const { |
ASSERT(!(details_.type() == CALLBACKS && !IsFound())); |
- return details_.type() == CALLBACKS; |
+ return !IsTransition() && details_.type() == CALLBACKS; |
} |
bool IsReadOnly() const { |
ASSERT(IsFound()); |
- ASSERT(!IsTransition()); |
ASSERT(details_.type() != NONEXISTENT); |
return details_.IsReadOnly(); |
} |
bool IsField() const { |
ASSERT(!(details_.type() == FIELD && !IsFound())); |
- return details_.type() == FIELD; |
+ return IsDescriptorOrDictionary() && type() == FIELD; |
} |
bool IsNormal() const { |
ASSERT(!(details_.type() == NORMAL && !IsFound())); |
- return details_.type() == NORMAL; |
+ return IsDescriptorOrDictionary() && type() == NORMAL; |
} |
bool IsConstant() const { |
ASSERT(!(details_.type() == CONSTANT && !IsFound())); |
- return details_.type() == CONSTANT; |
+ return IsDescriptorOrDictionary() && type() == CONSTANT; |
} |
bool IsConstantFunction() const { |
- return IsConstant() && GetValue()->IsJSFunction(); |
+ return IsConstant() && GetConstant()->IsJSFunction(); |
} |
bool IsDontDelete() const { return details_.IsDontDelete(); } |
bool IsDontEnum() const { return details_.IsDontEnum(); } |
bool IsFound() const { return lookup_type_ != NOT_FOUND; } |
+ bool IsDescriptorOrDictionary() const { |
+ return lookup_type_ == DESCRIPTOR_TYPE || lookup_type_ == DICTIONARY_TYPE; |
+ } |
bool IsTransition() const { return lookup_type_ == TRANSITION_TYPE; } |
bool IsHandler() const { return lookup_type_ == HANDLER_TYPE; } |
bool IsInterceptor() const { return lookup_type_ == INTERCEPTOR_TYPE; } |
@@ -306,20 +304,30 @@ class LookupResult V8_FINAL BASE_EMBEDDED { |
} |
bool IsDataProperty() const { |
- switch (type()) { |
- case FIELD: |
- case NORMAL: |
- case CONSTANT: |
- return true; |
- case CALLBACKS: { |
- Object* callback = GetCallbackObject(); |
- return callback->IsAccessorInfo() || callback->IsForeign(); |
- } |
- case HANDLER: |
- case INTERCEPTOR: |
- case TRANSITION: |
- case NONEXISTENT: |
+ switch (lookup_type_) { |
+ case NOT_FOUND: |
+ case TRANSITION_TYPE: |
+ case HANDLER_TYPE: |
+ case INTERCEPTOR_TYPE: |
return false; |
+ |
+ case DESCRIPTOR_TYPE: |
+ case DICTIONARY_TYPE: |
+ switch (type()) { |
+ case FIELD: |
+ case NORMAL: |
+ case CONSTANT: |
+ return true; |
+ case CALLBACKS: { |
+ Object* callback = GetCallbackObject(); |
+ return callback->IsAccessorInfo() || callback->IsForeign(); |
+ } |
+ case HANDLER: |
+ case INTERCEPTOR: |
+ case NONEXISTENT: |
+ UNREACHABLE(); |
+ return false; |
+ } |
} |
UNREACHABLE(); |
return false; |
@@ -329,45 +337,52 @@ class LookupResult V8_FINAL BASE_EMBEDDED { |
void DisallowCaching() { cacheable_ = false; } |
Object* GetLazyValue() const { |
- switch (type()) { |
- case FIELD: |
- return holder()->RawFastPropertyAt(GetFieldIndex().field_index()); |
- case NORMAL: { |
- Object* value; |
- value = holder()->property_dictionary()->ValueAt(GetDictionaryEntry()); |
- if (holder()->IsGlobalObject()) { |
- value = PropertyCell::cast(value)->value(); |
- } |
- return value; |
- } |
- case CONSTANT: |
- return GetConstant(); |
- case CALLBACKS: |
- case HANDLER: |
- case INTERCEPTOR: |
- case TRANSITION: |
- case NONEXISTENT: |
+ switch (lookup_type_) { |
+ case NOT_FOUND: |
+ case TRANSITION_TYPE: |
+ case HANDLER_TYPE: |
+ case INTERCEPTOR_TYPE: |
return isolate()->heap()->the_hole_value(); |
+ |
+ case DESCRIPTOR_TYPE: |
+ case DICTIONARY_TYPE: |
+ switch (type()) { |
+ case FIELD: |
+ return holder()->RawFastPropertyAt(GetFieldIndex().field_index()); |
+ case NORMAL: { |
+ Object* value = holder()->property_dictionary()->ValueAt( |
+ GetDictionaryEntry()); |
+ if (holder()->IsGlobalObject()) { |
+ value = PropertyCell::cast(value)->value(); |
+ } |
+ return value; |
+ } |
+ case CONSTANT: |
+ return GetConstant(); |
+ case CALLBACKS: |
+ return isolate()->heap()->the_hole_value(); |
+ case HANDLER: |
+ case INTERCEPTOR: |
+ case NONEXISTENT: |
+ UNREACHABLE(); |
+ return NULL; |
+ } |
} |
UNREACHABLE(); |
return NULL; |
} |
Map* GetTransitionTarget() const { |
- return transition_; |
- } |
- |
- PropertyDetails GetTransitionDetails() const { |
ASSERT(IsTransition()); |
- return transition_->GetLastDescriptorDetails(); |
+ return transition_; |
} |
bool IsTransitionToField() const { |
- return IsTransition() && GetTransitionDetails().type() == FIELD; |
+ return IsTransition() && details_.type() == FIELD; |
} |
bool IsTransitionToConstant() const { |
- return IsTransition() && GetTransitionDetails().type() == CONSTANT; |
+ return IsTransition() && details_.type() == CONSTANT; |
} |
int GetDescriptorIndex() const { |
@@ -376,7 +391,8 @@ class LookupResult V8_FINAL BASE_EMBEDDED { |
} |
PropertyIndex GetFieldIndex() const { |
- ASSERT(lookup_type_ == DESCRIPTOR_TYPE); |
+ ASSERT(lookup_type_ == DESCRIPTOR_TYPE || |
+ lookup_type_ == TRANSITION_TYPE); |
return PropertyIndex::NewFieldIndex(GetFieldIndexFromMap(holder()->map())); |
} |
@@ -409,7 +425,8 @@ class LookupResult V8_FINAL BASE_EMBEDDED { |
} |
Object* GetCallbackObject() const { |
- ASSERT(type() == CALLBACKS && !IsTransition()); |
+ ASSERT(!IsTransition()); |
+ ASSERT(type() == CALLBACKS); |
return GetValue(); |
} |
@@ -420,6 +437,8 @@ class LookupResult V8_FINAL BASE_EMBEDDED { |
Object* GetValue() const { |
if (lookup_type_ == DESCRIPTOR_TYPE) { |
return GetValueFromMap(holder()->map()); |
+ } else if (lookup_type_ == TRANSITION_TYPE) { |
+ return GetValueFromMap(transition_); |
} |
// In the dictionary case, the data is held in the value field. |
ASSERT(lookup_type_ == DICTIONARY_TYPE); |
@@ -427,13 +446,15 @@ class LookupResult V8_FINAL BASE_EMBEDDED { |
} |
Object* GetValueFromMap(Map* map) const { |
- ASSERT(lookup_type_ == DESCRIPTOR_TYPE); |
+ ASSERT(lookup_type_ == DESCRIPTOR_TYPE || |
+ lookup_type_ == TRANSITION_TYPE); |
ASSERT(number_ < map->NumberOfOwnDescriptors()); |
return map->instance_descriptors()->GetValue(number_); |
} |
int GetFieldIndexFromMap(Map* map) const { |
- ASSERT(lookup_type_ == DESCRIPTOR_TYPE); |
+ ASSERT(lookup_type_ == DESCRIPTOR_TYPE || |
+ lookup_type_ == TRANSITION_TYPE); |
ASSERT(number_ < map->NumberOfOwnDescriptors()); |
return map->instance_descriptors()->GetFieldIndex(number_); |
} |