5 #ifndef V8_LOOKUP_INL_H_ 6 #define V8_LOOKUP_INL_H_ 8 #include "src/lookup.h" 10 #include "src/handles-inl.h" 11 #include "src/heap/factory-inl.h" 12 #include "src/objects-inl.h" 13 #include "src/objects/api-callbacks.h" 14 #include "src/objects/name-inl.h" 15 #include "src/objects/map-inl.h" 20 LookupIterator::LookupIterator(Isolate* isolate, Handle<Object> receiver,
21 Handle<Name> name, Configuration configuration)
22 : LookupIterator(isolate, receiver, name, GetRoot(isolate, receiver),
25 LookupIterator::LookupIterator(Handle<Object> receiver, Handle<Name> name,
26 Handle<JSReceiver> holder,
27 Configuration configuration)
28 : LookupIterator(holder->GetIsolate(), receiver, name, holder,
31 LookupIterator::LookupIterator(Isolate* isolate, Handle<Object> receiver,
32 Handle<Name> name, Handle<JSReceiver> holder,
33 Configuration configuration)
34 : configuration_(ComputeConfiguration(configuration, name)),
35 interceptor_state_(InterceptorState::kUninitialized),
36 property_details_(PropertyDetails::Empty()),
38 name_(isolate_->factory()->InternalizeName(name)),
40 initial_holder_(holder),
43 number_(static_cast<
uint32_t>(DescriptorArray::kNotFound)) {
46 DCHECK(!name->AsArrayIndex(&index));
51 LookupIterator::LookupIterator(Isolate* isolate, Handle<Object> receiver,
52 uint32_t index, Configuration configuration)
53 : LookupIterator(isolate, receiver, index,
54 GetRoot(isolate, receiver, index), configuration) {}
56 LookupIterator LookupIterator::PropertyOrElement(
57 Isolate* isolate, Handle<Object> receiver, Handle<Name> name,
58 Handle<JSReceiver> holder, Configuration configuration) {
60 if (name->AsArrayIndex(&index)) {
62 LookupIterator(isolate, receiver, index, holder, configuration);
66 return LookupIterator(receiver, name, holder, configuration);
69 LookupIterator LookupIterator::PropertyOrElement(
70 Isolate* isolate, Handle<Object> receiver, Handle<Name> name,
71 Configuration configuration) {
73 if (name->AsArrayIndex(&index)) {
74 LookupIterator it = LookupIterator(isolate, receiver, index, configuration);
78 return LookupIterator(isolate, receiver, name, configuration);
81 Handle<Name> LookupIterator::GetName() {
82 if (name_.is_null()) {
84 name_ = factory()->Uint32ToString(index_);
89 bool LookupIterator::is_dictionary_holder()
const {
90 return !holder_->HasFastProperties();
93 Handle<Map> LookupIterator::transition_map()
const {
94 DCHECK_EQ(TRANSITION, state_);
95 return Handle<Map>::cast(transition_);
98 Handle<PropertyCell> LookupIterator::transition_cell()
const {
99 DCHECK_EQ(TRANSITION, state_);
100 return Handle<PropertyCell>::cast(transition_);
104 Handle<T> LookupIterator::GetHolder()
const {
106 return Handle<T>::cast(holder_);
109 bool LookupIterator::ExtendingNonExtensible(Handle<JSReceiver> receiver) {
110 DCHECK(receiver.is_identical_to(GetStoreTarget<JSReceiver>()));
111 return !receiver->map()->is_extensible() &&
112 (IsElement() || !name_->IsPrivate());
115 bool LookupIterator::IsCacheableTransition() {
116 DCHECK_EQ(TRANSITION, state_);
117 return transition_->IsPropertyCell() ||
118 (transition_map()->is_dictionary_map() &&
119 !GetStoreTarget<JSReceiver>()->HasFastProperties()) ||
120 transition_map()->GetBackPointer()->IsMap();
123 void LookupIterator::UpdateProtector() {
124 if (IsElement())
return;
127 ReadOnlyRoots roots(heap());
128 if (*name_ == roots.is_concat_spreadable_symbol() ||
129 *name_ == roots.constructor_string() || *name_ == roots.next_string() ||
130 *name_ == roots.species_symbol() || *name_ == roots.iterator_symbol() ||
131 *name_ == roots.resolve_string() || *name_ == roots.then_string()) {
132 InternalUpdateProtector();
136 int LookupIterator::descriptor_number()
const {
137 DCHECK(!IsElement());
138 DCHECK(has_property_);
139 DCHECK(holder_->HasFastProperties());
143 int LookupIterator::dictionary_entry()
const {
144 DCHECK(!IsElement());
145 DCHECK(has_property_);
146 DCHECK(!holder_->HasFastProperties());
150 LookupIterator::Configuration LookupIterator::ComputeConfiguration(
151 Configuration configuration, Handle<Name> name) {
152 return name->IsPrivate() ? OWN_SKIP_INTERCEPTOR : configuration;
155 Handle<JSReceiver> LookupIterator::GetRoot(Isolate* isolate,
156 Handle<Object> receiver,
158 if (receiver->IsJSReceiver())
return Handle<JSReceiver>::cast(receiver);
159 return GetRootForNonJSReceiver(isolate, receiver, index);
163 Handle<T> LookupIterator::GetStoreTarget()
const {
164 DCHECK(receiver_->IsJSReceiver());
165 if (receiver_->IsJSGlobalProxy()) {
166 Map map = JSGlobalProxy::cast(*receiver_)->map();
167 if (map->has_hidden_prototype()) {
168 return handle(JSGlobalObject::cast(map->prototype()), isolate_);
171 return Handle<T>::cast(receiver_);
173 inline Handle<InterceptorInfo> LookupIterator::GetInterceptor()
const {
174 DCHECK_EQ(INTERCEPTOR, state_);
175 InterceptorInfo* result =
176 IsElement() ? GetInterceptor<true>(JSObject::cast(*holder_))
177 : GetInterceptor<false>(JSObject::cast(*holder_));
178 return handle(result, isolate_);
184 #endif // V8_LOOKUP_INL_H_