LCOV - code coverage report
Current view: top level - src - lookup.h (source / functions) Hit Total Coverage
Test: app.info Lines: 15 15 100.0 %
Date: 2019-04-18 Functions: 4 5 80.0 %

          Line data    Source code
       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_H_
       6             : #define V8_LOOKUP_H_
       7             : 
       8             : #include "src/globals.h"
       9             : #include "src/heap/factory.h"
      10             : #include "src/isolate.h"
      11             : #include "src/objects.h"
      12             : #include "src/objects/descriptor-array.h"
      13             : #include "src/objects/js-objects.h"
      14             : #include "src/objects/map.h"
      15             : 
      16             : namespace v8 {
      17             : namespace internal {
      18             : 
      19             : class V8_EXPORT_PRIVATE LookupIterator final {
      20             :  public:
      21             :   enum Configuration {
      22             :     // Configuration bits.
      23             :     kInterceptor = 1 << 0,
      24             :     kPrototypeChain = 1 << 1,
      25             : 
      26             :     // Convenience combinations of bits.
      27             :     OWN_SKIP_INTERCEPTOR = 0,
      28             :     OWN = kInterceptor,
      29             :     PROTOTYPE_CHAIN_SKIP_INTERCEPTOR = kPrototypeChain,
      30             :     PROTOTYPE_CHAIN = kPrototypeChain | kInterceptor,
      31             :     DEFAULT = PROTOTYPE_CHAIN
      32             :   };
      33             : 
      34             :   enum State {
      35             :     ACCESS_CHECK,
      36             :     INTEGER_INDEXED_EXOTIC,
      37             :     INTERCEPTOR,
      38             :     JSPROXY,
      39             :     NOT_FOUND,
      40             :     ACCESSOR,
      41             :     DATA,
      42             :     TRANSITION,
      43             :     // Set state_ to BEFORE_PROPERTY to ensure that the next lookup will be a
      44             :     // PROPERTY lookup.
      45             :     BEFORE_PROPERTY = INTERCEPTOR
      46             :   };
      47             : 
      48             :   inline LookupIterator(Isolate* isolate, Handle<Object> receiver,
      49             :                         Handle<Name> name,
      50             :                         Configuration configuration = DEFAULT);
      51             : 
      52             :   inline LookupIterator(Handle<Object> receiver, Handle<Name> name,
      53             :                         Handle<JSReceiver> holder,
      54             :                         Configuration configuration = DEFAULT);
      55             : 
      56             :   inline LookupIterator(Isolate* isolate, Handle<Object> receiver,
      57             :                         Handle<Name> name, Handle<JSReceiver> holder,
      58             :                         Configuration configuration = DEFAULT);
      59             : 
      60             :   inline LookupIterator(Isolate* isolate, Handle<Object> receiver,
      61             :                         uint32_t index, Configuration configuration = DEFAULT);
      62             : 
      63             :   LookupIterator(Isolate* isolate, Handle<Object> receiver, uint32_t index,
      64             :                  Handle<JSReceiver> holder,
      65             :                  Configuration configuration = DEFAULT)
      66             :       : configuration_(configuration),
      67             :         interceptor_state_(InterceptorState::kUninitialized),
      68             :         property_details_(PropertyDetails::Empty()),
      69             :         isolate_(isolate),
      70             :         receiver_(receiver),
      71             :         initial_holder_(holder),
      72             :         index_(index),
      73   273639786 :         number_(static_cast<uint32_t>(DescriptorArray::kNotFound)) {
      74             :     // kMaxUInt32 isn't a valid index.
      75             :     DCHECK_NE(kMaxUInt32, index_);
      76    91213262 :     Start<true>();
      77             :   }
      78             : 
      79             :   static inline LookupIterator PropertyOrElement(
      80             :       Isolate* isolate, Handle<Object> receiver, Handle<Name> name,
      81             :       Configuration configuration = DEFAULT);
      82             : 
      83             :   static inline LookupIterator PropertyOrElement(
      84             :       Isolate* isolate, Handle<Object> receiver, Handle<Name> name,
      85             :       Handle<JSReceiver> holder, Configuration configuration = DEFAULT);
      86             : 
      87             :   static LookupIterator PropertyOrElement(
      88             :       Isolate* isolate, Handle<Object> receiver, Handle<Object> key,
      89             :       bool* success, Handle<JSReceiver> holder,
      90             :       Configuration configuration = DEFAULT);
      91             : 
      92             :   static LookupIterator PropertyOrElement(
      93             :       Isolate* isolate, Handle<Object> receiver, Handle<Object> key,
      94             :       bool* success, Configuration configuration = DEFAULT);
      95             : 
      96             :   static LookupIterator ForTransitionHandler(
      97             :       Isolate* isolate, Handle<Object> receiver, Handle<Name> name,
      98             :       Handle<Object> value, MaybeHandle<Map> maybe_transition_map);
      99             : 
     100     1413727 :   void Restart() {
     101             :     InterceptorState state = InterceptorState::kUninitialized;
     102     1413727 :     IsElement() ? RestartInternal<true>(state) : RestartInternal<false>(state);
     103     1413733 :   }
     104             : 
     105             :   Isolate* isolate() const { return isolate_; }
     106             :   State state() const { return state_; }
     107             : 
     108             :   Handle<Name> name() const {
     109             :     DCHECK(!IsElement());
     110             :     return name_;
     111             :   }
     112             :   inline Handle<Name> GetName();
     113             :   uint32_t index() const { return index_; }
     114             : 
     115             :   bool IsElement() const { return index_ != kMaxUInt32; }
     116             : 
     117     6042356 :   bool IsFound() const { return state_ != NOT_FOUND; }
     118             :   void Next();
     119             :   void NotFound() {
     120      537329 :     has_property_ = false;
     121      537329 :     state_ = NOT_FOUND;
     122             :   }
     123             : 
     124             :   Heap* heap() const { return isolate_->heap(); }
     125             :   Factory* factory() const { return isolate_->factory(); }
     126             :   Handle<Object> GetReceiver() const { return receiver_; }
     127             : 
     128             :   template <class T>
     129             :   inline Handle<T> GetStoreTarget() const;
     130             :   inline bool is_dictionary_holder() const;
     131             :   inline Handle<Map> transition_map() const;
     132             :   inline Handle<PropertyCell> transition_cell() const;
     133             :   template <class T>
     134             :   inline Handle<T> GetHolder() const;
     135             : 
     136             :   bool HolderIsReceiver() const;
     137             :   bool HolderIsReceiverOrHiddenPrototype() const;
     138             : 
     139             :   bool check_prototype_chain() const {
     140   227591768 :     return (configuration_ & kPrototypeChain) != 0;
     141             :   }
     142             : 
     143             :   /* ACCESS_CHECK */
     144             :   bool HasAccess() const;
     145             : 
     146             :   /* PROPERTY */
     147             :   inline bool ExtendingNonExtensible(Handle<JSReceiver> receiver);
     148             :   void PrepareForDataProperty(Handle<Object> value);
     149             :   void PrepareTransitionToDataProperty(Handle<JSReceiver> receiver,
     150             :                                        Handle<Object> value,
     151             :                                        PropertyAttributes attributes,
     152             :                                        StoreOrigin store_origin);
     153             :   inline bool IsCacheableTransition();
     154             :   void ApplyTransitionToDataProperty(Handle<JSReceiver> receiver);
     155             :   void ReconfigureDataProperty(Handle<Object> value,
     156             :                                PropertyAttributes attributes);
     157             :   void Delete();
     158             :   void TransitionToAccessorProperty(Handle<Object> getter,
     159             :                                     Handle<Object> setter,
     160             :                                     PropertyAttributes attributes);
     161             :   void TransitionToAccessorPair(Handle<Object> pair,
     162             :                                 PropertyAttributes attributes);
     163             :   PropertyDetails property_details() const {
     164             :     DCHECK(has_property_);
     165             :     return property_details_;
     166             :   }
     167             :   PropertyAttributes property_attributes() const {
     168             :     return property_details().attributes();
     169             :   }
     170             :   bool IsConfigurable() const { return property_details().IsConfigurable(); }
     171             :   bool IsReadOnly() const { return property_details().IsReadOnly(); }
     172             :   bool IsEnumerable() const { return property_details().IsEnumerable(); }
     173             :   Representation representation() const {
     174             :     return property_details().representation();
     175             :   }
     176             :   PropertyLocation location() const { return property_details().location(); }
     177             :   PropertyConstness constness() const { return property_details().constness(); }
     178             :   Handle<Map> GetFieldOwnerMap() const;
     179             :   FieldIndex GetFieldIndex() const;
     180             :   Handle<FieldType> GetFieldType() const;
     181             :   int GetFieldDescriptorIndex() const;
     182             :   int GetAccessorIndex() const;
     183             :   int GetConstantIndex() const;
     184             :   Handle<PropertyCell> GetPropertyCell() const;
     185             :   Handle<Object> GetAccessors() const;
     186             :   inline Handle<InterceptorInfo> GetInterceptor() const;
     187             :   Handle<InterceptorInfo> GetInterceptorForFailedAccessCheck() const;
     188             :   Handle<Object> GetDataValue() const;
     189             :   void WriteDataValue(Handle<Object> value, bool initializing_store);
     190             :   inline void UpdateProtector();
     191             : 
     192             :   // Lookup a 'cached' private property for an accessor.
     193             :   // If not found returns false and leaves the LookupIterator unmodified.
     194             :   bool TryLookupCachedProperty();
     195             :   bool LookupCachedProperty();
     196             : 
     197             :  private:
     198             :   // For |ForTransitionHandler|.
     199             :   LookupIterator(Isolate* isolate, Handle<Object> receiver, Handle<Name> name,
     200             :                  Handle<Map> transition_map, PropertyDetails details,
     201             :                  bool has_property);
     202             : 
     203             :   void InternalUpdateProtector();
     204             : 
     205             :   enum class InterceptorState {
     206             :     kUninitialized,
     207             :     kSkipNonMasking,
     208             :     kProcessNonMasking
     209             :   };
     210             : 
     211             :   Handle<Map> GetReceiverMap() const;
     212             : 
     213             :   V8_WARN_UNUSED_RESULT inline JSReceiver NextHolder(Map map);
     214             : 
     215             :   template <bool is_element>
     216             :   V8_EXPORT_PRIVATE void Start();
     217             :   template <bool is_element>
     218             :   void NextInternal(Map map, JSReceiver holder);
     219             :   template <bool is_element>
     220   370897171 :   inline State LookupInHolder(Map map, JSReceiver holder) {
     221             :     return map->IsSpecialReceiverMap()
     222             :                ? LookupInSpecialHolder<is_element>(map, holder)
     223   370897171 :                : LookupInRegularHolder<is_element>(map, holder);
     224             :   }
     225             :   template <bool is_element>
     226             :   State LookupInRegularHolder(Map map, JSReceiver holder);
     227             :   template <bool is_element>
     228             :   State LookupInSpecialHolder(Map map, JSReceiver holder);
     229             :   template <bool is_element>
     230         156 :   void RestartLookupForNonMaskingInterceptors() {
     231         156 :     RestartInternal<is_element>(InterceptorState::kProcessNonMasking);
     232         156 :   }
     233             :   template <bool is_element>
     234             :   void RestartInternal(InterceptorState interceptor_state);
     235             :   Handle<Object> FetchValue() const;
     236             :   bool IsConstFieldValueEqualTo(Object value) const;
     237             :   template <bool is_element>
     238             :   void ReloadPropertyInformation();
     239             : 
     240             :   template <bool is_element>
     241             :   bool SkipInterceptor(JSObject holder);
     242             :   template <bool is_element>
     243             :   static inline InterceptorInfo GetInterceptor(JSObject holder);
     244             : 
     245             :   bool check_interceptor() const {
     246    40217392 :     return (configuration_ & kInterceptor) != 0;
     247             :   }
     248             :   inline int descriptor_number() const;
     249             :   inline int dictionary_entry() const;
     250             : 
     251             :   static inline Configuration ComputeConfiguration(
     252             :       Configuration configuration, Handle<Name> name);
     253             : 
     254             :   static Handle<JSReceiver> GetRootForNonJSReceiver(
     255             :       Isolate* isolate, Handle<Object> receiver, uint32_t index = kMaxUInt32);
     256             :   static inline Handle<JSReceiver> GetRoot(Isolate* isolate,
     257             :                                            Handle<Object> receiver,
     258             :                                            uint32_t index = kMaxUInt32);
     259             : 
     260             :   State NotFound(JSReceiver const holder) const;
     261             : 
     262             :   // If configuration_ becomes mutable, update
     263             :   // HolderIsReceiverOrHiddenPrototype.
     264             :   const Configuration configuration_;
     265             :   State state_;
     266             :   bool has_property_;
     267             :   InterceptorState interceptor_state_;
     268             :   PropertyDetails property_details_;
     269             :   Isolate* const isolate_;
     270             :   Handle<Name> name_;
     271             :   Handle<Object> transition_;
     272             :   const Handle<Object> receiver_;
     273             :   Handle<JSReceiver> holder_;
     274             :   const Handle<JSReceiver> initial_holder_;
     275             :   const uint32_t index_;
     276             :   uint32_t number_;
     277             : };
     278             : 
     279             : 
     280             : }  // namespace internal
     281             : }  // namespace v8
     282             : 
     283             : #endif  // V8_LOOKUP_H_

Generated by: LCOV version 1.10