| // Copyright 2014 the V8 project authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef V8_LOOKUP_INL_H_ |
| #define V8_LOOKUP_INL_H_ |
| |
| #include "src/lookup.h" |
| |
| namespace v8 { |
| namespace internal { |
| |
| |
| JSReceiver* LookupIterator::NextHolder(Map* map) { |
| DisallowHeapAllocation no_gc; |
| if (map->prototype()->IsNull()) return NULL; |
| |
| JSReceiver* next = JSReceiver::cast(map->prototype()); |
| DCHECK(!next->map()->IsGlobalObjectMap() || |
| next->map()->is_hidden_prototype()); |
| |
| if (!check_prototype_chain() && |
| !(check_hidden() && next->map()->is_hidden_prototype()) && |
| // Always lookup behind the JSGlobalProxy into the JSGlobalObject, even |
| // when not checking other hidden prototypes. |
| !map->IsJSGlobalProxyMap()) { |
| return NULL; |
| } |
| |
| return next; |
| } |
| |
| |
| LookupIterator::State LookupIterator::LookupInHolder(Map* map, |
| JSReceiver* holder) { |
| STATIC_ASSERT(INTERCEPTOR == BEFORE_PROPERTY); |
| DisallowHeapAllocation no_gc; |
| switch (state_) { |
| case NOT_FOUND: |
| if (map->IsJSProxyMap()) return JSPROXY; |
| if (map->is_access_check_needed()) return ACCESS_CHECK; |
| // Fall through. |
| case ACCESS_CHECK: |
| if (check_interceptor() && map->has_named_interceptor()) { |
| return INTERCEPTOR; |
| } |
| // Fall through. |
| case INTERCEPTOR: |
| if (map->is_dictionary_map()) { |
| NameDictionary* dict = JSObject::cast(holder)->property_dictionary(); |
| number_ = dict->FindEntry(name_); |
| if (number_ == NameDictionary::kNotFound) return NOT_FOUND; |
| property_details_ = dict->DetailsAt(number_); |
| if (holder->IsGlobalObject()) { |
| if (property_details_.IsDeleted()) return NOT_FOUND; |
| PropertyCell* cell = PropertyCell::cast(dict->ValueAt(number_)); |
| if (cell->value()->IsTheHole()) return NOT_FOUND; |
| } |
| } else { |
| DescriptorArray* descriptors = map->instance_descriptors(); |
| number_ = descriptors->SearchWithCache(*name_, map); |
| if (number_ == DescriptorArray::kNotFound) return NOT_FOUND; |
| property_details_ = descriptors->GetDetails(number_); |
| } |
| has_property_ = true; |
| switch (property_details_.type()) { |
| case v8::internal::CONSTANT: |
| case v8::internal::FIELD: |
| case v8::internal::NORMAL: |
| return DATA; |
| case v8::internal::CALLBACKS: |
| return ACCESSOR; |
| } |
| case ACCESSOR: |
| case DATA: |
| return NOT_FOUND; |
| case JSPROXY: |
| case TRANSITION: |
| UNREACHABLE(); |
| } |
| UNREACHABLE(); |
| return state_; |
| } |
| } |
| } // namespace v8::internal |
| |
| #endif // V8_LOOKUP_INL_H_ |