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, NORMAL, Representation::None()),
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, NORMAL, Representation::None()),
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 transition_map_;
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() {
111 state_ == TRANSITION && transition_map()->GetBackPointer()->IsMap();
113 property_details_ = transition_map_->GetLastDescriptorDetails();
114 has_property_ = true;
118 void ApplyTransitionToDataProperty();
119 void ReconfigureDataProperty(Handle<Object> value,
120 PropertyAttributes attributes);
121 void TransitionToAccessorProperty(AccessorComponent component,
122 Handle<Object> accessor,
123 PropertyAttributes attributes);
124 PropertyDetails property_details() const {
125 DCHECK(has_property_);
126 return property_details_;
128 bool IsConfigurable() const { return property_details().IsConfigurable(); }
129 bool IsReadOnly() const { return property_details().IsReadOnly(); }
130 Representation representation() const {
131 return property_details().representation();
133 FieldIndex GetFieldIndex() const;
134 Handle<HeapType> GetFieldType() const;
135 int GetConstantIndex() const;
136 Handle<PropertyCell> GetPropertyCell() const;
137 Handle<Object> GetAccessors() const;
138 Handle<Object> GetDataValue() const;
139 void WriteDataValue(Handle<Object> value);
141 void InternalizeName();
144 Handle<Map> GetReceiverMap() const;
146 MUST_USE_RESULT inline JSReceiver* NextHolder(Map* map);
147 inline State LookupInHolder(Map* map, JSReceiver* holder);
148 Handle<Object> FetchValue() const;
149 void ReloadPropertyInformation();
151 bool IsBootstrapping() const;
153 bool check_hidden() const { return (configuration_ & kHidden) != 0; }
154 bool check_interceptor() const {
155 return !IsBootstrapping() && (configuration_ & kInterceptor) != 0;
157 bool check_prototype_chain() const {
158 return (configuration_ & kPrototypeChain) != 0;
160 int descriptor_number() const {
161 DCHECK(has_property_);
162 DCHECK(!holder_map_->is_dictionary_map());
165 int dictionary_entry() const {
166 DCHECK(has_property_);
167 DCHECK(holder_map_->is_dictionary_map());
171 static Configuration ComputeConfiguration(
172 Configuration configuration, Handle<Name> name) {
174 return static_cast<Configuration>(configuration & HIDDEN);
176 return configuration;
180 // If configuration_ becomes mutable, update
181 // HolderIsReceiverOrHiddenPrototype.
182 Configuration configuration_;
185 PropertyDetails property_details_;
188 Handle<Map> holder_map_;
189 Handle<Map> transition_map_;
190 Handle<Object> receiver_;
191 Handle<JSReceiver> holder_;
197 } } // namespace v8::internal
199 #endif // V8_LOOKUP_H_