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.
4
5#ifndef V8_LOOKUP_INL_H_
6#define V8_LOOKUP_INL_H_
7
8#include "src/lookup.h"
9
10namespace v8 {
11namespace internal {
12
13
14JSReceiver* LookupIterator::NextHolder(Map* map) {
15  DisallowHeapAllocation no_gc;
16  if (map->prototype()->IsNull()) return NULL;
17
18  JSReceiver* next = JSReceiver::cast(map->prototype());
19  DCHECK(!next->map()->IsGlobalObjectMap() ||
20         next->map()->is_hidden_prototype());
21
22  if (!check_prototype_chain() &&
23      !(check_hidden() && next->map()->is_hidden_prototype()) &&
24      // Always lookup behind the JSGlobalProxy into the JSGlobalObject, even
25      // when not checking other hidden prototypes.
26      !map->IsJSGlobalProxyMap()) {
27    return NULL;
28  }
29
30  return next;
31}
32
33
34LookupIterator::State LookupIterator::LookupInHolder(Map* map,
35                                                     JSReceiver* holder) {
36  STATIC_ASSERT(INTERCEPTOR == BEFORE_PROPERTY);
37  DisallowHeapAllocation no_gc;
38  switch (state_) {
39    case NOT_FOUND:
40      if (map->IsJSProxyMap()) return JSPROXY;
41      if (map->is_access_check_needed()) return ACCESS_CHECK;
42    // Fall through.
43    case ACCESS_CHECK:
44      if (check_interceptor() && map->has_named_interceptor()) {
45        return INTERCEPTOR;
46      }
47    // Fall through.
48    case INTERCEPTOR:
49      if (map->is_dictionary_map()) {
50        NameDictionary* dict = JSObject::cast(holder)->property_dictionary();
51        number_ = dict->FindEntry(name_);
52        if (number_ == NameDictionary::kNotFound) return NOT_FOUND;
53        property_details_ = dict->DetailsAt(number_);
54        if (holder->IsGlobalObject()) {
55          if (property_details_.IsDeleted()) return NOT_FOUND;
56          PropertyCell* cell = PropertyCell::cast(dict->ValueAt(number_));
57          if (cell->value()->IsTheHole()) return NOT_FOUND;
58        }
59      } else {
60        DescriptorArray* descriptors = map->instance_descriptors();
61        number_ = descriptors->SearchWithCache(*name_, map);
62        if (number_ == DescriptorArray::kNotFound) return NOT_FOUND;
63        property_details_ = descriptors->GetDetails(number_);
64      }
65      has_property_ = true;
66      switch (property_details_.type()) {
67        case v8::internal::CONSTANT:
68        case v8::internal::FIELD:
69        case v8::internal::NORMAL:
70          return DATA;
71        case v8::internal::CALLBACKS:
72          return ACCESSOR;
73      }
74    case ACCESSOR:
75    case DATA:
76      return NOT_FOUND;
77    case JSPROXY:
78    case TRANSITION:
79      UNREACHABLE();
80  }
81  UNREACHABLE();
82  return state_;
83}
84}
85}  // namespace v8::internal
86
87#endif  // V8_LOOKUP_INL_H_
88