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" |
11 | 11 |
12 namespace v8 { | 12 namespace v8 { |
13 namespace internal { | 13 namespace internal { |
14 | 14 |
15 class LookupIterator V8_FINAL BASE_EMBEDDED { | 15 class LookupIterator V8_FINAL BASE_EMBEDDED { |
16 public: | 16 public: |
17 enum Configuration { | 17 enum Configuration { |
18 // Configuration bits. | 18 // Configuration bits. |
19 CHECK_HIDDEN_PROPERTY = 1 << 0, | 19 kAccessCheck = 1 << 0, |
20 CHECK_DERIVED_PROPERTY = 1 << 1, | 20 kHidden = 1 << 1, |
21 CHECK_INTERCEPTOR = 1 << 2, | 21 kInterceptor = 1 << 2, |
22 CHECK_ACCESS_CHECK = 1 << 3, | 22 kPrototypeChain = 1 << 3, |
23 | 23 |
24 // Convience combinations of bits. | 24 // Convience combinations of bits. |
25 CHECK_PROPERTY = 0, | 25 OWN_PROPERTY = 0, |
26 CHECK_OWN = CHECK_ACCESS_CHECK | CHECK_INTERCEPTOR, | 26 OWN_SKIP_INTERCEPTOR = kAccessCheck, |
27 CHECK_HIDDEN_SKIP_INTERCEPTOR = CHECK_HIDDEN_PROPERTY | CHECK_ACCESS_CHECK, | 27 OWN = kAccessCheck | kInterceptor, |
28 CHECK_DERIVED_SKIP_INTERCEPTOR = | 28 HIDDEN_PROPERTY = kHidden, |
29 CHECK_HIDDEN_SKIP_INTERCEPTOR | CHECK_DERIVED_PROPERTY, | 29 HIDDEN_SKIP_INTERCEPTOR = kAccessCheck | kHidden, |
30 CHECK_DERIVED = CHECK_DERIVED_SKIP_INTERCEPTOR | CHECK_INTERCEPTOR, | 30 HIDDEN = kAccessCheck | kHidden | kInterceptor, |
31 CHECK_HIDDEN = CHECK_HIDDEN_SKIP_INTERCEPTOR | CHECK_INTERCEPTOR | 31 PROTOTYPE_CHAIN_PROPERTY = kHidden | kPrototypeChain, |
| 32 PROTOTYPE_CHAIN_SKIP_INTERCEPTOR = kAccessCheck | kHidden | kPrototypeChain, |
| 33 PROTOTYPE_CHAIN = kAccessCheck | kHidden | kPrototypeChain | kInterceptor |
32 }; | 34 }; |
33 | 35 |
34 enum State { | 36 enum State { |
35 ACCESS_CHECK, | 37 ACCESS_CHECK, |
36 INTERCEPTOR, | 38 INTERCEPTOR, |
37 JSPROXY, | 39 JSPROXY, |
38 NOT_FOUND, | 40 NOT_FOUND, |
39 PROPERTY, | 41 PROPERTY, |
40 TRANSITION, | 42 TRANSITION, |
41 // Set state_ to BEFORE_PROPERTY to ensure that the next lookup will be a | 43 // Set state_ to BEFORE_PROPERTY to ensure that the next lookup will be a |
42 // PROPERTY lookup. | 44 // PROPERTY lookup. |
43 BEFORE_PROPERTY = INTERCEPTOR | 45 BEFORE_PROPERTY = INTERCEPTOR |
44 }; | 46 }; |
45 | 47 |
46 enum PropertyKind { | 48 enum PropertyKind { |
47 DATA, | 49 DATA, |
48 ACCESSOR | 50 ACCESSOR |
49 }; | 51 }; |
50 | 52 |
51 enum PropertyEncoding { | 53 enum PropertyEncoding { |
52 DICTIONARY, | 54 DICTIONARY, |
53 DESCRIPTOR | 55 DESCRIPTOR |
54 }; | 56 }; |
55 | 57 |
56 LookupIterator(Handle<Object> receiver, Handle<Name> name, | 58 LookupIterator(Handle<Object> receiver, Handle<Name> name, |
57 Configuration configuration = CHECK_DERIVED) | 59 Configuration configuration = PROTOTYPE_CHAIN) |
58 : configuration_(ComputeConfiguration(configuration, name)), | 60 : configuration_(ComputeConfiguration(configuration, name)), |
59 state_(NOT_FOUND), | 61 state_(NOT_FOUND), |
60 property_kind_(DATA), | 62 property_kind_(DATA), |
61 property_encoding_(DESCRIPTOR), | 63 property_encoding_(DESCRIPTOR), |
62 property_details_(NONE, NORMAL, Representation::None()), | 64 property_details_(NONE, NORMAL, Representation::None()), |
63 isolate_(name->GetIsolate()), | 65 isolate_(name->GetIsolate()), |
64 name_(name), | 66 name_(name), |
65 maybe_receiver_(receiver), | 67 maybe_receiver_(receiver), |
66 number_(DescriptorArray::kNotFound) { | 68 number_(DescriptorArray::kNotFound) { |
67 Handle<JSReceiver> root = GetRoot(); | 69 Handle<JSReceiver> root = GetRoot(); |
68 holder_map_ = handle(root->map(), isolate_); | 70 holder_map_ = handle(root->map(), isolate_); |
69 maybe_holder_ = root; | 71 maybe_holder_ = root; |
70 Next(); | 72 Next(); |
71 } | 73 } |
72 | 74 |
73 LookupIterator(Handle<Object> receiver, Handle<Name> name, | 75 LookupIterator(Handle<Object> receiver, Handle<Name> name, |
74 Handle<JSReceiver> holder, | 76 Handle<JSReceiver> holder, |
75 Configuration configuration = CHECK_DERIVED) | 77 Configuration configuration = PROTOTYPE_CHAIN) |
76 : configuration_(ComputeConfiguration(configuration, name)), | 78 : configuration_(ComputeConfiguration(configuration, name)), |
77 state_(NOT_FOUND), | 79 state_(NOT_FOUND), |
78 property_kind_(DATA), | 80 property_kind_(DATA), |
79 property_encoding_(DESCRIPTOR), | 81 property_encoding_(DESCRIPTOR), |
80 property_details_(NONE, NORMAL, Representation::None()), | 82 property_details_(NONE, NORMAL, Representation::None()), |
81 isolate_(name->GetIsolate()), | 83 isolate_(name->GetIsolate()), |
82 name_(name), | 84 name_(name), |
83 holder_map_(holder->map(), isolate_), | 85 holder_map_(holder->map(), isolate_), |
84 maybe_receiver_(receiver), | 86 maybe_receiver_(receiver), |
85 maybe_holder_(holder), | 87 maybe_holder_(holder), |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 | 186 |
185 bool IsBootstrapping() const; | 187 bool IsBootstrapping() const; |
186 | 188 |
187 // Methods that fetch data from the holder ensure they always have a holder. | 189 // Methods that fetch data from the holder ensure they always have a holder. |
188 // This means the receiver needs to be present as opposed to just the receiver | 190 // This means the receiver needs to be present as opposed to just the receiver |
189 // map. Other objects in the prototype chain are transitively guaranteed to be | 191 // map. Other objects in the prototype chain are transitively guaranteed to be |
190 // present via the receiver map. | 192 // present via the receiver map. |
191 bool is_guaranteed_to_have_holder() const { | 193 bool is_guaranteed_to_have_holder() const { |
192 return !maybe_receiver_.is_null(); | 194 return !maybe_receiver_.is_null(); |
193 } | 195 } |
| 196 bool check_access_check() const { |
| 197 return (configuration_ & kAccessCheck) != 0; |
| 198 } |
| 199 bool check_hidden() const { return (configuration_ & kHidden) != 0; } |
194 bool check_interceptor() const { | 200 bool check_interceptor() const { |
195 return !IsBootstrapping() && (configuration_ & CHECK_INTERCEPTOR) != 0; | 201 return !IsBootstrapping() && (configuration_ & kInterceptor) != 0; |
196 } | 202 } |
197 bool check_derived() const { | 203 bool check_prototype_chain() const { |
198 return (configuration_ & CHECK_DERIVED_PROPERTY) != 0; | 204 return (configuration_ & kPrototypeChain) != 0; |
199 } | |
200 bool check_hidden() const { | |
201 return (configuration_ & CHECK_HIDDEN_PROPERTY) != 0; | |
202 } | |
203 bool check_access_check() const { | |
204 return (configuration_ & CHECK_ACCESS_CHECK) != 0; | |
205 } | 205 } |
206 int descriptor_number() const { | 206 int descriptor_number() const { |
207 DCHECK(has_property_); | 207 DCHECK(has_property_); |
208 DCHECK_EQ(DESCRIPTOR, property_encoding_); | 208 DCHECK_EQ(DESCRIPTOR, property_encoding_); |
209 return number_; | 209 return number_; |
210 } | 210 } |
211 int dictionary_entry() const { | 211 int dictionary_entry() const { |
212 DCHECK(has_property_); | 212 DCHECK(has_property_); |
213 DCHECK_EQ(DICTIONARY, property_encoding_); | 213 DCHECK_EQ(DICTIONARY, property_encoding_); |
214 return number_; | 214 return number_; |
215 } | 215 } |
216 | 216 |
217 static Configuration ComputeConfiguration( | 217 static Configuration ComputeConfiguration( |
218 Configuration configuration, Handle<Name> name) { | 218 Configuration configuration, Handle<Name> name) { |
219 if (name->IsOwn()) { | 219 if (name->IsOwn()) { |
220 return static_cast<Configuration>(configuration & CHECK_HIDDEN); | 220 return static_cast<Configuration>(configuration & HIDDEN); |
221 } else { | 221 } else { |
222 return configuration; | 222 return configuration; |
223 } | 223 } |
224 } | 224 } |
225 | 225 |
226 // If configuration_ becomes mutable, update | 226 // If configuration_ becomes mutable, update |
227 // HolderIsReceiverOrHiddenPrototype. | 227 // HolderIsReceiverOrHiddenPrototype. |
228 Configuration configuration_; | 228 Configuration configuration_; |
229 State state_; | 229 State state_; |
230 bool has_property_; | 230 bool has_property_; |
231 PropertyKind property_kind_; | 231 PropertyKind property_kind_; |
232 PropertyEncoding property_encoding_; | 232 PropertyEncoding property_encoding_; |
233 PropertyDetails property_details_; | 233 PropertyDetails property_details_; |
234 Isolate* isolate_; | 234 Isolate* isolate_; |
235 Handle<Name> name_; | 235 Handle<Name> name_; |
236 Handle<Map> holder_map_; | 236 Handle<Map> holder_map_; |
237 Handle<Map> transition_map_; | 237 Handle<Map> transition_map_; |
238 MaybeHandle<Object> maybe_receiver_; | 238 MaybeHandle<Object> maybe_receiver_; |
239 MaybeHandle<JSReceiver> maybe_holder_; | 239 MaybeHandle<JSReceiver> maybe_holder_; |
240 | 240 |
241 int number_; | 241 int number_; |
242 }; | 242 }; |
243 | 243 |
244 | 244 |
245 } } // namespace v8::internal | 245 } } // namespace v8::internal |
246 | 246 |
247 #endif // V8_LOOKUP_H_ | 247 #endif // V8_LOOKUP_H_ |
OLD | NEW |