// Copyright 2011 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_MAYBE_HANDLES_H_ #define V8_MAYBE_HANDLES_H_ #include #include "src/handles.h" namespace v8 { namespace internal { // ---------------------------------------------------------------------------- // A Handle can be converted into a MaybeHandle. Converting a MaybeHandle // into a Handle requires checking that it does not point to nullptr. This // ensures nullptr checks before use. // // Also note that Handles do not provide default equality comparison or hashing // operators on purpose. Such operators would be misleading, because intended // semantics is ambiguous between Handle location and object identity. template class MaybeHandle final { public: V8_INLINE MaybeHandle() = default; // Constructor for handling automatic up casting from Handle. // Ex. Handle can be passed when MaybeHandle is expected. template ::value>::type> V8_INLINE MaybeHandle(Handle handle) : location_(reinterpret_cast(handle.location_)) {} // Constructor for handling automatic up casting. // Ex. MaybeHandle can be passed when Handle is expected. template ::value>::type> V8_INLINE MaybeHandle(MaybeHandle maybe_handle) : location_(reinterpret_cast(maybe_handle.location_)) {} V8_INLINE MaybeHandle(T* object, Isolate* isolate); V8_INLINE void Assert() const { DCHECK_NOT_NULL(location_); } V8_INLINE void Check() const { CHECK_NOT_NULL(location_); } V8_INLINE Handle ToHandleChecked() const { Check(); return Handle(location_); } // Convert to a Handle with a type that can be upcasted to. template V8_INLINE bool ToHandle(Handle* out) const { if (location_ == nullptr) { *out = Handle::null(); return false; } else { *out = Handle(location_); return true; } } // Returns the raw address where this handle is stored. This should only be // used for hashing handles; do not ever try to dereference it. V8_INLINE Address address() const { return bit_cast
(location_); } bool is_null() const { return location_ == nullptr; } protected: T** location_ = nullptr; // MaybeHandles of different classes are allowed to access each // other's location_. template friend class MaybeHandle; }; // A handle which contains a potentially weak pointer. Keeps it alive (strongly) // while the MaybeObjectHandle is alive. class MaybeObjectHandle { public: inline MaybeObjectHandle(); inline MaybeObjectHandle(MaybeObject* object, Isolate* isolate); inline MaybeObjectHandle(Object* object, Isolate* isolate); inline explicit MaybeObjectHandle(Handle object); static inline MaybeObjectHandle Weak(Object* object, Isolate* isolate); static inline MaybeObjectHandle Weak(Handle object); inline MaybeObject* operator*() const; inline MaybeObject* operator->() const; inline Handle object() const; bool is_identical_to(const MaybeObjectHandle& other) const { Handle this_handle; Handle other_handle; return reference_type_ == other.reference_type_ && handle_.ToHandle(&this_handle) == other.handle_.ToHandle(&other_handle) && this_handle.is_identical_to(other_handle); } bool is_null() const { return handle_.is_null(); } private: inline MaybeObjectHandle(Object* object, HeapObjectReferenceType reference_type, Isolate* isolate); inline MaybeObjectHandle(Handle object, HeapObjectReferenceType reference_type); HeapObjectReferenceType reference_type_; MaybeHandle handle_; }; } // namespace internal } // namespace v8 #endif // V8_MAYBE_HANDLES_H_