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
11namespace v8 {
12namespace 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
26class 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() = default;
45
46 inline bool HasAccess() const;
47
48 template <typename T = HeapObject>
49 T GetCurrent() const {
50 DCHECK(handle_.is_null());
51 return T::cast(object_);
52 }
53
54 template <typename T = HeapObject>
55 static Handle<T> GetCurrent(const PrototypeIterator& iterator) {
56 DCHECK(!iterator.handle_.is_null());
57 DCHECK_EQ(iterator.object_, 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<HeapObject> 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