lookup-inl.h 2.63 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
// 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());

22
  if (!check_prototype_chain() &&
23 24 25
      !(check_hidden() && next->map()->is_hidden_prototype()) &&
      // Always lookup behind the JSGlobalProxy into the JSGlobalObject, even
      // when not checking other hidden prototypes.
26
      !map->IsJSGlobalProxyMap()) {
27 28 29 30 31 32 33
    return NULL;
  }

  return next;
}


34 35
LookupIterator::State LookupIterator::LookupInHolder(Map* map,
                                                     JSReceiver* holder) {
36
  STATIC_ASSERT(INTERCEPTOR == BEFORE_PROPERTY);
37 38 39
  DisallowHeapAllocation no_gc;
  switch (state_) {
    case NOT_FOUND:
40 41
      if (map->IsJSProxyMap()) return JSPROXY;
      if (map->is_access_check_needed()) return ACCESS_CHECK;
42 43 44 45 46 47 48 49
    // Fall through.
    case ACCESS_CHECK:
      if (check_interceptor() && map->has_named_interceptor()) {
        return INTERCEPTOR;
      }
    // Fall through.
    case INTERCEPTOR:
      if (map->is_dictionary_map()) {
50 51 52 53 54 55 56 57 58
        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;
        }
59 60 61 62
      } else {
        DescriptorArray* descriptors = map->instance_descriptors();
        number_ = descriptors->SearchWithCache(*name_, map);
        if (number_ == DescriptorArray::kNotFound) return NOT_FOUND;
63
        property_details_ = descriptors->GetDetails(number_);
64
      }
65 66 67 68 69 70 71 72 73 74
      has_property_ = true;
      switch (property_details_.type()) {
        case v8::internal::CONSTANT:
        case v8::internal::FIELD:
          return DATA;
        case v8::internal::CALLBACKS:
          return ACCESSOR;
      }
    case ACCESSOR:
    case DATA:
75 76
      return NOT_FOUND;
    case JSPROXY:
77
    case TRANSITION:
78 79 80 81 82 83 84 85 86
      UNREACHABLE();
  }
  UNREACHABLE();
  return state_;
}
}
}  // namespace v8::internal

#endif  // V8_LOOKUP_INL_H_