| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_LOOKUP_H_ | 5 #ifndef V8_LOOKUP_H_ |
| 6 #define V8_LOOKUP_H_ | 6 #define V8_LOOKUP_H_ |
| 7 | 7 |
| 8 #include "src/factory.h" | 8 #include "src/factory.h" |
| 9 #include "src/isolate.h" | 9 #include "src/isolate.h" |
| 10 #include "src/objects.h" | 10 #include "src/objects.h" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 HIDDEN = kHidden | kInterceptor, | 27 HIDDEN = kHidden | kInterceptor, |
| 28 PROTOTYPE_CHAIN_SKIP_INTERCEPTOR = kHidden | kPrototypeChain, | 28 PROTOTYPE_CHAIN_SKIP_INTERCEPTOR = kHidden | kPrototypeChain, |
| 29 PROTOTYPE_CHAIN = kHidden | kPrototypeChain | kInterceptor | 29 PROTOTYPE_CHAIN = kHidden | kPrototypeChain | kInterceptor |
| 30 }; | 30 }; |
| 31 | 31 |
| 32 enum State { | 32 enum State { |
| 33 ACCESS_CHECK, | 33 ACCESS_CHECK, |
| 34 INTERCEPTOR, | 34 INTERCEPTOR, |
| 35 JSPROXY, | 35 JSPROXY, |
| 36 NOT_FOUND, | 36 NOT_FOUND, |
| 37 PROPERTY, | 37 UNKNOWN, // Dictionary-mode holder map without a holder. |
| 38 ACCESSOR, |
| 39 DATA, |
| 38 TRANSITION, | 40 TRANSITION, |
| 39 // Set state_ to BEFORE_PROPERTY to ensure that the next lookup will be a | 41 // Set state_ to BEFORE_PROPERTY to ensure that the next lookup will be a |
| 40 // PROPERTY lookup. | 42 // PROPERTY lookup. |
| 41 BEFORE_PROPERTY = INTERCEPTOR | 43 BEFORE_PROPERTY = INTERCEPTOR |
| 42 }; | 44 }; |
| 43 | 45 |
| 44 enum PropertyKind { | |
| 45 DATA, | |
| 46 ACCESSOR | |
| 47 }; | |
| 48 | |
| 49 enum PropertyEncoding { | 46 enum PropertyEncoding { |
| 50 DICTIONARY, | 47 DICTIONARY, |
| 51 DESCRIPTOR | 48 DESCRIPTOR |
| 52 }; | 49 }; |
| 53 | 50 |
| 54 LookupIterator(Handle<Object> receiver, Handle<Name> name, | 51 LookupIterator(Handle<Object> receiver, Handle<Name> name, |
| 55 Configuration configuration = PROTOTYPE_CHAIN) | 52 Configuration configuration = PROTOTYPE_CHAIN) |
| 56 : configuration_(ComputeConfiguration(configuration, name)), | 53 : configuration_(ComputeConfiguration(configuration, name)), |
| 57 state_(NOT_FOUND), | 54 state_(NOT_FOUND), |
| 58 property_kind_(DATA), | |
| 59 property_encoding_(DESCRIPTOR), | 55 property_encoding_(DESCRIPTOR), |
| 60 property_details_(NONE, NORMAL, Representation::None()), | 56 property_details_(NONE, NORMAL, Representation::None()), |
| 61 isolate_(name->GetIsolate()), | 57 isolate_(name->GetIsolate()), |
| 62 name_(name), | 58 name_(name), |
| 63 maybe_receiver_(receiver), | 59 maybe_receiver_(receiver), |
| 64 number_(DescriptorArray::kNotFound) { | 60 number_(DescriptorArray::kNotFound) { |
| 65 Handle<JSReceiver> root = GetRoot(); | 61 Handle<JSReceiver> root = GetRoot(); |
| 66 holder_map_ = handle(root->map(), isolate_); | 62 holder_map_ = handle(root->map(), isolate_); |
| 67 maybe_holder_ = root; | 63 maybe_holder_ = root; |
| 68 Next(); | 64 Next(); |
| 69 } | 65 } |
| 70 | 66 |
| 71 LookupIterator(Handle<Object> receiver, Handle<Name> name, | 67 LookupIterator(Handle<Object> receiver, Handle<Name> name, |
| 72 Handle<JSReceiver> holder, | 68 Handle<JSReceiver> holder, |
| 73 Configuration configuration = PROTOTYPE_CHAIN) | 69 Configuration configuration = PROTOTYPE_CHAIN) |
| 74 : configuration_(ComputeConfiguration(configuration, name)), | 70 : configuration_(ComputeConfiguration(configuration, name)), |
| 75 state_(NOT_FOUND), | 71 state_(NOT_FOUND), |
| 76 property_kind_(DATA), | |
| 77 property_encoding_(DESCRIPTOR), | 72 property_encoding_(DESCRIPTOR), |
| 78 property_details_(NONE, NORMAL, Representation::None()), | 73 property_details_(NONE, NORMAL, Representation::None()), |
| 79 isolate_(name->GetIsolate()), | 74 isolate_(name->GetIsolate()), |
| 80 name_(name), | 75 name_(name), |
| 81 holder_map_(holder->map(), isolate_), | 76 holder_map_(holder->map(), isolate_), |
| 82 maybe_receiver_(receiver), | 77 maybe_receiver_(receiver), |
| 83 maybe_holder_(holder), | 78 maybe_holder_(holder), |
| 84 number_(DescriptorArray::kNotFound) { | 79 number_(DescriptorArray::kNotFound) { |
| 85 Next(); | 80 Next(); |
| 86 } | 81 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 111 DCHECK(IsFound()); | 106 DCHECK(IsFound()); |
| 112 return Handle<T>::cast(maybe_holder_.ToHandleChecked()); | 107 return Handle<T>::cast(maybe_holder_.ToHandleChecked()); |
| 113 } | 108 } |
| 114 Handle<JSReceiver> GetRoot() const; | 109 Handle<JSReceiver> GetRoot() const; |
| 115 bool HolderIsReceiverOrHiddenPrototype() const; | 110 bool HolderIsReceiverOrHiddenPrototype() const; |
| 116 | 111 |
| 117 /* ACCESS_CHECK */ | 112 /* ACCESS_CHECK */ |
| 118 bool HasAccess(v8::AccessType access_type) const; | 113 bool HasAccess(v8::AccessType access_type) const; |
| 119 | 114 |
| 120 /* PROPERTY */ | 115 /* PROPERTY */ |
| 121 // HasProperty needs to be called before any of the other PROPERTY methods | |
| 122 // below can be used. It ensures that we are able to provide a definite | |
| 123 // answer, and loads extra information about the property. | |
| 124 bool HasProperty(); | |
| 125 void PrepareForDataProperty(Handle<Object> value); | 116 void PrepareForDataProperty(Handle<Object> value); |
| 126 void PrepareTransitionToDataProperty(Handle<Object> value, | 117 void PrepareTransitionToDataProperty(Handle<Object> value, |
| 127 PropertyAttributes attributes, | 118 PropertyAttributes attributes, |
| 128 Object::StoreFromKeyed store_mode); | 119 Object::StoreFromKeyed store_mode); |
| 129 bool IsCacheableTransition() { | 120 bool IsCacheableTransition() { |
| 130 bool cacheable = | 121 bool cacheable = |
| 131 state_ == TRANSITION && transition_map()->GetBackPointer()->IsMap(); | 122 state_ == TRANSITION && transition_map()->GetBackPointer()->IsMap(); |
| 132 if (cacheable) { | 123 if (cacheable) { |
| 133 property_details_ = transition_map_->GetLastDescriptorDetails(); | 124 property_details_ = transition_map_->GetLastDescriptorDetails(); |
| 134 LoadPropertyKind(); | |
| 135 has_property_ = true; | 125 has_property_ = true; |
| 136 } | 126 } |
| 137 return cacheable; | 127 return cacheable; |
| 138 } | 128 } |
| 139 void ApplyTransitionToDataProperty(); | 129 void ApplyTransitionToDataProperty(); |
| 140 void ReconfigureDataProperty(Handle<Object> value, | 130 void ReconfigureDataProperty(Handle<Object> value, |
| 141 PropertyAttributes attributes); | 131 PropertyAttributes attributes); |
| 142 void TransitionToAccessorProperty(AccessorComponent component, | 132 void TransitionToAccessorProperty(AccessorComponent component, |
| 143 Handle<Object> accessor, | 133 Handle<Object> accessor, |
| 144 PropertyAttributes attributes); | 134 PropertyAttributes attributes); |
| 145 PropertyKind property_kind() const { | |
| 146 DCHECK(has_property_); | |
| 147 return property_kind_; | |
| 148 } | |
| 149 PropertyEncoding property_encoding() const { | 135 PropertyEncoding property_encoding() const { |
| 150 DCHECK(has_property_); | 136 DCHECK(has_property_); |
| 151 return property_encoding_; | 137 return property_encoding_; |
| 152 } | 138 } |
| 153 PropertyDetails property_details() const { | 139 PropertyDetails property_details() const { |
| 154 DCHECK(has_property_); | 140 DCHECK(has_property_); |
| 155 return property_details_; | 141 return property_details_; |
| 156 } | 142 } |
| 157 bool IsConfigurable() const { return property_details().IsConfigurable(); } | 143 bool IsConfigurable() const { return property_details().IsConfigurable(); } |
| 158 bool IsReadOnly() const { return property_details().IsReadOnly(); } | 144 bool IsReadOnly() const { return property_details().IsReadOnly(); } |
| 159 Representation representation() const { | 145 Representation representation() const { |
| 160 return property_details().representation(); | 146 return property_details().representation(); |
| 161 } | 147 } |
| 162 FieldIndex GetFieldIndex() const; | 148 FieldIndex GetFieldIndex() const; |
| 163 Handle<HeapType> GetFieldType() const; | 149 Handle<HeapType> GetFieldType() const; |
| 164 int GetConstantIndex() const; | 150 int GetConstantIndex() const; |
| 165 Handle<PropertyCell> GetPropertyCell() const; | 151 Handle<PropertyCell> GetPropertyCell() const; |
| 166 Handle<Object> GetAccessors() const; | 152 Handle<Object> GetAccessors() const; |
| 167 Handle<Object> GetDataValue() const; | 153 Handle<Object> GetDataValue() const; |
| 168 void WriteDataValue(Handle<Object> value); | 154 void WriteDataValue(Handle<Object> value); |
| 169 | 155 |
| 170 void InternalizeName(); | 156 void InternalizeName(); |
| 171 | 157 |
| 172 private: | 158 private: |
| 173 Handle<Map> GetReceiverMap() const; | 159 Handle<Map> GetReceiverMap() const; |
| 174 | 160 |
| 175 MUST_USE_RESULT inline JSReceiver* NextHolder(Map* map); | 161 MUST_USE_RESULT inline JSReceiver* NextHolder(Map* map); |
| 176 inline State LookupInHolder(Map* map); | 162 inline State LookupInHolder(Map* map, JSReceiver* holder); |
| 177 Handle<Object> FetchValue() const; | 163 Handle<Object> FetchValue() const; |
| 178 void ReloadPropertyInformation(); | 164 void ReloadPropertyInformation(); |
| 179 void LoadPropertyKind(); | |
| 180 | 165 |
| 181 bool IsBootstrapping() const; | 166 bool IsBootstrapping() const; |
| 182 | 167 |
| 183 // Methods that fetch data from the holder ensure they always have a holder. | 168 // Methods that fetch data from the holder ensure they always have a holder. |
| 184 // This means the receiver needs to be present as opposed to just the receiver | 169 // This means the receiver needs to be present as opposed to just the receiver |
| 185 // map. Other objects in the prototype chain are transitively guaranteed to be | 170 // map. Other objects in the prototype chain are transitively guaranteed to be |
| 186 // present via the receiver map. | 171 // present via the receiver map. |
| 187 bool is_guaranteed_to_have_holder() const { | 172 bool is_guaranteed_to_have_holder() const { |
| 188 return !maybe_receiver_.is_null(); | 173 return !maybe_receiver_.is_null(); |
| 189 } | 174 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 212 } else { | 197 } else { |
| 213 return configuration; | 198 return configuration; |
| 214 } | 199 } |
| 215 } | 200 } |
| 216 | 201 |
| 217 // If configuration_ becomes mutable, update | 202 // If configuration_ becomes mutable, update |
| 218 // HolderIsReceiverOrHiddenPrototype. | 203 // HolderIsReceiverOrHiddenPrototype. |
| 219 Configuration configuration_; | 204 Configuration configuration_; |
| 220 State state_; | 205 State state_; |
| 221 bool has_property_; | 206 bool has_property_; |
| 222 PropertyKind property_kind_; | |
| 223 PropertyEncoding property_encoding_; | 207 PropertyEncoding property_encoding_; |
| 224 PropertyDetails property_details_; | 208 PropertyDetails property_details_; |
| 225 Isolate* isolate_; | 209 Isolate* isolate_; |
| 226 Handle<Name> name_; | 210 Handle<Name> name_; |
| 227 Handle<Map> holder_map_; | 211 Handle<Map> holder_map_; |
| 228 Handle<Map> transition_map_; | 212 Handle<Map> transition_map_; |
| 229 MaybeHandle<Object> maybe_receiver_; | 213 MaybeHandle<Object> maybe_receiver_; |
| 230 MaybeHandle<JSReceiver> maybe_holder_; | 214 MaybeHandle<JSReceiver> maybe_holder_; |
| 231 | 215 |
| 232 int number_; | 216 int number_; |
| 233 }; | 217 }; |
| 234 | 218 |
| 235 | 219 |
| 236 } } // namespace v8::internal | 220 } } // namespace v8::internal |
| 237 | 221 |
| 238 #endif // V8_LOOKUP_H_ | 222 #endif // V8_LOOKUP_H_ |
| OLD | NEW |