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.
8 #include "src/factory.h"
9 #include "src/isolate.h"
10 #include "src/objects.h"
15 class LookupIterator FINAL BASE_EMBEDDED {
18 // Configuration bits.
20 kInterceptor = 1 << 1,
21 kPrototypeChain = 1 << 2,
23 // Convience combinations of bits.
24 OWN_SKIP_INTERCEPTOR = 0,
26 HIDDEN_SKIP_INTERCEPTOR = kHidden,
27 HIDDEN = kHidden | kInterceptor,
28 PROTOTYPE_CHAIN_SKIP_INTERCEPTOR = kHidden | kPrototypeChain,
29 PROTOTYPE_CHAIN = kHidden | kPrototypeChain | kInterceptor
40 // Set state_ to BEFORE_PROPERTY to ensure that the next lookup will be a
42 BEFORE_PROPERTY = INTERCEPTOR
45 LookupIterator(Handle<Object> receiver, Handle<Name> name,
46 Configuration configuration = PROTOTYPE_CHAIN)
47 : configuration_(ComputeConfiguration(configuration, name)),
49 property_details_(NONE, v8::internal::DATA, 0),
50 isolate_(name->GetIsolate()),
53 number_(DescriptorArray::kNotFound) {
55 holder_map_ = handle(holder_->map(), isolate_);
59 LookupIterator(Handle<Object> receiver, Handle<Name> name,
60 Handle<JSReceiver> holder,
61 Configuration configuration = PROTOTYPE_CHAIN)
62 : configuration_(ComputeConfiguration(configuration, name)),
64 property_details_(NONE, v8::internal::DATA, 0),
65 isolate_(name->GetIsolate()),
67 holder_map_(holder->map(), isolate_),
70 number_(DescriptorArray::kNotFound) {
74 Isolate* isolate() const { return isolate_; }
75 State state() const { return state_; }
76 Handle<Name> name() const { return name_; }
78 bool IsFound() const { return state_ != NOT_FOUND; }
81 has_property_ = false;
85 Factory* factory() const { return isolate_->factory(); }
86 Handle<Object> GetReceiver() const { return receiver_; }
87 Handle<JSObject> GetStoreTarget() const;
88 bool is_dictionary_holder() const { return holder_map_->is_dictionary_map(); }
89 Handle<Map> transition_map() const {
90 DCHECK_EQ(TRANSITION, state_);
91 return Handle<Map>::cast(transition_);
94 Handle<T> GetHolder() const {
96 return Handle<T>::cast(holder_);
98 Handle<JSReceiver> GetRoot() const;
99 bool HolderIsReceiverOrHiddenPrototype() const;
102 bool HasAccess(v8::AccessType access_type) const;
105 void PrepareForDataProperty(Handle<Object> value);
106 void PrepareTransitionToDataProperty(Handle<Object> value,
107 PropertyAttributes attributes,
108 Object::StoreFromKeyed store_mode);
109 bool IsCacheableTransition() {
110 if (state_ != TRANSITION) return false;
111 return transition_->IsPropertyCell() ||
112 transition_map()->GetBackPointer()->IsMap();
114 void ApplyTransitionToDataProperty();
115 void ReconfigureDataProperty(Handle<Object> value,
116 PropertyAttributes attributes);
117 void TransitionToAccessorProperty(AccessorComponent component,
118 Handle<Object> accessor,
119 PropertyAttributes attributes);
120 PropertyDetails property_details() const {
121 DCHECK(has_property_);
122 return property_details_;
124 bool IsConfigurable() const { return property_details().IsConfigurable(); }
125 bool IsReadOnly() const { return property_details().IsReadOnly(); }
126 Representation representation() const {
127 return property_details().representation();
129 FieldIndex GetFieldIndex() const;
130 Handle<HeapType> GetFieldType() const;
131 int GetAccessorIndex() const;
132 int GetConstantIndex() const;
133 Handle<PropertyCell> GetPropertyCell() const;
134 Handle<PropertyCell> GetTransitionPropertyCell() const {
135 DCHECK_EQ(TRANSITION, state_);
136 return Handle<PropertyCell>::cast(transition_);
138 Handle<Object> GetAccessors() const;
139 Handle<Object> GetDataValue() const;
140 // Usually returns the value that was passed in, but may perform
141 // non-observable modifications on it, such as internalize strings.
142 Handle<Object> WriteDataValue(Handle<Object> value);
144 // Checks whether the receiver is an indexed exotic object
145 // and name is a special numeric index.
146 bool IsSpecialNumericIndex() const;
148 void InternalizeName();
151 Handle<Map> GetReceiverMap() const;
153 MUST_USE_RESULT inline JSReceiver* NextHolder(Map* map);
154 inline State LookupInHolder(Map* map, JSReceiver* holder);
155 Handle<Object> FetchValue() const;
156 void ReloadPropertyInformation();
158 bool IsBootstrapping() const;
160 bool check_hidden() const { return (configuration_ & kHidden) != 0; }
161 bool check_interceptor() const {
162 return !IsBootstrapping() && (configuration_ & kInterceptor) != 0;
164 bool check_prototype_chain() const {
165 return (configuration_ & kPrototypeChain) != 0;
167 int descriptor_number() const {
168 DCHECK(has_property_);
169 DCHECK(!holder_map_->is_dictionary_map());
172 int dictionary_entry() const {
173 DCHECK(has_property_);
174 DCHECK(holder_map_->is_dictionary_map());
178 static Configuration ComputeConfiguration(
179 Configuration configuration, Handle<Name> name) {
181 return static_cast<Configuration>(configuration &
182 HIDDEN_SKIP_INTERCEPTOR);
184 return configuration;
188 // If configuration_ becomes mutable, update
189 // HolderIsReceiverOrHiddenPrototype.
190 Configuration configuration_;
193 PropertyDetails property_details_;
196 Handle<Map> holder_map_;
197 Handle<Object> transition_;
198 Handle<Object> receiver_;
199 Handle<JSReceiver> holder_;
205 } } // namespace v8::internal
207 #endif // V8_LOOKUP_H_