Home | History | Annotate | Download | only in src
      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 
     10 namespace v8 {
     11 namespace internal {
     12 
     13 
     14 JSReceiver* 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 
     34 LookupIterator::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