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_PROTOTYPE_H_
      6 #define V8_PROTOTYPE_H_
      7 
      8 #include "src/isolate.h"
      9 #include "src/objects.h"
     10 
     11 namespace v8 {
     12 namespace internal {
     13 
     14 /**
     15  * A class to uniformly access the prototype of any Object and walk its
     16  * prototype chain.
     17  *
     18  * The PrototypeIterator can either start at the prototype (default), or
     19  * include the receiver itself. If a PrototypeIterator is constructed for a
     20  * Map, it will always start at the prototype.
     21  *
     22  * The PrototypeIterator can either run to the null_value(), the first
     23  * non-hidden prototype, or a given object.
     24  */
     25 
     26 class PrototypeIterator {
     27  public:
     28   enum WhereToEnd { END_AT_NULL, END_AT_NON_HIDDEN };
     29 
     30   inline PrototypeIterator(Isolate* isolate, Handle<JSReceiver> receiver,
     31                            WhereToStart where_to_start = kStartAtPrototype,
     32                            WhereToEnd where_to_end = END_AT_NULL);
     33 
     34   inline PrototypeIterator(Isolate* isolate, JSReceiver* receiver,
     35                            WhereToStart where_to_start = kStartAtPrototype,
     36                            WhereToEnd where_to_end = END_AT_NULL);
     37 
     38   inline explicit PrototypeIterator(Isolate* isolate, Map* receiver_map,
     39                                     WhereToEnd where_to_end = END_AT_NULL);
     40 
     41   inline explicit PrototypeIterator(Isolate* isolate, Handle<Map> receiver_map,
     42                                     WhereToEnd where_to_end = END_AT_NULL);
     43 
     44   ~PrototypeIterator() {}
     45 
     46   inline bool HasAccess() const;
     47 
     48   template <typename T = Object>
     49   T* GetCurrent() const {
     50     DCHECK(handle_.is_null());
     51     return T::cast(object_);
     52   }
     53 
     54   template <typename T = Object>
     55   static Handle<T> GetCurrent(const PrototypeIterator& iterator) {
     56     DCHECK(!iterator.handle_.is_null());
     57     DCHECK_NULL(iterator.object_);
     58     return Handle<T>::cast(iterator.handle_);
     59   }
     60 
     61   inline void Advance();
     62 
     63   inline void AdvanceIgnoringProxies();
     64 
     65   // Returns false iff a call to JSProxy::GetPrototype throws.
     66   V8_WARN_UNUSED_RESULT inline bool AdvanceFollowingProxies();
     67 
     68   V8_WARN_UNUSED_RESULT inline bool
     69   AdvanceFollowingProxiesIgnoringAccessChecks();
     70 
     71   bool IsAtEnd() const { return is_at_end_; }
     72   Isolate* isolate() const { return isolate_; }
     73 
     74  private:
     75   Isolate* isolate_;
     76   Object* object_;
     77   Handle<Object> handle_;
     78   WhereToEnd where_to_end_;
     79   bool is_at_end_;
     80   int seen_proxies_;
     81 
     82   DISALLOW_COPY_AND_ASSIGN(PrototypeIterator);
     83 };
     84 
     85 
     86 }  // namespace internal
     87 
     88 }  // namespace v8
     89 
     90 #endif  // V8_PROTOTYPE_H_
     91