• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
~PrototypeIterator()44   ~PrototypeIterator() {}
45 
46   inline bool HasAccess() const;
47 
48   template <typename T = Object>
GetCurrent()49   T* GetCurrent() const {
50     DCHECK(handle_.is_null());
51     return T::cast(object_);
52   }
53 
54   template <typename T = Object>
GetCurrent(const PrototypeIterator & iterator)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 
IsAtEnd()71   bool IsAtEnd() const { return is_at_end_; }
isolate()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