1 // Copyright 2011 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_MAYBE_HANDLES_H_ 6 #define V8_MAYBE_HANDLES_H_ 7 8 #include <type_traits> 9 10 #include "src/handles.h" 11 12 namespace v8 { 13 namespace internal { 14 15 // ---------------------------------------------------------------------------- 16 // A Handle can be converted into a MaybeHandle. Converting a MaybeHandle 17 // into a Handle requires checking that it does not point to nullptr. This 18 // ensures nullptr checks before use. 19 // 20 // Also note that Handles do not provide default equality comparison or hashing 21 // operators on purpose. Such operators would be misleading, because intended 22 // semantics is ambiguous between Handle location and object identity. 23 template <typename T> 24 class MaybeHandle final { 25 public: MaybeHandle()26 V8_INLINE MaybeHandle() {} 27 28 // Constructor for handling automatic up casting from Handle. 29 // Ex. Handle<JSArray> can be passed when MaybeHandle<Object> is expected. 30 template <typename S, typename = typename std::enable_if< 31 std::is_convertible<S*, T*>::value>::type> MaybeHandle(Handle<S> handle)32 V8_INLINE MaybeHandle(Handle<S> handle) 33 : location_(reinterpret_cast<T**>(handle.location_)) {} 34 35 // Constructor for handling automatic up casting. 36 // Ex. MaybeHandle<JSArray> can be passed when Handle<Object> is expected. 37 template <typename S, typename = typename std::enable_if< 38 std::is_convertible<S*, T*>::value>::type> MaybeHandle(MaybeHandle<S> maybe_handle)39 V8_INLINE MaybeHandle(MaybeHandle<S> maybe_handle) 40 : location_(reinterpret_cast<T**>(maybe_handle.location_)) {} 41 42 V8_INLINE MaybeHandle(T* object, Isolate* isolate); 43 Assert()44 V8_INLINE void Assert() const { DCHECK_NOT_NULL(location_); } Check()45 V8_INLINE void Check() const { CHECK_NOT_NULL(location_); } 46 ToHandleChecked()47 V8_INLINE Handle<T> ToHandleChecked() const { 48 Check(); 49 return Handle<T>(location_); 50 } 51 52 // Convert to a Handle with a type that can be upcasted to. 53 template <typename S> ToHandle(Handle<S> * out)54 V8_INLINE bool ToHandle(Handle<S>* out) const { 55 if (location_ == nullptr) { 56 *out = Handle<T>::null(); 57 return false; 58 } else { 59 *out = Handle<T>(location_); 60 return true; 61 } 62 } 63 64 // Returns the raw address where this handle is stored. This should only be 65 // used for hashing handles; do not ever try to dereference it. address()66 V8_INLINE Address address() const { return bit_cast<Address>(location_); } 67 is_null()68 bool is_null() const { return location_ == nullptr; } 69 70 protected: 71 T** location_ = nullptr; 72 73 // MaybeHandles of different classes are allowed to access each 74 // other's location_. 75 template <typename> 76 friend class MaybeHandle; 77 }; 78 79 // A handle which contains a potentially weak pointer. Keeps it alive (strongly) 80 // while the MaybeObjectHandle is alive. 81 class MaybeObjectHandle { 82 public: 83 inline MaybeObjectHandle(); 84 inline MaybeObjectHandle(MaybeObject* object, Isolate* isolate); 85 inline MaybeObjectHandle(Object* object, Isolate* isolate); 86 inline explicit MaybeObjectHandle(Handle<Object> object); 87 88 static inline MaybeObjectHandle Weak(Object* object, Isolate* isolate); 89 static inline MaybeObjectHandle Weak(Handle<Object> object); 90 91 inline MaybeObject* operator*() const; 92 inline MaybeObject* operator->() const; 93 inline Handle<Object> object() const; 94 is_identical_to(const MaybeObjectHandle & other)95 bool is_identical_to(const MaybeObjectHandle& other) const { 96 Handle<Object> this_handle; 97 Handle<Object> other_handle; 98 return reference_type_ == other.reference_type_ && 99 handle_.ToHandle(&this_handle) == 100 other.handle_.ToHandle(&other_handle) && 101 this_handle.is_identical_to(other_handle); 102 } 103 is_null()104 bool is_null() const { return handle_.is_null(); } 105 106 private: 107 inline MaybeObjectHandle(Object* object, 108 HeapObjectReferenceType reference_type, 109 Isolate* isolate); 110 inline MaybeObjectHandle(Handle<Object> object, 111 HeapObjectReferenceType reference_type); 112 113 HeapObjectReferenceType reference_type_; 114 MaybeHandle<Object> handle_; 115 }; 116 117 } // namespace internal 118 } // namespace v8 119 120 #endif // V8_MAYBE_HANDLES_H_ 121