| Index: src/lookup.cc
|
| diff --git a/src/lookup.cc b/src/lookup.cc
|
| index bad5a20df51222151cc7e135583e16671c6ee390..7b26a6d89ce04048b792d58cf562012678c53933 100644
|
| --- a/src/lookup.cc
|
| +++ b/src/lookup.cc
|
| @@ -45,6 +45,22 @@ LookupIterator LookupIterator::PropertyOrElement(Isolate* isolate,
|
| return LookupIterator(receiver, name, configuration);
|
| }
|
|
|
| +void LookupIterator::Start() {
|
| + DisallowHeapAllocation no_gc;
|
| +
|
| + has_property_ = false;
|
| + state_ = NOT_FOUND;
|
| + number_ = DescriptorArray::kNotFound;
|
| + holder_ = initial_holder_;
|
| +
|
| + JSReceiver* holder = *holder_;
|
| + Map* map = holder->map();
|
| +
|
| + state_ = LookupInHolder(map, holder);
|
| + if (IsFound()) return;
|
| +
|
| + NextInternal(map, holder);
|
| +}
|
|
|
| void LookupIterator::Next() {
|
| DCHECK_NE(JSPROXY, state_);
|
| @@ -55,11 +71,15 @@ void LookupIterator::Next() {
|
| JSReceiver* holder = *holder_;
|
| Map* map = holder->map();
|
|
|
| - // Perform lookup on current holder.
|
| - state_ = LookupInHolder(map, holder);
|
| - if (IsFound()) return;
|
| + if (map->instance_type() <= LAST_SPECIAL_RECEIVER_TYPE) {
|
| + state_ = LookupInSpecialHolder(map, holder);
|
| + if (IsFound()) return;
|
| + }
|
| +
|
| + NextInternal(map, holder);
|
| +}
|
|
|
| - // Continue lookup if lookup on current holder failed.
|
| +void LookupIterator::NextInternal(Map* map, JSReceiver* holder) {
|
| do {
|
| JSReceiver* maybe_holder = NextHolder(map);
|
| if (maybe_holder == nullptr) {
|
| @@ -67,24 +87,21 @@ void LookupIterator::Next() {
|
| RestartLookupForNonMaskingInterceptors();
|
| return;
|
| }
|
| - break;
|
| + if (holder != *holder_) holder_ = handle(holder, isolate_);
|
| + return;
|
| }
|
| holder = maybe_holder;
|
| map = holder->map();
|
| state_ = LookupInHolder(map, holder);
|
| } while (!IsFound());
|
|
|
| - if (holder != *holder_) holder_ = handle(holder, isolate_);
|
| + holder_ = handle(holder, isolate_);
|
| }
|
|
|
| -
|
| void LookupIterator::RestartInternal(InterceptorState interceptor_state) {
|
| - state_ = NOT_FOUND;
|
| interceptor_state_ = interceptor_state;
|
| property_details_ = PropertyDetails::Empty();
|
| - holder_ = initial_holder_;
|
| - number_ = DescriptorArray::kNotFound;
|
| - Next();
|
| + Start();
|
| }
|
|
|
|
|
| @@ -116,18 +133,6 @@ Handle<Map> LookupIterator::GetReceiverMap() const {
|
| return handle(Handle<HeapObject>::cast(receiver_)->map(), isolate_);
|
| }
|
|
|
| -
|
| -Handle<JSObject> LookupIterator::GetStoreTarget() const {
|
| - if (receiver_->IsJSGlobalProxy()) {
|
| - Object* prototype = JSGlobalProxy::cast(*receiver_)->map()->prototype();
|
| - if (!prototype->IsNull()) {
|
| - return handle(JSGlobalObject::cast(prototype), isolate_);
|
| - }
|
| - }
|
| - return Handle<JSObject>::cast(receiver_);
|
| -}
|
| -
|
| -
|
| bool LookupIterator::HasAccess() const {
|
| DCHECK_EQ(ACCESS_CHECK, state_);
|
| return isolate_->MayAccess(handle(isolate_->context()),
|
| @@ -605,10 +610,9 @@ bool LookupIterator::SkipInterceptor(JSObject* holder) {
|
| return interceptor_state_ == InterceptorState::kProcessNonMasking;
|
| }
|
|
|
| -
|
| JSReceiver* LookupIterator::NextHolder(Map* map) {
|
| DisallowHeapAllocation no_gc;
|
| - if (!map->prototype()->IsJSReceiver()) return NULL;
|
| + if (map->prototype() == heap()->null_value()) return NULL;
|
|
|
| DCHECK(!map->IsJSGlobalProxyMap() || map->has_hidden_prototype());
|
|
|
| @@ -635,13 +639,9 @@ LookupIterator::State LookupIterator::NotFound(JSReceiver* const holder) const {
|
| : NOT_FOUND;
|
| }
|
|
|
| -LookupIterator::State LookupIterator::LookupInHolder(Map* const map,
|
| - JSReceiver* const holder) {
|
| +LookupIterator::State LookupIterator::LookupInSpecialHolder(
|
| + Map* const map, JSReceiver* const holder) {
|
| STATIC_ASSERT(INTERCEPTOR == BEFORE_PROPERTY);
|
| - DisallowHeapAllocation no_gc;
|
| - if (interceptor_state_ == InterceptorState::kProcessNonMasking) {
|
| - return LookupNonMaskingInterceptorInHolder(map, holder);
|
| - }
|
| switch (state_) {
|
| case NOT_FOUND:
|
| if (map->IsJSProxyMap()) {
|
| @@ -658,22 +658,7 @@ LookupIterator::State LookupIterator::LookupInHolder(Map* const map,
|
| }
|
| // Fall through.
|
| case INTERCEPTOR:
|
| - if (IsElement()) {
|
| - JSObject* js_object = JSObject::cast(holder);
|
| - ElementsAccessor* accessor = js_object->GetElementsAccessor();
|
| - FixedArrayBase* backing_store = js_object->elements();
|
| - number_ = accessor->GetEntryForIndex(js_object, backing_store, index_);
|
| - if (number_ == kMaxUInt32) {
|
| - return holder->IsJSTypedArray() ? INTEGER_INDEXED_EXOTIC : NOT_FOUND;
|
| - }
|
| - property_details_ = accessor->GetDetails(js_object, number_);
|
| - } else if (!map->is_dictionary_map()) {
|
| - DescriptorArray* descriptors = map->instance_descriptors();
|
| - int number = descriptors->SearchWithCache(isolate_, *name_, map);
|
| - if (number == DescriptorArray::kNotFound) return NotFound(holder);
|
| - number_ = static_cast<uint32_t>(number);
|
| - property_details_ = descriptors->GetDetails(number_);
|
| - } else if (map->IsJSGlobalObjectMap()) {
|
| + if (!IsElement() && map->IsJSGlobalObjectMap()) {
|
| GlobalDictionary* dict = JSObject::cast(holder)->global_dictionary();
|
| int number = dict->FindEntry(name_);
|
| if (number == GlobalDictionary::kNotFound) return NOT_FOUND;
|
| @@ -682,20 +667,15 @@ LookupIterator::State LookupIterator::LookupInHolder(Map* const map,
|
| PropertyCell* cell = PropertyCell::cast(dict->ValueAt(number_));
|
| if (cell->value()->IsTheHole()) return NOT_FOUND;
|
| property_details_ = cell->property_details();
|
| - } else {
|
| - NameDictionary* dict = holder->property_dictionary();
|
| - int number = dict->FindEntry(name_);
|
| - if (number == NameDictionary::kNotFound) return NotFound(holder);
|
| - number_ = static_cast<uint32_t>(number);
|
| - property_details_ = dict->DetailsAt(number_);
|
| - }
|
| - has_property_ = true;
|
| - switch (property_details_.kind()) {
|
| - case v8::internal::kData:
|
| - return DATA;
|
| - case v8::internal::kAccessor:
|
| - return ACCESSOR;
|
| + has_property_ = true;
|
| + switch (property_details_.kind()) {
|
| + case v8::internal::kData:
|
| + return DATA;
|
| + case v8::internal::kAccessor:
|
| + return ACCESSOR;
|
| + }
|
| }
|
| + return LookupInRegularHolder(map, holder);
|
| case ACCESSOR:
|
| case DATA:
|
| return NOT_FOUND;
|
| @@ -705,22 +685,46 @@ LookupIterator::State LookupIterator::LookupInHolder(Map* const map,
|
| UNREACHABLE();
|
| }
|
| UNREACHABLE();
|
| - return state_;
|
| + return NOT_FOUND;
|
| }
|
|
|
| -
|
| -LookupIterator::State LookupIterator::LookupNonMaskingInterceptorInHolder(
|
| +LookupIterator::State LookupIterator::LookupInRegularHolder(
|
| Map* const map, JSReceiver* const holder) {
|
| - switch (state_) {
|
| - case NOT_FOUND:
|
| - if (check_interceptor() && HasInterceptor(map) &&
|
| - !SkipInterceptor(JSObject::cast(holder))) {
|
| - return INTERCEPTOR;
|
| - }
|
| - // Fall through.
|
| - default:
|
| - return NOT_FOUND;
|
| + DisallowHeapAllocation no_gc;
|
| + if (interceptor_state_ == InterceptorState::kProcessNonMasking) {
|
| + return NOT_FOUND;
|
| }
|
| +
|
| + if (IsElement()) {
|
| + JSObject* js_object = JSObject::cast(holder);
|
| + ElementsAccessor* accessor = js_object->GetElementsAccessor();
|
| + FixedArrayBase* backing_store = js_object->elements();
|
| + number_ = accessor->GetEntryForIndex(js_object, backing_store, index_);
|
| + if (number_ == kMaxUInt32) {
|
| + return holder->IsJSTypedArray() ? INTEGER_INDEXED_EXOTIC : NOT_FOUND;
|
| + }
|
| + property_details_ = accessor->GetDetails(js_object, number_);
|
| + } else if (!map->is_dictionary_map()) {
|
| + DescriptorArray* descriptors = map->instance_descriptors();
|
| + int number = descriptors->SearchWithCache(isolate_, *name_, map);
|
| + if (number == DescriptorArray::kNotFound) return NotFound(holder);
|
| + number_ = static_cast<uint32_t>(number);
|
| + property_details_ = descriptors->GetDetails(number_);
|
| + } else {
|
| + NameDictionary* dict = holder->property_dictionary();
|
| + int number = dict->FindEntry(name_);
|
| + if (number == NameDictionary::kNotFound) return NotFound(holder);
|
| + number_ = static_cast<uint32_t>(number);
|
| + property_details_ = dict->DetailsAt(number_);
|
| + }
|
| + has_property_ = true;
|
| + switch (property_details_.kind()) {
|
| + case v8::internal::kData:
|
| + return DATA;
|
| + case v8::internal::kAccessor:
|
| + return ACCESSOR;
|
| + }
|
| +
|
| UNREACHABLE();
|
| return state_;
|
| }
|
|
|