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_OBJECTS_PROTOTYPE_H_ 6 #define V8_OBJECTS_PROTOTYPE_H_ 7 8 #include "src/execution/isolate.h" 9 #include "src/objects/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() = default; 45 PrototypeIterator(const PrototypeIterator&) = delete; 46 PrototypeIterator& operator=(const PrototypeIterator&) = delete; 47 48 inline bool HasAccess() const; 49 50 template <typename T = HeapObject> GetCurrent()51 T GetCurrent() const { 52 DCHECK(handle_.is_null()); 53 return T::cast(object_); 54 } 55 56 template <typename T = HeapObject> GetCurrent(const PrototypeIterator & iterator)57 static Handle<T> GetCurrent(const PrototypeIterator& iterator) { 58 DCHECK(!iterator.handle_.is_null()); 59 DCHECK_EQ(iterator.object_, Object()); 60 return Handle<T>::cast(iterator.handle_); 61 } 62 63 inline void Advance(); 64 65 inline void AdvanceIgnoringProxies(); 66 67 // Returns false iff a call to JSProxy::GetPrototype throws. 68 V8_WARN_UNUSED_RESULT inline bool AdvanceFollowingProxies(); 69 70 V8_WARN_UNUSED_RESULT inline bool 71 AdvanceFollowingProxiesIgnoringAccessChecks(); 72 IsAtEnd()73 bool IsAtEnd() const { return is_at_end_; } isolate()74 Isolate* isolate() const { return isolate_; } 75 76 private: 77 Isolate* isolate_; 78 Object object_; 79 Handle<HeapObject> handle_; 80 WhereToEnd where_to_end_; 81 bool is_at_end_; 82 int seen_proxies_; 83 }; 84 85 } // namespace internal 86 87 } // namespace v8 88 89 #endif // V8_OBJECTS_PROTOTYPE_H_ 90