1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
10 #include "src/factory.h"
11 #include "src/field-index.h"
12 #include "src/field-index-inl.h"
13 #include "src/isolate.h"
14 #include "src/types.h"
19 // Abstraction for elements in instance-descriptor arrays.
21 // Each descriptor has a key, property attributes, property type,
22 // property index (in the actual instance-descriptor array) and
23 // optionally a piece of data.
24 class Descriptor BASE_EMBEDDED {
26 void KeyToUniqueName() {
27 if (!key_->IsUniqueName()) {
28 key_ = key_->GetIsolate()->factory()->InternalizeString(
29 Handle<String>::cast(key_));
33 Handle<Name> GetKey() const { return key_; }
34 Handle<Object> GetValue() const { return value_; }
35 PropertyDetails GetDetails() const { return details_; }
37 void SetSortedKeyIndex(int index) { details_ = details_.set_pointer(index); }
41 Handle<Object> value_;
42 PropertyDetails details_;
45 Descriptor() : details_(Smi::FromInt(0)) {}
47 void Init(Handle<Name> key, Handle<Object> value, PropertyDetails details) {
53 Descriptor(Handle<Name> key, Handle<Object> value, PropertyDetails details)
58 Descriptor(Handle<Name> key,
60 PropertyAttributes attributes,
62 Representation representation,
66 details_(attributes, type, representation, field_index) { }
68 friend class DescriptorArray;
73 std::ostream& operator<<(std::ostream& os, const Descriptor& d);
76 class FieldDescriptor FINAL : public Descriptor {
78 FieldDescriptor(Handle<Name> key,
80 PropertyAttributes attributes,
81 Representation representation)
82 : Descriptor(key, HeapType::Any(key->GetIsolate()), attributes,
83 FIELD, representation, field_index) {}
84 FieldDescriptor(Handle<Name> key,
86 Handle<HeapType> field_type,
87 PropertyAttributes attributes,
88 Representation representation)
89 : Descriptor(key, field_type, attributes, FIELD,
90 representation, field_index) { }
94 class ConstantDescriptor FINAL : public Descriptor {
96 ConstantDescriptor(Handle<Name> key,
98 PropertyAttributes attributes)
99 : Descriptor(key, value, attributes, CONSTANT,
100 value->OptimalRepresentation()) {}
104 class CallbacksDescriptor FINAL : public Descriptor {
106 CallbacksDescriptor(Handle<Name> key,
107 Handle<Object> foreign,
108 PropertyAttributes attributes)
109 : Descriptor(key, foreign, attributes, CALLBACKS,
110 Representation::Tagged()) {}
114 class LookupResult FINAL BASE_EMBEDDED {
116 explicit LookupResult(Isolate* isolate)
118 next_(isolate->top_lookup_result()),
119 lookup_type_(NOT_FOUND),
122 details_(NONE, NORMAL, Representation::None()) {
123 isolate->set_top_lookup_result(this);
127 DCHECK(isolate()->top_lookup_result() == this);
128 isolate()->set_top_lookup_result(next_);
131 Isolate* isolate() const { return isolate_; }
133 void DescriptorResult(JSObject* holder, PropertyDetails details, int number) {
134 lookup_type_ = DESCRIPTOR_TYPE;
141 void TransitionResult(JSObject* holder, Map* target) {
142 lookup_type_ = TRANSITION_TYPE;
143 number_ = target->LastAdded();
144 details_ = target->instance_descriptors()->GetDetails(number_);
146 transition_ = target;
150 lookup_type_ = NOT_FOUND;
151 details_ = PropertyDetails(NONE, NORMAL, Representation::None());
156 Representation representation() const {
158 return details_.representation();
161 // Property callbacks does not include transitions to callbacks.
162 bool IsPropertyCallbacks() const {
163 DCHECK(!(details_.type() == CALLBACKS && !IsFound()));
164 return !IsTransition() && details_.type() == CALLBACKS;
167 bool IsReadOnly() const {
169 return details_.IsReadOnly();
172 bool IsField() const {
173 DCHECK(!(details_.type() == FIELD && !IsFound()));
174 return lookup_type_ == DESCRIPTOR_TYPE && details_.type() == FIELD;
177 bool IsConstant() const {
178 DCHECK(!(details_.type() == CONSTANT && !IsFound()));
179 return lookup_type_ == DESCRIPTOR_TYPE && details_.type() == CONSTANT;
182 bool IsConfigurable() const { return details_.IsConfigurable(); }
183 bool IsFound() const { return lookup_type_ != NOT_FOUND; }
184 bool IsTransition() const { return lookup_type_ == TRANSITION_TYPE; }
186 // Is the result is a property excluding transitions and the null descriptor?
187 bool IsProperty() const {
188 return IsFound() && !IsTransition();
191 Map* GetTransitionTarget() const {
192 DCHECK(IsTransition());
196 bool IsTransitionToField() const {
197 return IsTransition() && details_.type() == FIELD;
200 int GetLocalFieldIndexFromMap(Map* map) const {
201 return GetFieldIndexFromMap(map) - map->inobject_properties();
204 Object* GetConstantFromMap(Map* map) const {
205 DCHECK(details_.type() == CONSTANT);
206 return GetValueFromMap(map);
209 Object* GetValueFromMap(Map* map) const {
210 DCHECK(lookup_type_ == DESCRIPTOR_TYPE ||
211 lookup_type_ == TRANSITION_TYPE);
212 DCHECK(number_ < map->NumberOfOwnDescriptors());
213 return map->instance_descriptors()->GetValue(number_);
216 int GetFieldIndexFromMap(Map* map) const {
217 DCHECK(lookup_type_ == DESCRIPTOR_TYPE ||
218 lookup_type_ == TRANSITION_TYPE);
219 DCHECK(number_ < map->NumberOfOwnDescriptors());
220 return map->instance_descriptors()->GetFieldIndex(number_);
223 HeapType* GetFieldTypeFromMap(Map* map) const {
224 DCHECK_NE(NOT_FOUND, lookup_type_);
225 DCHECK(number_ < map->NumberOfOwnDescriptors());
226 return map->instance_descriptors()->GetFieldType(number_);
229 Map* GetFieldOwnerFromMap(Map* map) const {
230 DCHECK(lookup_type_ == DESCRIPTOR_TYPE ||
231 lookup_type_ == TRANSITION_TYPE);
232 DCHECK(number_ < map->NumberOfOwnDescriptors());
233 return map->FindFieldOwner(number_);
236 void Iterate(ObjectVisitor* visitor);
242 // Where did we find the result;
243 enum { NOT_FOUND, DESCRIPTOR_TYPE, TRANSITION_TYPE } lookup_type_;
248 PropertyDetails details_;
252 std::ostream& operator<<(std::ostream& os, const LookupResult& r);
253 } } // namespace v8::internal
255 #endif // V8_PROPERTY_H_