| 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 final BASE_EMBEDDED { | 15 class LookupIterator final BASE_EMBEDDED { |
| 16 public: | 16 public: |
| 17 enum Configuration { | 17 enum Configuration { |
| 18 // Configuration bits. | 18 // Configuration bits. |
| 19 kHidden = 1 << 0, | 19 kHidden = 1 << 0, |
| 20 kInterceptor = 1 << 1, | 20 kInterceptor = 1 << 1, |
| 21 kPrototypeChain = 1 << 2, | 21 kPrototypeChain = 1 << 2, |
| 22 | 22 |
| 23 // Convience combinations of bits. | 23 // Convience combinations of bits. |
| 24 OWN_SKIP_INTERCEPTOR = 0, | 24 OWN_SKIP_INTERCEPTOR = 0, |
| 25 OWN = kInterceptor, | 25 OWN = kInterceptor, |
| 26 HIDDEN_SKIP_INTERCEPTOR = kHidden, | 26 HIDDEN_SKIP_INTERCEPTOR = kHidden, |
| 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 DEFAULT = PROTOTYPE_CHAIN |
| 30 }; | 31 }; |
| 31 | 32 |
| 32 enum State { | 33 enum State { |
| 33 ACCESS_CHECK, | 34 ACCESS_CHECK, |
| 34 INTEGER_INDEXED_EXOTIC, | 35 INTEGER_INDEXED_EXOTIC, |
| 35 INTERCEPTOR, | 36 INTERCEPTOR, |
| 36 JSPROXY, | 37 JSPROXY, |
| 37 NOT_FOUND, | 38 NOT_FOUND, |
| 38 ACCESSOR, | 39 ACCESSOR, |
| 39 DATA, | 40 DATA, |
| 40 TRANSITION, | 41 TRANSITION, |
| 41 // Set state_ to BEFORE_PROPERTY to ensure that the next lookup will be a | 42 // Set state_ to BEFORE_PROPERTY to ensure that the next lookup will be a |
| 42 // PROPERTY lookup. | 43 // PROPERTY lookup. |
| 43 BEFORE_PROPERTY = INTERCEPTOR | 44 BEFORE_PROPERTY = INTERCEPTOR |
| 44 }; | 45 }; |
| 45 | 46 |
| 46 LookupIterator(Handle<Object> receiver, Handle<Name> name, | 47 LookupIterator(Handle<Object> receiver, Handle<Name> name, |
| 47 Configuration configuration = PROTOTYPE_CHAIN) | 48 Configuration configuration = DEFAULT) |
| 48 : configuration_(ComputeConfiguration(configuration, name)), | 49 : configuration_(ComputeConfiguration(configuration, name)), |
| 49 state_(NOT_FOUND), | 50 state_(NOT_FOUND), |
| 50 exotic_index_state_(ExoticIndexState::kUninitialized), | 51 exotic_index_state_(ExoticIndexState::kUninitialized), |
| 51 interceptor_state_(InterceptorState::kUninitialized), | 52 interceptor_state_(InterceptorState::kUninitialized), |
| 52 property_details_(PropertyDetails::Empty()), | 53 property_details_(PropertyDetails::Empty()), |
| 53 isolate_(name->GetIsolate()), | 54 isolate_(name->GetIsolate()), |
| 54 name_(name), | 55 name_(name), |
| 55 // kMaxUInt32 isn't a valid index. | 56 // kMaxUInt32 isn't a valid index. |
| 56 index_(kMaxUInt32), | 57 index_(kMaxUInt32), |
| 57 receiver_(receiver), | 58 receiver_(receiver), |
| 58 holder_(GetRoot(receiver_, isolate_)), | 59 holder_(GetRoot(receiver_, isolate_)), |
| 59 holder_map_(holder_->map(), isolate_), | 60 holder_map_(holder_->map(), isolate_), |
| 60 initial_holder_(holder_), | 61 initial_holder_(holder_), |
| 61 number_(DescriptorArray::kNotFound) { | 62 number_(DescriptorArray::kNotFound) { |
| 62 #ifdef DEBUG | 63 #ifdef DEBUG |
| 63 uint32_t index; // Assert that the name is not an array index. | 64 uint32_t index; // Assert that the name is not an array index. |
| 64 DCHECK(!name->AsArrayIndex(&index)); | 65 DCHECK(!name->AsArrayIndex(&index)); |
| 65 #endif // DEBUG | 66 #endif // DEBUG |
| 66 Next(); | 67 Next(); |
| 67 } | 68 } |
| 68 | 69 |
| 69 LookupIterator(Handle<Object> receiver, Handle<Name> name, | 70 LookupIterator(Handle<Object> receiver, Handle<Name> name, |
| 70 Handle<JSReceiver> holder, | 71 Handle<JSReceiver> holder, |
| 71 Configuration configuration = PROTOTYPE_CHAIN) | 72 Configuration configuration = DEFAULT) |
| 72 : configuration_(ComputeConfiguration(configuration, name)), | 73 : configuration_(ComputeConfiguration(configuration, name)), |
| 73 state_(NOT_FOUND), | 74 state_(NOT_FOUND), |
| 74 exotic_index_state_(ExoticIndexState::kUninitialized), | 75 exotic_index_state_(ExoticIndexState::kUninitialized), |
| 75 interceptor_state_(InterceptorState::kUninitialized), | 76 interceptor_state_(InterceptorState::kUninitialized), |
| 76 property_details_(PropertyDetails::Empty()), | 77 property_details_(PropertyDetails::Empty()), |
| 77 isolate_(name->GetIsolate()), | 78 isolate_(name->GetIsolate()), |
| 78 name_(name), | 79 name_(name), |
| 79 // kMaxUInt32 isn't a valid index. | 80 // kMaxUInt32 isn't a valid index. |
| 80 index_(kMaxUInt32), | 81 index_(kMaxUInt32), |
| 81 receiver_(receiver), | 82 receiver_(receiver), |
| 82 holder_(holder), | 83 holder_(holder), |
| 83 holder_map_(holder_->map(), isolate_), | 84 holder_map_(holder_->map(), isolate_), |
| 84 initial_holder_(holder_), | 85 initial_holder_(holder_), |
| 85 number_(DescriptorArray::kNotFound) { | 86 number_(DescriptorArray::kNotFound) { |
| 86 #ifdef DEBUG | 87 #ifdef DEBUG |
| 87 uint32_t index; // Assert that the name is not an array index. | 88 uint32_t index; // Assert that the name is not an array index. |
| 88 DCHECK(!name->AsArrayIndex(&index)); | 89 DCHECK(!name->AsArrayIndex(&index)); |
| 89 #endif // DEBUG | 90 #endif // DEBUG |
| 90 Next(); | 91 Next(); |
| 91 } | 92 } |
| 92 | 93 |
| 93 LookupIterator(Isolate* isolate, Handle<Object> receiver, uint32_t index, | 94 LookupIterator(Isolate* isolate, Handle<Object> receiver, uint32_t index, |
| 94 Configuration configuration = PROTOTYPE_CHAIN) | 95 Configuration configuration = DEFAULT) |
| 95 : configuration_(configuration), | 96 : configuration_(configuration), |
| 96 state_(NOT_FOUND), | 97 state_(NOT_FOUND), |
| 97 exotic_index_state_(ExoticIndexState::kUninitialized), | 98 exotic_index_state_(ExoticIndexState::kUninitialized), |
| 98 interceptor_state_(InterceptorState::kUninitialized), | 99 interceptor_state_(InterceptorState::kUninitialized), |
| 99 property_details_(PropertyDetails::Empty()), | 100 property_details_(PropertyDetails::Empty()), |
| 100 isolate_(isolate), | 101 isolate_(isolate), |
| 101 name_(), | 102 name_(), |
| 102 index_(index), | 103 index_(index), |
| 103 receiver_(receiver), | 104 receiver_(receiver), |
| 104 holder_(GetRoot(receiver_, isolate_)), | 105 holder_(GetRoot(receiver_, isolate_)), |
| 105 holder_map_(holder_->map(), isolate_), | 106 holder_map_(holder_->map(), isolate_), |
| 106 initial_holder_(holder_), | 107 initial_holder_(holder_), |
| 107 number_(DescriptorArray::kNotFound) { | 108 number_(DescriptorArray::kNotFound) { |
| 108 // kMaxUInt32 isn't a valid index. | 109 // kMaxUInt32 isn't a valid index. |
| 109 DCHECK_NE(kMaxUInt32, index_); | 110 DCHECK_NE(kMaxUInt32, index_); |
| 110 Next(); | 111 Next(); |
| 111 } | 112 } |
| 112 | 113 |
| 113 LookupIterator(Isolate* isolate, Handle<Object> receiver, uint32_t index, | 114 LookupIterator(Isolate* isolate, Handle<Object> receiver, uint32_t index, |
| 114 Handle<JSReceiver> holder, | 115 Handle<JSReceiver> holder, |
| 115 Configuration configuration = PROTOTYPE_CHAIN) | 116 Configuration configuration = DEFAULT) |
| 116 : configuration_(configuration), | 117 : configuration_(configuration), |
| 117 state_(NOT_FOUND), | 118 state_(NOT_FOUND), |
| 118 exotic_index_state_(ExoticIndexState::kUninitialized), | 119 exotic_index_state_(ExoticIndexState::kUninitialized), |
| 119 interceptor_state_(InterceptorState::kUninitialized), | 120 interceptor_state_(InterceptorState::kUninitialized), |
| 120 property_details_(PropertyDetails::Empty()), | 121 property_details_(PropertyDetails::Empty()), |
| 121 isolate_(isolate), | 122 isolate_(isolate), |
| 122 name_(), | 123 name_(), |
| 123 index_(index), | 124 index_(index), |
| 124 receiver_(receiver), | 125 receiver_(receiver), |
| 125 holder_(holder), | 126 holder_(holder), |
| 126 holder_map_(holder_->map(), isolate_), | 127 holder_map_(holder_->map(), isolate_), |
| 127 initial_holder_(holder_), | 128 initial_holder_(holder_), |
| 128 number_(DescriptorArray::kNotFound) { | 129 number_(DescriptorArray::kNotFound) { |
| 129 // kMaxUInt32 isn't a valid index. | 130 // kMaxUInt32 isn't a valid index. |
| 130 DCHECK_NE(kMaxUInt32, index_); | 131 DCHECK_NE(kMaxUInt32, index_); |
| 131 Next(); | 132 Next(); |
| 132 } | 133 } |
| 133 | 134 |
| 135 static LookupIterator PropertyOrElement( |
| 136 Isolate* isolate, Handle<Object> receiver, Handle<Name> name, |
| 137 Configuration configuration = DEFAULT) { |
| 138 uint32_t index; |
| 139 LookupIterator it = |
| 140 name->AsArrayIndex(&index) |
| 141 ? LookupIterator(isolate, receiver, index, configuration) |
| 142 : LookupIterator(receiver, name, configuration); |
| 143 it.name_ = name; |
| 144 return it; |
| 145 } |
| 146 |
| 147 static LookupIterator PropertyOrElement( |
| 148 Isolate* isolate, Handle<Object> receiver, Handle<Name> name, |
| 149 Handle<JSReceiver> holder, Configuration configuration = DEFAULT) { |
| 150 uint32_t index; |
| 151 LookupIterator it = |
| 152 name->AsArrayIndex(&index) |
| 153 ? LookupIterator(isolate, receiver, index, holder, configuration) |
| 154 : LookupIterator(receiver, name, holder, configuration); |
| 155 it.name_ = name; |
| 156 return it; |
| 157 } |
| 134 Isolate* isolate() const { return isolate_; } | 158 Isolate* isolate() const { return isolate_; } |
| 135 State state() const { return state_; } | 159 State state() const { return state_; } |
| 136 | 160 |
| 137 Handle<Name> name() const { | 161 Handle<Name> name() const { |
| 138 DCHECK(!IsElement()); | 162 DCHECK(!IsElement()); |
| 139 return name_; | 163 return name_; |
| 140 } | 164 } |
| 141 Handle<Name> GetName() { | 165 Handle<Name> GetName() { |
| 142 if (name_.is_null()) { | 166 if (name_.is_null()) { |
| 143 DCHECK(IsElement()); | 167 DCHECK(IsElement()); |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 Handle<JSReceiver> holder_; | 304 Handle<JSReceiver> holder_; |
| 281 Handle<Map> holder_map_; | 305 Handle<Map> holder_map_; |
| 282 const Handle<JSReceiver> initial_holder_; | 306 const Handle<JSReceiver> initial_holder_; |
| 283 uint32_t number_; | 307 uint32_t number_; |
| 284 }; | 308 }; |
| 285 | 309 |
| 286 | 310 |
| 287 } } // namespace v8::internal | 311 } } // namespace v8::internal |
| 288 | 312 |
| 289 #endif // V8_LOOKUP_H_ | 313 #endif // V8_LOOKUP_H_ |
| OLD | NEW |