#ifndef V8_PROPERTY_H_
#define V8_PROPERTY_H_
-#include "isolate.h"
-#include "factory.h"
-#include "types.h"
+#include "src/factory.h"
+#include "src/field-index.h"
+#include "src/field-index-inl.h"
+#include "src/isolate.h"
+#include "src/types.h"
namespace v8 {
namespace internal {
+class OStream;
+
// Abstraction for elements in instance-descriptor arrays.
//
// Each descriptor has a key, property attributes, property type,
}
}
- Handle<Name> GetKey() { return key_; }
- Handle<Object> GetValue() { return value_; }
- PropertyDetails GetDetails() { return details_; }
-
-#ifdef OBJECT_PRINT
- void Print(FILE* out);
-#endif
+ Handle<Name> GetKey() const { return key_; }
+ Handle<Object> GetValue() const { return value_; }
+ PropertyDetails GetDetails() const { return details_; }
void SetSortedKeyIndex(int index) { details_ = details_.set_pointer(index); }
};
-class FieldDescriptor V8_FINAL : public Descriptor {
+OStream& operator<<(OStream& os, const Descriptor& d);
+
+
+class FieldDescriptor FINAL : public Descriptor {
public:
FieldDescriptor(Handle<Name> key,
int field_index,
};
-class ConstantDescriptor V8_FINAL : public Descriptor {
+class ConstantDescriptor FINAL : public Descriptor {
public:
ConstantDescriptor(Handle<Name> key,
Handle<Object> value,
};
-class CallbacksDescriptor V8_FINAL : public Descriptor {
+class CallbacksDescriptor FINAL : public Descriptor {
public:
CallbacksDescriptor(Handle<Name> key,
Handle<Object> foreign,
};
-// Holds a property index value distinguishing if it is a field index or an
-// index inside the object header.
-class PropertyIndex V8_FINAL {
- public:
- static PropertyIndex NewFieldIndex(int index) {
- return PropertyIndex(index, false);
- }
- static PropertyIndex NewHeaderIndex(int index) {
- return PropertyIndex(index, true);
- }
-
- bool is_field_index() { return (index_ & kHeaderIndexBit) == 0; }
- bool is_header_index() { return (index_ & kHeaderIndexBit) != 0; }
-
- int field_index() {
- ASSERT(is_field_index());
- return value();
- }
- int header_index() {
- ASSERT(is_header_index());
- return value();
- }
-
- bool is_inobject(Handle<JSObject> holder) {
- if (is_header_index()) return true;
- return field_index() < holder->map()->inobject_properties();
- }
-
- int translate(Handle<JSObject> holder) {
- if (is_header_index()) return header_index();
- int index = field_index() - holder->map()->inobject_properties();
- if (index >= 0) return index;
- return index + holder->map()->instance_size() / kPointerSize;
- }
-
- private:
- static const int kHeaderIndexBit = 1 << 31;
- static const int kIndexMask = ~kHeaderIndexBit;
-
- int value() { return index_ & kIndexMask; }
-
- PropertyIndex(int index, bool is_header_based)
- : index_(index | (is_header_based ? kHeaderIndexBit : 0)) {
- ASSERT(index <= kIndexMask);
- }
-
- int index_;
-};
-
-
-class LookupResult V8_FINAL BASE_EMBEDDED {
+class LookupResult FINAL BASE_EMBEDDED {
public:
explicit LookupResult(Isolate* isolate)
: isolate_(isolate),
lookup_type_(NOT_FOUND),
holder_(NULL),
transition_(NULL),
- cacheable_(true),
- details_(NONE, NONEXISTENT, Representation::None()) {
+ details_(NONE, NORMAL, Representation::None()) {
isolate->set_top_lookup_result(this);
}
~LookupResult() {
- ASSERT(isolate()->top_lookup_result() == this);
+ DCHECK(isolate()->top_lookup_result() == this);
isolate()->set_top_lookup_result(next_);
}
number_ = number;
}
- bool CanHoldValue(Handle<Object> value) const {
- switch (type()) {
- case NORMAL:
- return true;
- case FIELD:
- return value->FitsRepresentation(representation()) &&
- GetFieldType()->NowContains(value);
- case CONSTANT:
- ASSERT(GetConstant() != *value ||
- value->FitsRepresentation(representation()));
- return GetConstant() == *value;
- case CALLBACKS:
- case HANDLER:
- case INTERCEPTOR:
- return true;
- case NONEXISTENT:
- UNREACHABLE();
- }
- UNREACHABLE();
- return true;
- }
-
void TransitionResult(JSObject* holder, Map* target) {
lookup_type_ = TRANSITION_TYPE;
number_ = target->LastAdded();
transition_ = target;
}
- void DictionaryResult(JSObject* holder, int entry) {
- lookup_type_ = DICTIONARY_TYPE;
- holder_ = holder;
- transition_ = NULL;
- details_ = holder->property_dictionary()->DetailsAt(entry);
- number_ = entry;
- }
-
- void HandlerResult(JSProxy* proxy) {
- lookup_type_ = HANDLER_TYPE;
- holder_ = proxy;
- transition_ = NULL;
- details_ = PropertyDetails(NONE, HANDLER, Representation::Tagged());
- cacheable_ = false;
- }
-
- void InterceptorResult(JSObject* holder) {
- lookup_type_ = INTERCEPTOR_TYPE;
- holder_ = holder;
- transition_ = NULL;
- details_ = PropertyDetails(NONE, INTERCEPTOR, Representation::Tagged());
- }
-
void NotFound() {
lookup_type_ = NOT_FOUND;
- details_ = PropertyDetails(NONE, NONEXISTENT, Representation::None());
+ details_ = PropertyDetails(NONE, NORMAL, Representation::None());
holder_ = NULL;
transition_ = NULL;
}
- JSObject* holder() const {
- ASSERT(IsFound());
- return JSObject::cast(holder_);
- }
-
- JSProxy* proxy() const {
- ASSERT(IsHandler());
- return JSProxy::cast(holder_);
- }
-
- PropertyType type() const {
- ASSERT(IsFound());
- return details_.type();
- }
-
Representation representation() const {
- ASSERT(IsFound());
- ASSERT(details_.type() != NONEXISTENT);
+ DCHECK(IsFound());
return details_.representation();
}
- PropertyAttributes GetAttributes() const {
- ASSERT(IsFound());
- ASSERT(details_.type() != NONEXISTENT);
- return details_.attributes();
- }
-
- PropertyDetails GetPropertyDetails() const {
- return details_;
- }
-
- bool IsFastPropertyType() const {
- ASSERT(IsFound());
- return IsTransition() || type() != NORMAL;
- }
-
// Property callbacks does not include transitions to callbacks.
bool IsPropertyCallbacks() const {
- ASSERT(!(details_.type() == CALLBACKS && !IsFound()));
+ DCHECK(!(details_.type() == CALLBACKS && !IsFound()));
return !IsTransition() && details_.type() == CALLBACKS;
}
bool IsReadOnly() const {
- ASSERT(IsFound());
- ASSERT(details_.type() != NONEXISTENT);
+ DCHECK(IsFound());
return details_.IsReadOnly();
}
bool IsField() const {
- ASSERT(!(details_.type() == FIELD && !IsFound()));
- return IsDescriptorOrDictionary() && type() == FIELD;
- }
-
- bool IsNormal() const {
- ASSERT(!(details_.type() == NORMAL && !IsFound()));
- return IsDescriptorOrDictionary() && type() == NORMAL;
+ DCHECK(!(details_.type() == FIELD && !IsFound()));
+ return lookup_type_ == DESCRIPTOR_TYPE && details_.type() == FIELD;
}
bool IsConstant() const {
- ASSERT(!(details_.type() == CONSTANT && !IsFound()));
- return IsDescriptorOrDictionary() && type() == CONSTANT;
- }
-
- bool IsConstantFunction() const {
- return IsConstant() && GetConstant()->IsJSFunction();
+ DCHECK(!(details_.type() == CONSTANT && !IsFound()));
+ return lookup_type_ == DESCRIPTOR_TYPE && details_.type() == CONSTANT;
}
- bool IsDontDelete() const { return details_.IsDontDelete(); }
- bool IsDontEnum() const { return details_.IsDontEnum(); }
+ bool IsConfigurable() const { return details_.IsConfigurable(); }
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; }
// Is the result is a property excluding transitions and the null descriptor?
bool IsProperty() const {
return IsFound() && !IsTransition();
}
- bool IsDataProperty() const {
- 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();
- ASSERT(!callback->IsForeign());
- return callback->IsAccessorInfo();
- }
- case HANDLER:
- case INTERCEPTOR:
- case NONEXISTENT:
- UNREACHABLE();
- return false;
- }
- }
- UNREACHABLE();
- return false;
- }
-
- bool IsCacheable() const { return cacheable_; }
- void DisallowCaching() { cacheable_ = false; }
-
- Object* GetLazyValue() const {
- 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 {
- ASSERT(IsTransition());
+ DCHECK(IsTransition());
return transition_;
}
return IsTransition() && details_.type() == FIELD;
}
- bool IsTransitionToConstant() const {
- return IsTransition() && details_.type() == CONSTANT;
- }
-
- int GetDescriptorIndex() const {
- ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
- return number_;
- }
-
- PropertyIndex GetFieldIndex() const {
- ASSERT(lookup_type_ == DESCRIPTOR_TYPE ||
- lookup_type_ == TRANSITION_TYPE);
- return PropertyIndex::NewFieldIndex(GetFieldIndexFromMap(holder()->map()));
- }
-
int GetLocalFieldIndexFromMap(Map* map) const {
return GetFieldIndexFromMap(map) - map->inobject_properties();
}
- int GetDictionaryEntry() const {
- ASSERT(lookup_type_ == DICTIONARY_TYPE);
- return number_;
- }
-
- JSFunction* GetConstantFunction() const {
- ASSERT(type() == CONSTANT);
- return JSFunction::cast(GetValue());
- }
-
Object* GetConstantFromMap(Map* map) const {
- ASSERT(type() == CONSTANT);
+ DCHECK(details_.type() == CONSTANT);
return GetValueFromMap(map);
}
- JSFunction* GetConstantFunctionFromMap(Map* map) const {
- return JSFunction::cast(GetConstantFromMap(map));
- }
-
- Object* GetConstant() const {
- ASSERT(type() == CONSTANT);
- return GetValue();
- }
-
- Object* GetCallbackObject() const {
- ASSERT(!IsTransition());
- ASSERT(type() == CALLBACKS);
- return GetValue();
- }
-
-#ifdef OBJECT_PRINT
- void Print(FILE* out);
-#endif
-
- 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);
- return holder()->GetNormalizedProperty(this);
- }
-
Object* GetValueFromMap(Map* map) const {
- ASSERT(lookup_type_ == DESCRIPTOR_TYPE ||
+ DCHECK(lookup_type_ == DESCRIPTOR_TYPE ||
lookup_type_ == TRANSITION_TYPE);
- ASSERT(number_ < map->NumberOfOwnDescriptors());
+ DCHECK(number_ < map->NumberOfOwnDescriptors());
return map->instance_descriptors()->GetValue(number_);
}
int GetFieldIndexFromMap(Map* map) const {
- ASSERT(lookup_type_ == DESCRIPTOR_TYPE ||
+ DCHECK(lookup_type_ == DESCRIPTOR_TYPE ||
lookup_type_ == TRANSITION_TYPE);
- ASSERT(number_ < map->NumberOfOwnDescriptors());
+ DCHECK(number_ < map->NumberOfOwnDescriptors());
return map->instance_descriptors()->GetFieldIndex(number_);
}
- HeapType* GetFieldType() const {
- ASSERT(type() == FIELD);
- if (lookup_type_ == DESCRIPTOR_TYPE) {
- return GetFieldTypeFromMap(holder()->map());
- }
- ASSERT(lookup_type_ == TRANSITION_TYPE);
- return GetFieldTypeFromMap(transition_);
- }
-
HeapType* GetFieldTypeFromMap(Map* map) const {
- ASSERT(lookup_type_ == DESCRIPTOR_TYPE ||
- lookup_type_ == TRANSITION_TYPE);
- ASSERT(number_ < map->NumberOfOwnDescriptors());
+ DCHECK_NE(NOT_FOUND, lookup_type_);
+ DCHECK(number_ < map->NumberOfOwnDescriptors());
return map->instance_descriptors()->GetFieldType(number_);
}
- Map* GetFieldOwner() const {
- return GetFieldOwnerFromMap(holder()->map());
- }
-
Map* GetFieldOwnerFromMap(Map* map) const {
- ASSERT(lookup_type_ == DESCRIPTOR_TYPE ||
+ DCHECK(lookup_type_ == DESCRIPTOR_TYPE ||
lookup_type_ == TRANSITION_TYPE);
- ASSERT(number_ < map->NumberOfOwnDescriptors());
+ DCHECK(number_ < map->NumberOfOwnDescriptors());
return map->FindFieldOwner(number_);
}
LookupResult* next_;
// Where did we find the result;
- enum {
- NOT_FOUND,
- DESCRIPTOR_TYPE,
- TRANSITION_TYPE,
- DICTIONARY_TYPE,
- HANDLER_TYPE,
- INTERCEPTOR_TYPE
- } lookup_type_;
+ enum { NOT_FOUND, DESCRIPTOR_TYPE, TRANSITION_TYPE } lookup_type_;
JSReceiver* holder_;
Map* transition_;
int number_;
- bool cacheable_;
PropertyDetails details_;
};
+
+OStream& operator<<(OStream& os, const LookupResult& r);
} } // namespace v8::internal
#endif // V8_PROPERTY_H_