Index: src/lookup.h |
diff --git a/src/lookup.h b/src/lookup.h |
index 0c298d99bf7ed2a0de1015a1f383a1fb5292c34c..9a053198cbc8378c07c0806964ff0b320b43e06e 100644 |
--- a/src/lookup.h |
+++ b/src/lookup.h |
@@ -47,7 +47,6 @@ class LookupIterator final BASE_EMBEDDED { |
LookupIterator(Handle<Object> receiver, Handle<Name> name, |
Configuration configuration = DEFAULT) |
: configuration_(ComputeConfiguration(configuration, name)), |
- state_(NOT_FOUND), |
interceptor_state_(InterceptorState::kUninitialized), |
property_details_(PropertyDetails::Empty()), |
isolate_(name->GetIsolate()), |
@@ -55,21 +54,18 @@ class LookupIterator final BASE_EMBEDDED { |
// kMaxUInt32 isn't a valid index. |
index_(kMaxUInt32), |
receiver_(receiver), |
- holder_(GetRoot(isolate_, receiver)), |
- initial_holder_(holder_), |
- number_(DescriptorArray::kNotFound) { |
+ initial_holder_(GetRoot(isolate_, receiver)) { |
#ifdef DEBUG |
uint32_t index; // Assert that the name is not an array index. |
DCHECK(!name->AsArrayIndex(&index)); |
#endif // DEBUG |
- Next(); |
+ Start<false>(); |
} |
LookupIterator(Handle<Object> receiver, Handle<Name> name, |
Handle<JSReceiver> holder, |
Configuration configuration = DEFAULT) |
: configuration_(ComputeConfiguration(configuration, name)), |
- state_(NOT_FOUND), |
interceptor_state_(InterceptorState::kUninitialized), |
property_details_(PropertyDetails::Empty()), |
isolate_(name->GetIsolate()), |
@@ -77,51 +73,43 @@ class LookupIterator final BASE_EMBEDDED { |
// kMaxUInt32 isn't a valid index. |
index_(kMaxUInt32), |
receiver_(receiver), |
- holder_(holder), |
- initial_holder_(holder_), |
- number_(DescriptorArray::kNotFound) { |
+ initial_holder_(holder) { |
#ifdef DEBUG |
uint32_t index; // Assert that the name is not an array index. |
DCHECK(!name->AsArrayIndex(&index)); |
#endif // DEBUG |
- Next(); |
+ Start<false>(); |
} |
LookupIterator(Isolate* isolate, Handle<Object> receiver, uint32_t index, |
Configuration configuration = DEFAULT) |
: configuration_(configuration), |
- state_(NOT_FOUND), |
interceptor_state_(InterceptorState::kUninitialized), |
property_details_(PropertyDetails::Empty()), |
isolate_(isolate), |
name_(), |
index_(index), |
receiver_(receiver), |
- holder_(GetRoot(isolate, receiver, index)), |
- initial_holder_(holder_), |
- number_(DescriptorArray::kNotFound) { |
+ initial_holder_(GetRoot(isolate, receiver, index)) { |
// kMaxUInt32 isn't a valid index. |
DCHECK_NE(kMaxUInt32, index_); |
- Next(); |
+ Start<true>(); |
} |
LookupIterator(Isolate* isolate, Handle<Object> receiver, uint32_t index, |
Handle<JSReceiver> holder, |
Configuration configuration = DEFAULT) |
: configuration_(configuration), |
- state_(NOT_FOUND), |
interceptor_state_(InterceptorState::kUninitialized), |
property_details_(PropertyDetails::Empty()), |
isolate_(isolate), |
name_(), |
index_(index), |
receiver_(receiver), |
- holder_(holder), |
- initial_holder_(holder_), |
- number_(DescriptorArray::kNotFound) { |
+ initial_holder_(holder) { |
// kMaxUInt32 isn't a valid index. |
DCHECK_NE(kMaxUInt32, index_); |
- Next(); |
+ Start<true>(); |
} |
static LookupIterator PropertyOrElement( |
@@ -154,7 +142,10 @@ class LookupIterator final BASE_EMBEDDED { |
Isolate* isolate, Handle<Object> receiver, Handle<Object> key, |
bool* success, Configuration configuration = DEFAULT); |
- void Restart() { RestartInternal(InterceptorState::kUninitialized); } |
+ void Restart() { |
+ InterceptorState state = InterceptorState::kUninitialized; |
+ IsElement() ? RestartInternal<true>(state) : RestartInternal<false>(state); |
+ } |
Isolate* isolate() const { return isolate_; } |
State state() const { return state_; } |
@@ -184,7 +175,17 @@ class LookupIterator final BASE_EMBEDDED { |
Heap* heap() const { return isolate_->heap(); } |
Factory* factory() const { return isolate_->factory(); } |
Handle<Object> GetReceiver() const { return receiver_; } |
- Handle<JSObject> GetStoreTarget() const; |
+ |
+ Handle<JSObject> GetStoreTarget() const { |
+ if (receiver_->IsJSGlobalProxy()) { |
+ Map* map = JSGlobalProxy::cast(*receiver_)->map(); |
+ if (map->has_hidden_prototype()) { |
+ return handle(JSGlobalObject::cast(map->prototype()), isolate_); |
+ } |
+ } |
+ return Handle<JSObject>::cast(receiver_); |
+ } |
+ |
bool is_dictionary_holder() const { return !holder_->HasFastProperties(); } |
Handle<Map> transition_map() const { |
DCHECK_EQ(TRANSITION, state_); |
@@ -256,9 +257,17 @@ class LookupIterator final BASE_EMBEDDED { |
} |
Handle<Object> GetDataValue() const; |
void WriteDataValue(Handle<Object> value); |
- void UpdateProtector(); |
+ inline void UpdateProtector() { |
+ if (FLAG_harmony_species && !IsElement() && |
+ (*name_ == heap()->constructor_string() || |
+ *name_ == heap()->species_symbol())) { |
+ InternalUpdateProtector(); |
+ } |
+ } |
private: |
+ void InternalUpdateProtector(); |
+ |
enum class InterceptorState { |
kUninitialized, |
kSkipNonMasking, |
@@ -268,16 +277,32 @@ class LookupIterator final BASE_EMBEDDED { |
Handle<Map> GetReceiverMap() const; |
MUST_USE_RESULT inline JSReceiver* NextHolder(Map* map); |
- inline State LookupInHolder(Map* map, JSReceiver* holder); |
+ |
+ template <bool is_element> |
+ void Start(); |
+ template <bool is_element> |
+ void NextInternal(Map* map, JSReceiver* holder); |
+ template <bool is_element> |
+ inline State LookupInHolder(Map* map, JSReceiver* holder) { |
+ return map->instance_type() <= LAST_SPECIAL_RECEIVER_TYPE |
+ ? LookupInSpecialHolder<is_element>(map, holder) |
+ : LookupInRegularHolder<is_element>(map, holder); |
+ } |
+ template <bool is_element> |
+ State LookupInRegularHolder(Map* map, JSReceiver* holder); |
+ template <bool is_element> |
+ State LookupInSpecialHolder(Map* map, JSReceiver* holder); |
+ template <bool is_element> |
void RestartLookupForNonMaskingInterceptors() { |
- RestartInternal(InterceptorState::kProcessNonMasking); |
+ RestartInternal<is_element>(InterceptorState::kProcessNonMasking); |
} |
+ template <bool is_element> |
void RestartInternal(InterceptorState interceptor_state); |
- State LookupNonMaskingInterceptorInHolder(Map* map, JSReceiver* holder); |
Handle<Object> FetchValue() const; |
+ template <bool is_element> |
void ReloadPropertyInformation(); |
+ |
inline bool SkipInterceptor(JSObject* holder); |
- bool HasInterceptor(Map* map) const; |
inline InterceptorInfo* GetInterceptor(JSObject* holder) const { |
if (IsElement()) return holder->GetIndexedInterceptor(); |
return holder->GetNamedInterceptor(); |