blob: d4777a0baa80282e742c6d086250851e909f2cdc [file] [log] [blame]
// 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_