summaryrefslogtreecommitdiff
path: root/deps/v8/src/prototype.h
blob: e8fe06ac4407e6ef51e24814eab92fa797f90a22 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_PROTOTYPE_H_
#define V8_PROTOTYPE_H_

#include "src/isolate.h"
#include "src/objects.h"

namespace v8 {
namespace internal {

/**
 * A class to uniformly access the prototype of any Object and walk its
 * prototype chain.
 *
 * The PrototypeIterator can either start at the prototype (default), or
 * include the receiver itself. If a PrototypeIterator is constructed for a
 * Map, it will always start at the prototype.
 *
 * The PrototypeIterator can either run to the null_value(), the first
 * non-hidden prototype, or a given object.
 */

class PrototypeIterator {
 public:
  enum WhereToEnd { END_AT_NULL, END_AT_NON_HIDDEN };

  inline PrototypeIterator(Isolate* isolate, Handle<JSReceiver> receiver,
                           WhereToStart where_to_start = kStartAtPrototype,
                           WhereToEnd where_to_end = END_AT_NULL);

  inline PrototypeIterator(Isolate* isolate, JSReceiver* receiver,
                           WhereToStart where_to_start = kStartAtPrototype,
                           WhereToEnd where_to_end = END_AT_NULL);

  inline explicit PrototypeIterator(Isolate* isolate, Map* receiver_map,
                                    WhereToEnd where_to_end = END_AT_NULL);

  inline explicit PrototypeIterator(Isolate* isolate, Handle<Map> receiver_map,
                                    WhereToEnd where_to_end = END_AT_NULL);

  ~PrototypeIterator() = default;

  inline bool HasAccess() const;

  template <typename T = Object>
  T* GetCurrent() const {
    DCHECK(handle_.is_null());
    return T::cast(object_);
  }

  template <typename T = Object>
  static Handle<T> GetCurrent(const PrototypeIterator& iterator) {
    DCHECK(!iterator.handle_.is_null());
    DCHECK_NULL(iterator.object_);
    return Handle<T>::cast(iterator.handle_);
  }

  inline void Advance();

  inline void AdvanceIgnoringProxies();

  // Returns false iff a call to JSProxy::GetPrototype throws.
  V8_WARN_UNUSED_RESULT inline bool AdvanceFollowingProxies();

  V8_WARN_UNUSED_RESULT inline bool
  AdvanceFollowingProxiesIgnoringAccessChecks();

  bool IsAtEnd() const { return is_at_end_; }
  Isolate* isolate() const { return isolate_; }

 private:
  Isolate* isolate_;
  Object* object_;
  Handle<Object> handle_;
  WhereToEnd where_to_end_;
  bool is_at_end_;
  int seen_proxies_;

  DISALLOW_COPY_AND_ASSIGN(PrototypeIterator);
};


}  // namespace internal

}  // namespace v8

#endif  // V8_PROTOTYPE_H_