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.
5 #ifndef V8_LOOKUP_INL_H_
6 #define V8_LOOKUP_INL_H_
8 #include "src/lookup.h"
10 #include "src/elements.h"
16 JSReceiver* LookupIterator::NextHolder(Map* map) {
17 DisallowHeapAllocation no_gc;
18 if (!map->prototype()->IsJSReceiver()) return NULL;
20 JSReceiver* next = JSReceiver::cast(map->prototype());
21 DCHECK(!next->map()->IsGlobalObjectMap() ||
22 next->map()->is_hidden_prototype());
24 if (!check_prototype_chain() &&
25 !(check_hidden() && next->map()->is_hidden_prototype()) &&
26 // Always lookup behind the JSGlobalProxy into the JSGlobalObject, even
27 // when not checking other hidden prototypes.
28 !map->IsJSGlobalProxyMap()) {
36 LookupIterator::State LookupIterator::LookupInHolder(Map* const map,
37 JSReceiver* const holder) {
38 STATIC_ASSERT(INTERCEPTOR == BEFORE_PROPERTY);
39 DisallowHeapAllocation no_gc;
40 if (interceptor_state_ == InterceptorState::kProcessNonMasking) {
41 return LookupNonMaskingInterceptorInHolder(map, holder);
45 if (map->IsJSProxyMap()) return JSPROXY;
46 if (map->is_access_check_needed() &&
47 (IsElement() || !isolate_->IsInternallyUsedPropertyName(name_))) {
52 if (exotic_index_state_ != ExoticIndexState::kNotExotic &&
53 IsIntegerIndexedExotic(holder)) {
54 return INTEGER_INDEXED_EXOTIC;
56 if (check_interceptor() && HasInterceptor(map) &&
57 !SkipInterceptor(JSObject::cast(holder))) {
63 // TODO(verwaest): Optimize.
64 if (holder->IsStringObjectWithCharacterAt(index_)) {
65 PropertyAttributes attributes =
66 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
67 property_details_ = PropertyDetails(attributes, v8::internal::DATA, 0,
68 PropertyCellType::kNoCell);
70 JSObject* js_object = JSObject::cast(holder);
71 if (js_object->elements() == isolate()->heap()->empty_fixed_array()) {
75 ElementsAccessor* accessor = js_object->GetElementsAccessor();
76 FixedArrayBase* backing_store = js_object->elements();
78 accessor->GetEntryForIndex(js_object, backing_store, index_);
79 if (number_ == kMaxUInt32) return NOT_FOUND;
80 property_details_ = accessor->GetDetails(backing_store, number_);
82 } else if (!map->is_dictionary_map()) {
83 DescriptorArray* descriptors = map->instance_descriptors();
84 int number = descriptors->SearchWithCache(*name_, map);
85 if (number == DescriptorArray::kNotFound) return NOT_FOUND;
86 number_ = static_cast<uint32_t>(number);
87 property_details_ = descriptors->GetDetails(number_);
88 } else if (map->IsGlobalObjectMap()) {
89 GlobalDictionary* dict = JSObject::cast(holder)->global_dictionary();
90 int number = dict->FindEntry(name_);
91 if (number == GlobalDictionary::kNotFound) return NOT_FOUND;
92 number_ = static_cast<uint32_t>(number);
93 DCHECK(dict->ValueAt(number_)->IsPropertyCell());
94 PropertyCell* cell = PropertyCell::cast(dict->ValueAt(number_));
95 if (cell->value()->IsTheHole()) return NOT_FOUND;
96 property_details_ = cell->property_details();
98 NameDictionary* dict = JSObject::cast(holder)->property_dictionary();
99 int number = dict->FindEntry(name_);
100 if (number == NameDictionary::kNotFound) return NOT_FOUND;
101 number_ = static_cast<uint32_t>(number);
102 property_details_ = dict->DetailsAt(number_);
104 has_property_ = true;
105 switch (property_details_.kind()) {
106 case v8::internal::kData:
108 case v8::internal::kAccessor:
114 case INTEGER_INDEXED_EXOTIC:
124 LookupIterator::State LookupIterator::LookupNonMaskingInterceptorInHolder(
125 Map* const map, JSReceiver* const holder) {
128 if (check_interceptor() && HasInterceptor(map) &&
129 !SkipInterceptor(JSObject::cast(holder))) {
140 } // namespace v8::internal
142 #endif // V8_LOOKUP_INL_H_