• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #ifndef V8_LOOKUP_INL_H_
6 #define V8_LOOKUP_INL_H_
7 
8 #include "src/lookup.h"
9 
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"
16 
17 namespace v8 {
18 namespace internal {
19 
LookupIterator(Handle<Object> receiver,Handle<Name> name,Handle<JSReceiver> holder,Configuration configuration)20 LookupIterator::LookupIterator(Handle<Object> receiver, Handle<Name> name,
21                                Handle<JSReceiver> holder,
22                                Configuration configuration)
23     : LookupIterator(holder->GetIsolate(), receiver, name, holder,
24                      configuration) {}
25 
LookupIterator(Isolate * isolate,Handle<Object> receiver,Handle<Name> name,Handle<JSReceiver> holder,Configuration configuration)26 LookupIterator::LookupIterator(Isolate* isolate, Handle<Object> receiver,
27                                Handle<Name> name, Handle<JSReceiver> holder,
28                                Configuration configuration)
29     : configuration_(ComputeConfiguration(configuration, name)),
30       interceptor_state_(InterceptorState::kUninitialized),
31       property_details_(PropertyDetails::Empty()),
32       isolate_(isolate),
33       name_(isolate_->factory()->InternalizeName(name)),
34       receiver_(receiver),
35       initial_holder_(holder),
36       // kMaxUInt32 isn't a valid index.
37       index_(kMaxUInt32),
38       number_(static_cast<uint32_t>(DescriptorArray::kNotFound)) {
39 #ifdef DEBUG
40   uint32_t index;  // Assert that the name is not an array index.
41   DCHECK(!name->AsArrayIndex(&index));
42 #endif  // DEBUG
43   Start<false>();
44 }
45 
PropertyOrElement(Isolate * isolate,Handle<Object> receiver,Handle<Name> name,Handle<JSReceiver> holder,Configuration configuration)46 LookupIterator LookupIterator::PropertyOrElement(
47     Isolate* isolate, Handle<Object> receiver, Handle<Name> name,
48     Handle<JSReceiver> holder, Configuration configuration) {
49   uint32_t index;
50   if (name->AsArrayIndex(&index)) {
51     LookupIterator it =
52         LookupIterator(isolate, receiver, index, holder, configuration);
53     it.name_ = name;
54     return it;
55   }
56   return LookupIterator(receiver, name, holder, configuration);
57 }
58 
PropertyOrElement(Isolate * isolate,Handle<Object> receiver,Handle<Name> name,Configuration configuration)59 LookupIterator LookupIterator::PropertyOrElement(
60     Isolate* isolate, Handle<Object> receiver, Handle<Name> name,
61     Configuration configuration) {
62   uint32_t index;
63   if (name->AsArrayIndex(&index)) {
64     LookupIterator it = LookupIterator(isolate, receiver, index, configuration);
65     it.name_ = name;
66     return it;
67   }
68   return LookupIterator(isolate, receiver, name, configuration);
69 }
70 
GetName()71 Handle<Name> LookupIterator::GetName() {
72   if (name_.is_null()) {
73     DCHECK(IsElement());
74     name_ = factory()->Uint32ToString(index_);
75   }
76   return name_;
77 }
78 
is_dictionary_holder()79 bool LookupIterator::is_dictionary_holder() const {
80   return !holder_->HasFastProperties();
81 }
82 
ExtendingNonExtensible(Handle<JSReceiver> receiver)83 bool LookupIterator::ExtendingNonExtensible(Handle<JSReceiver> receiver) {
84   DCHECK(receiver.is_identical_to(GetStoreTarget<JSReceiver>()));
85   return !receiver->map()->is_extensible() &&
86          (IsElement() || !name_->IsPrivate());
87 }
88 
IsCacheableTransition()89 bool LookupIterator::IsCacheableTransition() {
90   DCHECK_EQ(TRANSITION, state_);
91   return transition_->IsPropertyCell() ||
92          (transition_map()->is_dictionary_map() &&
93           !GetStoreTarget<JSReceiver>()->HasFastProperties()) ||
94          transition_map()->GetBackPointer()->IsMap();
95 }
96 
UpdateProtector()97 void LookupIterator::UpdateProtector() {
98   if (IsElement()) return;
99   // This list must be kept in sync with
100   // CodeStubAssembler::CheckForAssociatedProtector!
101   ReadOnlyRoots roots(heap());
102   if (*name_ == roots.is_concat_spreadable_symbol() ||
103       *name_ == roots.constructor_string() || *name_ == roots.next_string() ||
104       *name_ == roots.species_symbol() || *name_ == roots.iterator_symbol() ||
105       *name_ == roots.resolve_string() || *name_ == roots.then_string()) {
106     InternalUpdateProtector();
107   }
108 }
109 
ComputeConfiguration(Configuration configuration,Handle<Name> name)110 LookupIterator::Configuration LookupIterator::ComputeConfiguration(
111     Configuration configuration, Handle<Name> name) {
112   return name->IsPrivate() ? OWN_SKIP_INTERCEPTOR : configuration;
113 }
114 
GetRoot(Isolate * isolate,Handle<Object> receiver,uint32_t index)115 Handle<JSReceiver> LookupIterator::GetRoot(Isolate* isolate,
116                                            Handle<Object> receiver,
117                                            uint32_t index) {
118   if (receiver->IsJSReceiver()) return Handle<JSReceiver>::cast(receiver);
119   return GetRootForNonJSReceiver(isolate, receiver, index);
120 }
121 
122 template <class T>
GetStoreTarget()123 Handle<T> LookupIterator::GetStoreTarget() const {
124   DCHECK(receiver_->IsJSReceiver());
125   if (receiver_->IsJSGlobalProxy()) {
126     Map* map = JSGlobalProxy::cast(*receiver_)->map();
127     if (map->has_hidden_prototype()) {
128       return handle(JSGlobalObject::cast(map->prototype()), isolate_);
129     }
130   }
131   return Handle<T>::cast(receiver_);
132 }
GetInterceptor()133 inline Handle<InterceptorInfo> LookupIterator::GetInterceptor() const {
134   DCHECK_EQ(INTERCEPTOR, state_);
135   InterceptorInfo* result =
136       IsElement() ? GetInterceptor<true>(JSObject::cast(*holder_))
137                   : GetInterceptor<false>(JSObject::cast(*holder_));
138   return handle(result, isolate_);
139 }
140 
141 }  // namespace internal
142 }  // namespace v8
143 
144 #endif  // V8_LOOKUP_INL_H_
145