11cb0ef41Sopenharmony_ci// Copyright 2021 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#ifndef INCLUDE_V8_PERSISTENT_HANDLE_H_ 61cb0ef41Sopenharmony_ci#define INCLUDE_V8_PERSISTENT_HANDLE_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include "v8-internal.h" // NOLINT(build/include_directory) 91cb0ef41Sopenharmony_ci#include "v8-local-handle.h" // NOLINT(build/include_directory) 101cb0ef41Sopenharmony_ci#include "v8-weak-callback-info.h" // NOLINT(build/include_directory) 111cb0ef41Sopenharmony_ci#include "v8config.h" // NOLINT(build/include_directory) 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_cinamespace v8 { 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_ciclass Isolate; 161cb0ef41Sopenharmony_citemplate <class K, class V, class T> 171cb0ef41Sopenharmony_ciclass PersistentValueMapBase; 181cb0ef41Sopenharmony_citemplate <class V, class T> 191cb0ef41Sopenharmony_ciclass PersistentValueVector; 201cb0ef41Sopenharmony_citemplate <class T> 211cb0ef41Sopenharmony_ciclass Global; 221cb0ef41Sopenharmony_citemplate <class T> 231cb0ef41Sopenharmony_ciclass PersistentBase; 241cb0ef41Sopenharmony_citemplate <class K, class V, class T> 251cb0ef41Sopenharmony_ciclass PersistentValueMap; 261cb0ef41Sopenharmony_ciclass Value; 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_cinamespace api_internal { 291cb0ef41Sopenharmony_ciV8_EXPORT Value* Eternalize(v8::Isolate* isolate, Value* handle); 301cb0ef41Sopenharmony_ciV8_EXPORT internal::Address* CopyGlobalReference(internal::Address* from); 311cb0ef41Sopenharmony_ciV8_EXPORT void DisposeGlobal(internal::Address* global_handle); 321cb0ef41Sopenharmony_ciV8_EXPORT void MakeWeak(internal::Address** location_addr); 331cb0ef41Sopenharmony_ciV8_EXPORT void* ClearWeak(internal::Address* location); 341cb0ef41Sopenharmony_ciV8_EXPORT void AnnotateStrongRetainer(internal::Address* location, 351cb0ef41Sopenharmony_ci const char* label); 361cb0ef41Sopenharmony_ciV8_EXPORT internal::Address* GlobalizeReference(internal::Isolate* isolate, 371cb0ef41Sopenharmony_ci internal::Address* handle); 381cb0ef41Sopenharmony_ciV8_EXPORT void MoveGlobalReference(internal::Address** from, 391cb0ef41Sopenharmony_ci internal::Address** to); 401cb0ef41Sopenharmony_ci} // namespace api_internal 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_ci/** 431cb0ef41Sopenharmony_ci * Eternal handles are set-once handles that live for the lifetime of the 441cb0ef41Sopenharmony_ci * isolate. 451cb0ef41Sopenharmony_ci */ 461cb0ef41Sopenharmony_citemplate <class T> 471cb0ef41Sopenharmony_ciclass Eternal { 481cb0ef41Sopenharmony_ci public: 491cb0ef41Sopenharmony_ci V8_INLINE Eternal() : val_(nullptr) {} 501cb0ef41Sopenharmony_ci template <class S> 511cb0ef41Sopenharmony_ci V8_INLINE Eternal(Isolate* isolate, Local<S> handle) : val_(nullptr) { 521cb0ef41Sopenharmony_ci Set(isolate, handle); 531cb0ef41Sopenharmony_ci } 541cb0ef41Sopenharmony_ci // Can only be safely called if already set. 551cb0ef41Sopenharmony_ci V8_INLINE Local<T> Get(Isolate* isolate) const { 561cb0ef41Sopenharmony_ci // The eternal handle will never go away, so as with the roots, we don't 571cb0ef41Sopenharmony_ci // even need to open a handle. 581cb0ef41Sopenharmony_ci return Local<T>(val_); 591cb0ef41Sopenharmony_ci } 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ci V8_INLINE bool IsEmpty() const { return val_ == nullptr; } 621cb0ef41Sopenharmony_ci 631cb0ef41Sopenharmony_ci template <class S> 641cb0ef41Sopenharmony_ci void Set(Isolate* isolate, Local<S> handle) { 651cb0ef41Sopenharmony_ci static_assert(std::is_base_of<T, S>::value, "type check"); 661cb0ef41Sopenharmony_ci val_ = reinterpret_cast<T*>( 671cb0ef41Sopenharmony_ci api_internal::Eternalize(isolate, reinterpret_cast<Value*>(*handle))); 681cb0ef41Sopenharmony_ci } 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ci private: 711cb0ef41Sopenharmony_ci T* val_; 721cb0ef41Sopenharmony_ci}; 731cb0ef41Sopenharmony_ci 741cb0ef41Sopenharmony_cinamespace api_internal { 751cb0ef41Sopenharmony_ciV8_EXPORT void MakeWeak(internal::Address* location, void* data, 761cb0ef41Sopenharmony_ci WeakCallbackInfo<void>::Callback weak_callback, 771cb0ef41Sopenharmony_ci WeakCallbackType type); 781cb0ef41Sopenharmony_ci} // namespace api_internal 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ci/** 811cb0ef41Sopenharmony_ci * An object reference that is independent of any handle scope. Where 821cb0ef41Sopenharmony_ci * a Local handle only lives as long as the HandleScope in which it was 831cb0ef41Sopenharmony_ci * allocated, a PersistentBase handle remains valid until it is explicitly 841cb0ef41Sopenharmony_ci * disposed using Reset(). 851cb0ef41Sopenharmony_ci * 861cb0ef41Sopenharmony_ci * A persistent handle contains a reference to a storage cell within 871cb0ef41Sopenharmony_ci * the V8 engine which holds an object value and which is updated by 881cb0ef41Sopenharmony_ci * the garbage collector whenever the object is moved. A new storage 891cb0ef41Sopenharmony_ci * cell can be created using the constructor or PersistentBase::Reset and 901cb0ef41Sopenharmony_ci * existing handles can be disposed using PersistentBase::Reset. 911cb0ef41Sopenharmony_ci * 921cb0ef41Sopenharmony_ci */ 931cb0ef41Sopenharmony_citemplate <class T> 941cb0ef41Sopenharmony_ciclass PersistentBase { 951cb0ef41Sopenharmony_ci public: 961cb0ef41Sopenharmony_ci /** 971cb0ef41Sopenharmony_ci * If non-empty, destroy the underlying storage cell 981cb0ef41Sopenharmony_ci * IsEmpty() will return true after this call. 991cb0ef41Sopenharmony_ci */ 1001cb0ef41Sopenharmony_ci V8_INLINE void Reset(); 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ci /** 1031cb0ef41Sopenharmony_ci * If non-empty, destroy the underlying storage cell 1041cb0ef41Sopenharmony_ci * and create a new one with the contents of other if other is non empty 1051cb0ef41Sopenharmony_ci */ 1061cb0ef41Sopenharmony_ci template <class S> 1071cb0ef41Sopenharmony_ci V8_INLINE void Reset(Isolate* isolate, const Local<S>& other); 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_ci /** 1101cb0ef41Sopenharmony_ci * If non-empty, destroy the underlying storage cell 1111cb0ef41Sopenharmony_ci * and create a new one with the contents of other if other is non empty 1121cb0ef41Sopenharmony_ci */ 1131cb0ef41Sopenharmony_ci template <class S> 1141cb0ef41Sopenharmony_ci V8_INLINE void Reset(Isolate* isolate, const PersistentBase<S>& other); 1151cb0ef41Sopenharmony_ci 1161cb0ef41Sopenharmony_ci V8_INLINE bool IsEmpty() const { return val_ == nullptr; } 1171cb0ef41Sopenharmony_ci V8_INLINE void Empty() { val_ = 0; } 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ci V8_INLINE Local<T> Get(Isolate* isolate) const { 1201cb0ef41Sopenharmony_ci return Local<T>::New(isolate, *this); 1211cb0ef41Sopenharmony_ci } 1221cb0ef41Sopenharmony_ci 1231cb0ef41Sopenharmony_ci template <class S> 1241cb0ef41Sopenharmony_ci V8_INLINE bool operator==(const PersistentBase<S>& that) const { 1251cb0ef41Sopenharmony_ci internal::Address* a = reinterpret_cast<internal::Address*>(this->val_); 1261cb0ef41Sopenharmony_ci internal::Address* b = reinterpret_cast<internal::Address*>(that.val_); 1271cb0ef41Sopenharmony_ci if (a == nullptr) return b == nullptr; 1281cb0ef41Sopenharmony_ci if (b == nullptr) return false; 1291cb0ef41Sopenharmony_ci return *a == *b; 1301cb0ef41Sopenharmony_ci } 1311cb0ef41Sopenharmony_ci 1321cb0ef41Sopenharmony_ci template <class S> 1331cb0ef41Sopenharmony_ci V8_INLINE bool operator==(const Local<S>& that) const { 1341cb0ef41Sopenharmony_ci internal::Address* a = reinterpret_cast<internal::Address*>(this->val_); 1351cb0ef41Sopenharmony_ci internal::Address* b = reinterpret_cast<internal::Address*>(that.val_); 1361cb0ef41Sopenharmony_ci if (a == nullptr) return b == nullptr; 1371cb0ef41Sopenharmony_ci if (b == nullptr) return false; 1381cb0ef41Sopenharmony_ci return *a == *b; 1391cb0ef41Sopenharmony_ci } 1401cb0ef41Sopenharmony_ci 1411cb0ef41Sopenharmony_ci template <class S> 1421cb0ef41Sopenharmony_ci V8_INLINE bool operator!=(const PersistentBase<S>& that) const { 1431cb0ef41Sopenharmony_ci return !operator==(that); 1441cb0ef41Sopenharmony_ci } 1451cb0ef41Sopenharmony_ci 1461cb0ef41Sopenharmony_ci template <class S> 1471cb0ef41Sopenharmony_ci V8_INLINE bool operator!=(const Local<S>& that) const { 1481cb0ef41Sopenharmony_ci return !operator==(that); 1491cb0ef41Sopenharmony_ci } 1501cb0ef41Sopenharmony_ci 1511cb0ef41Sopenharmony_ci /** 1521cb0ef41Sopenharmony_ci * Install a finalization callback on this object. 1531cb0ef41Sopenharmony_ci * NOTE: There is no guarantee as to *when* or even *if* the callback is 1541cb0ef41Sopenharmony_ci * invoked. The invocation is performed solely on a best effort basis. 1551cb0ef41Sopenharmony_ci * As always, GC-based finalization should *not* be relied upon for any 1561cb0ef41Sopenharmony_ci * critical form of resource management! 1571cb0ef41Sopenharmony_ci * 1581cb0ef41Sopenharmony_ci * The callback is supposed to reset the handle. No further V8 API may be 1591cb0ef41Sopenharmony_ci * called in this callback. In case additional work involving V8 needs to be 1601cb0ef41Sopenharmony_ci * done, a second callback can be scheduled using 1611cb0ef41Sopenharmony_ci * WeakCallbackInfo<void>::SetSecondPassCallback. 1621cb0ef41Sopenharmony_ci */ 1631cb0ef41Sopenharmony_ci template <typename P> 1641cb0ef41Sopenharmony_ci V8_INLINE void SetWeak(P* parameter, 1651cb0ef41Sopenharmony_ci typename WeakCallbackInfo<P>::Callback callback, 1661cb0ef41Sopenharmony_ci WeakCallbackType type); 1671cb0ef41Sopenharmony_ci 1681cb0ef41Sopenharmony_ci /** 1691cb0ef41Sopenharmony_ci * Turns this handle into a weak phantom handle without finalization callback. 1701cb0ef41Sopenharmony_ci * The handle will be reset automatically when the garbage collector detects 1711cb0ef41Sopenharmony_ci * that the object is no longer reachable. 1721cb0ef41Sopenharmony_ci * A related function Isolate::NumberOfPhantomHandleResetsSinceLastCall 1731cb0ef41Sopenharmony_ci * returns how many phantom handles were reset by the garbage collector. 1741cb0ef41Sopenharmony_ci */ 1751cb0ef41Sopenharmony_ci V8_INLINE void SetWeak(); 1761cb0ef41Sopenharmony_ci 1771cb0ef41Sopenharmony_ci template <typename P> 1781cb0ef41Sopenharmony_ci V8_INLINE P* ClearWeak(); 1791cb0ef41Sopenharmony_ci 1801cb0ef41Sopenharmony_ci // TODO(dcarney): remove this. 1811cb0ef41Sopenharmony_ci V8_INLINE void ClearWeak() { ClearWeak<void>(); } 1821cb0ef41Sopenharmony_ci 1831cb0ef41Sopenharmony_ci /** 1841cb0ef41Sopenharmony_ci * Annotates the strong handle with the given label, which is then used by the 1851cb0ef41Sopenharmony_ci * heap snapshot generator as a name of the edge from the root to the handle. 1861cb0ef41Sopenharmony_ci * The function does not take ownership of the label and assumes that the 1871cb0ef41Sopenharmony_ci * label is valid as long as the handle is valid. 1881cb0ef41Sopenharmony_ci */ 1891cb0ef41Sopenharmony_ci V8_INLINE void AnnotateStrongRetainer(const char* label); 1901cb0ef41Sopenharmony_ci 1911cb0ef41Sopenharmony_ci /** Returns true if the handle's reference is weak. */ 1921cb0ef41Sopenharmony_ci V8_INLINE bool IsWeak() const; 1931cb0ef41Sopenharmony_ci 1941cb0ef41Sopenharmony_ci /** 1951cb0ef41Sopenharmony_ci * Assigns a wrapper class ID to the handle. 1961cb0ef41Sopenharmony_ci */ 1971cb0ef41Sopenharmony_ci V8_INLINE void SetWrapperClassId(uint16_t class_id); 1981cb0ef41Sopenharmony_ci 1991cb0ef41Sopenharmony_ci /** 2001cb0ef41Sopenharmony_ci * Returns the class ID previously assigned to this handle or 0 if no class ID 2011cb0ef41Sopenharmony_ci * was previously assigned. 2021cb0ef41Sopenharmony_ci */ 2031cb0ef41Sopenharmony_ci V8_INLINE uint16_t WrapperClassId() const; 2041cb0ef41Sopenharmony_ci 2051cb0ef41Sopenharmony_ci PersistentBase(const PersistentBase& other) = delete; 2061cb0ef41Sopenharmony_ci void operator=(const PersistentBase&) = delete; 2071cb0ef41Sopenharmony_ci 2081cb0ef41Sopenharmony_ci private: 2091cb0ef41Sopenharmony_ci friend class Isolate; 2101cb0ef41Sopenharmony_ci friend class Utils; 2111cb0ef41Sopenharmony_ci template <class F> 2121cb0ef41Sopenharmony_ci friend class Local; 2131cb0ef41Sopenharmony_ci template <class F1, class F2> 2141cb0ef41Sopenharmony_ci friend class Persistent; 2151cb0ef41Sopenharmony_ci template <class F> 2161cb0ef41Sopenharmony_ci friend class Global; 2171cb0ef41Sopenharmony_ci template <class F> 2181cb0ef41Sopenharmony_ci friend class PersistentBase; 2191cb0ef41Sopenharmony_ci template <class F> 2201cb0ef41Sopenharmony_ci friend class ReturnValue; 2211cb0ef41Sopenharmony_ci template <class F1, class F2, class F3> 2221cb0ef41Sopenharmony_ci friend class PersistentValueMapBase; 2231cb0ef41Sopenharmony_ci template <class F1, class F2> 2241cb0ef41Sopenharmony_ci friend class PersistentValueVector; 2251cb0ef41Sopenharmony_ci friend class Object; 2261cb0ef41Sopenharmony_ci 2271cb0ef41Sopenharmony_ci explicit V8_INLINE PersistentBase(T* val) : val_(val) {} 2281cb0ef41Sopenharmony_ci V8_INLINE static T* New(Isolate* isolate, T* that); 2291cb0ef41Sopenharmony_ci 2301cb0ef41Sopenharmony_ci T* val_; 2311cb0ef41Sopenharmony_ci}; 2321cb0ef41Sopenharmony_ci 2331cb0ef41Sopenharmony_ci/** 2341cb0ef41Sopenharmony_ci * Default traits for Persistent. This class does not allow 2351cb0ef41Sopenharmony_ci * use of the copy constructor or assignment operator. 2361cb0ef41Sopenharmony_ci * At present kResetInDestructor is not set, but that will change in a future 2371cb0ef41Sopenharmony_ci * version. 2381cb0ef41Sopenharmony_ci */ 2391cb0ef41Sopenharmony_citemplate <class T> 2401cb0ef41Sopenharmony_ciclass NonCopyablePersistentTraits { 2411cb0ef41Sopenharmony_ci public: 2421cb0ef41Sopenharmony_ci using NonCopyablePersistent = Persistent<T, NonCopyablePersistentTraits<T>>; 2431cb0ef41Sopenharmony_ci static const bool kResetInDestructor = false; 2441cb0ef41Sopenharmony_ci template <class S, class M> 2451cb0ef41Sopenharmony_ci V8_INLINE static void Copy(const Persistent<S, M>& source, 2461cb0ef41Sopenharmony_ci NonCopyablePersistent* dest) { 2471cb0ef41Sopenharmony_ci static_assert(sizeof(S) < 0, 2481cb0ef41Sopenharmony_ci "NonCopyablePersistentTraits::Copy is not instantiable"); 2491cb0ef41Sopenharmony_ci } 2501cb0ef41Sopenharmony_ci}; 2511cb0ef41Sopenharmony_ci 2521cb0ef41Sopenharmony_ci/** 2531cb0ef41Sopenharmony_ci * Helper class traits to allow copying and assignment of Persistent. 2541cb0ef41Sopenharmony_ci * This will clone the contents of storage cell, but not any of the flags, etc. 2551cb0ef41Sopenharmony_ci */ 2561cb0ef41Sopenharmony_citemplate <class T> 2571cb0ef41Sopenharmony_cistruct CopyablePersistentTraits { 2581cb0ef41Sopenharmony_ci using CopyablePersistent = Persistent<T, CopyablePersistentTraits<T>>; 2591cb0ef41Sopenharmony_ci static const bool kResetInDestructor = true; 2601cb0ef41Sopenharmony_ci template <class S, class M> 2611cb0ef41Sopenharmony_ci static V8_INLINE void Copy(const Persistent<S, M>& source, 2621cb0ef41Sopenharmony_ci CopyablePersistent* dest) { 2631cb0ef41Sopenharmony_ci // do nothing, just allow copy 2641cb0ef41Sopenharmony_ci } 2651cb0ef41Sopenharmony_ci}; 2661cb0ef41Sopenharmony_ci 2671cb0ef41Sopenharmony_ci/** 2681cb0ef41Sopenharmony_ci * A PersistentBase which allows copy and assignment. 2691cb0ef41Sopenharmony_ci * 2701cb0ef41Sopenharmony_ci * Copy, assignment and destructor behavior is controlled by the traits 2711cb0ef41Sopenharmony_ci * class M. 2721cb0ef41Sopenharmony_ci * 2731cb0ef41Sopenharmony_ci * Note: Persistent class hierarchy is subject to future changes. 2741cb0ef41Sopenharmony_ci */ 2751cb0ef41Sopenharmony_citemplate <class T, class M> 2761cb0ef41Sopenharmony_ciclass Persistent : public PersistentBase<T> { 2771cb0ef41Sopenharmony_ci public: 2781cb0ef41Sopenharmony_ci /** 2791cb0ef41Sopenharmony_ci * A Persistent with no storage cell. 2801cb0ef41Sopenharmony_ci */ 2811cb0ef41Sopenharmony_ci V8_INLINE Persistent() : PersistentBase<T>(nullptr) {} 2821cb0ef41Sopenharmony_ci /** 2831cb0ef41Sopenharmony_ci * Construct a Persistent from a Local. 2841cb0ef41Sopenharmony_ci * When the Local is non-empty, a new storage cell is created 2851cb0ef41Sopenharmony_ci * pointing to the same object, and no flags are set. 2861cb0ef41Sopenharmony_ci */ 2871cb0ef41Sopenharmony_ci template <class S> 2881cb0ef41Sopenharmony_ci V8_INLINE Persistent(Isolate* isolate, Local<S> that) 2891cb0ef41Sopenharmony_ci : PersistentBase<T>(PersistentBase<T>::New(isolate, *that)) { 2901cb0ef41Sopenharmony_ci static_assert(std::is_base_of<T, S>::value, "type check"); 2911cb0ef41Sopenharmony_ci } 2921cb0ef41Sopenharmony_ci /** 2931cb0ef41Sopenharmony_ci * Construct a Persistent from a Persistent. 2941cb0ef41Sopenharmony_ci * When the Persistent is non-empty, a new storage cell is created 2951cb0ef41Sopenharmony_ci * pointing to the same object, and no flags are set. 2961cb0ef41Sopenharmony_ci */ 2971cb0ef41Sopenharmony_ci template <class S, class M2> 2981cb0ef41Sopenharmony_ci V8_INLINE Persistent(Isolate* isolate, const Persistent<S, M2>& that) 2991cb0ef41Sopenharmony_ci : PersistentBase<T>(PersistentBase<T>::New(isolate, *that)) { 3001cb0ef41Sopenharmony_ci static_assert(std::is_base_of<T, S>::value, "type check"); 3011cb0ef41Sopenharmony_ci } 3021cb0ef41Sopenharmony_ci /** 3031cb0ef41Sopenharmony_ci * The copy constructors and assignment operator create a Persistent 3041cb0ef41Sopenharmony_ci * exactly as the Persistent constructor, but the Copy function from the 3051cb0ef41Sopenharmony_ci * traits class is called, allowing the setting of flags based on the 3061cb0ef41Sopenharmony_ci * copied Persistent. 3071cb0ef41Sopenharmony_ci */ 3081cb0ef41Sopenharmony_ci V8_INLINE Persistent(const Persistent& that) : PersistentBase<T>(nullptr) { 3091cb0ef41Sopenharmony_ci Copy(that); 3101cb0ef41Sopenharmony_ci } 3111cb0ef41Sopenharmony_ci template <class S, class M2> 3121cb0ef41Sopenharmony_ci V8_INLINE Persistent(const Persistent<S, M2>& that) : PersistentBase<T>(0) { 3131cb0ef41Sopenharmony_ci Copy(that); 3141cb0ef41Sopenharmony_ci } 3151cb0ef41Sopenharmony_ci V8_INLINE Persistent& operator=(const Persistent& that) { 3161cb0ef41Sopenharmony_ci Copy(that); 3171cb0ef41Sopenharmony_ci return *this; 3181cb0ef41Sopenharmony_ci } 3191cb0ef41Sopenharmony_ci template <class S, class M2> 3201cb0ef41Sopenharmony_ci V8_INLINE Persistent& operator=(const Persistent<S, M2>& that) { 3211cb0ef41Sopenharmony_ci Copy(that); 3221cb0ef41Sopenharmony_ci return *this; 3231cb0ef41Sopenharmony_ci } 3241cb0ef41Sopenharmony_ci /** 3251cb0ef41Sopenharmony_ci * The destructor will dispose the Persistent based on the 3261cb0ef41Sopenharmony_ci * kResetInDestructor flags in the traits class. Since not calling dispose 3271cb0ef41Sopenharmony_ci * can result in a memory leak, it is recommended to always set this flag. 3281cb0ef41Sopenharmony_ci */ 3291cb0ef41Sopenharmony_ci V8_INLINE ~Persistent() { 3301cb0ef41Sopenharmony_ci if (M::kResetInDestructor) this->Reset(); 3311cb0ef41Sopenharmony_ci } 3321cb0ef41Sopenharmony_ci 3331cb0ef41Sopenharmony_ci // TODO(dcarney): this is pretty useless, fix or remove 3341cb0ef41Sopenharmony_ci template <class S> 3351cb0ef41Sopenharmony_ci V8_INLINE static Persistent<T>& Cast(const Persistent<S>& that) { 3361cb0ef41Sopenharmony_ci#ifdef V8_ENABLE_CHECKS 3371cb0ef41Sopenharmony_ci // If we're going to perform the type check then we have to check 3381cb0ef41Sopenharmony_ci // that the handle isn't empty before doing the checked cast. 3391cb0ef41Sopenharmony_ci if (!that.IsEmpty()) T::Cast(*that); 3401cb0ef41Sopenharmony_ci#endif 3411cb0ef41Sopenharmony_ci return reinterpret_cast<Persistent<T>&>(const_cast<Persistent<S>&>(that)); 3421cb0ef41Sopenharmony_ci } 3431cb0ef41Sopenharmony_ci 3441cb0ef41Sopenharmony_ci // TODO(dcarney): this is pretty useless, fix or remove 3451cb0ef41Sopenharmony_ci template <class S> 3461cb0ef41Sopenharmony_ci V8_INLINE Persistent<S>& As() const { 3471cb0ef41Sopenharmony_ci return Persistent<S>::Cast(*this); 3481cb0ef41Sopenharmony_ci } 3491cb0ef41Sopenharmony_ci 3501cb0ef41Sopenharmony_ci private: 3511cb0ef41Sopenharmony_ci friend class Isolate; 3521cb0ef41Sopenharmony_ci friend class Utils; 3531cb0ef41Sopenharmony_ci template <class F> 3541cb0ef41Sopenharmony_ci friend class Local; 3551cb0ef41Sopenharmony_ci template <class F1, class F2> 3561cb0ef41Sopenharmony_ci friend class Persistent; 3571cb0ef41Sopenharmony_ci template <class F> 3581cb0ef41Sopenharmony_ci friend class ReturnValue; 3591cb0ef41Sopenharmony_ci 3601cb0ef41Sopenharmony_ci explicit V8_INLINE Persistent(T* that) : PersistentBase<T>(that) {} 3611cb0ef41Sopenharmony_ci V8_INLINE T* operator*() const { return this->val_; } 3621cb0ef41Sopenharmony_ci template <class S, class M2> 3631cb0ef41Sopenharmony_ci V8_INLINE void Copy(const Persistent<S, M2>& that); 3641cb0ef41Sopenharmony_ci}; 3651cb0ef41Sopenharmony_ci 3661cb0ef41Sopenharmony_ci/** 3671cb0ef41Sopenharmony_ci * A PersistentBase which has move semantics. 3681cb0ef41Sopenharmony_ci * 3691cb0ef41Sopenharmony_ci * Note: Persistent class hierarchy is subject to future changes. 3701cb0ef41Sopenharmony_ci */ 3711cb0ef41Sopenharmony_citemplate <class T> 3721cb0ef41Sopenharmony_ciclass Global : public PersistentBase<T> { 3731cb0ef41Sopenharmony_ci public: 3741cb0ef41Sopenharmony_ci /** 3751cb0ef41Sopenharmony_ci * A Global with no storage cell. 3761cb0ef41Sopenharmony_ci */ 3771cb0ef41Sopenharmony_ci V8_INLINE Global() : PersistentBase<T>(nullptr) {} 3781cb0ef41Sopenharmony_ci 3791cb0ef41Sopenharmony_ci /** 3801cb0ef41Sopenharmony_ci * Construct a Global from a Local. 3811cb0ef41Sopenharmony_ci * When the Local is non-empty, a new storage cell is created 3821cb0ef41Sopenharmony_ci * pointing to the same object, and no flags are set. 3831cb0ef41Sopenharmony_ci */ 3841cb0ef41Sopenharmony_ci template <class S> 3851cb0ef41Sopenharmony_ci V8_INLINE Global(Isolate* isolate, Local<S> that) 3861cb0ef41Sopenharmony_ci : PersistentBase<T>(PersistentBase<T>::New(isolate, *that)) { 3871cb0ef41Sopenharmony_ci static_assert(std::is_base_of<T, S>::value, "type check"); 3881cb0ef41Sopenharmony_ci } 3891cb0ef41Sopenharmony_ci 3901cb0ef41Sopenharmony_ci /** 3911cb0ef41Sopenharmony_ci * Construct a Global from a PersistentBase. 3921cb0ef41Sopenharmony_ci * When the Persistent is non-empty, a new storage cell is created 3931cb0ef41Sopenharmony_ci * pointing to the same object, and no flags are set. 3941cb0ef41Sopenharmony_ci */ 3951cb0ef41Sopenharmony_ci template <class S> 3961cb0ef41Sopenharmony_ci V8_INLINE Global(Isolate* isolate, const PersistentBase<S>& that) 3971cb0ef41Sopenharmony_ci : PersistentBase<T>(PersistentBase<T>::New(isolate, that.val_)) { 3981cb0ef41Sopenharmony_ci static_assert(std::is_base_of<T, S>::value, "type check"); 3991cb0ef41Sopenharmony_ci } 4001cb0ef41Sopenharmony_ci 4011cb0ef41Sopenharmony_ci /** 4021cb0ef41Sopenharmony_ci * Move constructor. 4031cb0ef41Sopenharmony_ci */ 4041cb0ef41Sopenharmony_ci V8_INLINE Global(Global&& other); 4051cb0ef41Sopenharmony_ci 4061cb0ef41Sopenharmony_ci V8_INLINE ~Global() { this->Reset(); } 4071cb0ef41Sopenharmony_ci 4081cb0ef41Sopenharmony_ci /** 4091cb0ef41Sopenharmony_ci * Move via assignment. 4101cb0ef41Sopenharmony_ci */ 4111cb0ef41Sopenharmony_ci template <class S> 4121cb0ef41Sopenharmony_ci V8_INLINE Global& operator=(Global<S>&& rhs); 4131cb0ef41Sopenharmony_ci 4141cb0ef41Sopenharmony_ci /** 4151cb0ef41Sopenharmony_ci * Pass allows returning uniques from functions, etc. 4161cb0ef41Sopenharmony_ci */ 4171cb0ef41Sopenharmony_ci Global Pass() { return static_cast<Global&&>(*this); } 4181cb0ef41Sopenharmony_ci 4191cb0ef41Sopenharmony_ci /* 4201cb0ef41Sopenharmony_ci * For compatibility with Chromium's base::Bind (base::Passed). 4211cb0ef41Sopenharmony_ci */ 4221cb0ef41Sopenharmony_ci using MoveOnlyTypeForCPP03 = void; 4231cb0ef41Sopenharmony_ci 4241cb0ef41Sopenharmony_ci Global(const Global&) = delete; 4251cb0ef41Sopenharmony_ci void operator=(const Global&) = delete; 4261cb0ef41Sopenharmony_ci 4271cb0ef41Sopenharmony_ci private: 4281cb0ef41Sopenharmony_ci template <class F> 4291cb0ef41Sopenharmony_ci friend class ReturnValue; 4301cb0ef41Sopenharmony_ci V8_INLINE T* operator*() const { return this->val_; } 4311cb0ef41Sopenharmony_ci}; 4321cb0ef41Sopenharmony_ci 4331cb0ef41Sopenharmony_ci// UniquePersistent is an alias for Global for historical reason. 4341cb0ef41Sopenharmony_citemplate <class T> 4351cb0ef41Sopenharmony_ciusing UniquePersistent = Global<T>; 4361cb0ef41Sopenharmony_ci 4371cb0ef41Sopenharmony_ci/** 4381cb0ef41Sopenharmony_ci * Interface for iterating through all the persistent handles in the heap. 4391cb0ef41Sopenharmony_ci */ 4401cb0ef41Sopenharmony_ciclass V8_EXPORT PersistentHandleVisitor { 4411cb0ef41Sopenharmony_ci public: 4421cb0ef41Sopenharmony_ci virtual ~PersistentHandleVisitor() = default; 4431cb0ef41Sopenharmony_ci virtual void VisitPersistentHandle(Persistent<Value>* value, 4441cb0ef41Sopenharmony_ci uint16_t class_id) {} 4451cb0ef41Sopenharmony_ci}; 4461cb0ef41Sopenharmony_ci 4471cb0ef41Sopenharmony_citemplate <class T> 4481cb0ef41Sopenharmony_ciT* PersistentBase<T>::New(Isolate* isolate, T* that) { 4491cb0ef41Sopenharmony_ci if (that == nullptr) return nullptr; 4501cb0ef41Sopenharmony_ci internal::Address* p = reinterpret_cast<internal::Address*>(that); 4511cb0ef41Sopenharmony_ci return reinterpret_cast<T*>(api_internal::GlobalizeReference( 4521cb0ef41Sopenharmony_ci reinterpret_cast<internal::Isolate*>(isolate), p)); 4531cb0ef41Sopenharmony_ci} 4541cb0ef41Sopenharmony_ci 4551cb0ef41Sopenharmony_citemplate <class T, class M> 4561cb0ef41Sopenharmony_citemplate <class S, class M2> 4571cb0ef41Sopenharmony_civoid Persistent<T, M>::Copy(const Persistent<S, M2>& that) { 4581cb0ef41Sopenharmony_ci static_assert(std::is_base_of<T, S>::value, "type check"); 4591cb0ef41Sopenharmony_ci this->Reset(); 4601cb0ef41Sopenharmony_ci if (that.IsEmpty()) return; 4611cb0ef41Sopenharmony_ci internal::Address* p = reinterpret_cast<internal::Address*>(that.val_); 4621cb0ef41Sopenharmony_ci this->val_ = reinterpret_cast<T*>(api_internal::CopyGlobalReference(p)); 4631cb0ef41Sopenharmony_ci M::Copy(that, this); 4641cb0ef41Sopenharmony_ci} 4651cb0ef41Sopenharmony_ci 4661cb0ef41Sopenharmony_citemplate <class T> 4671cb0ef41Sopenharmony_cibool PersistentBase<T>::IsWeak() const { 4681cb0ef41Sopenharmony_ci using I = internal::Internals; 4691cb0ef41Sopenharmony_ci if (this->IsEmpty()) return false; 4701cb0ef41Sopenharmony_ci return I::GetNodeState(reinterpret_cast<internal::Address*>(this->val_)) == 4711cb0ef41Sopenharmony_ci I::kNodeStateIsWeakValue; 4721cb0ef41Sopenharmony_ci} 4731cb0ef41Sopenharmony_ci 4741cb0ef41Sopenharmony_citemplate <class T> 4751cb0ef41Sopenharmony_civoid PersistentBase<T>::Reset() { 4761cb0ef41Sopenharmony_ci if (this->IsEmpty()) return; 4771cb0ef41Sopenharmony_ci api_internal::DisposeGlobal(reinterpret_cast<internal::Address*>(this->val_)); 4781cb0ef41Sopenharmony_ci val_ = nullptr; 4791cb0ef41Sopenharmony_ci} 4801cb0ef41Sopenharmony_ci 4811cb0ef41Sopenharmony_ci/** 4821cb0ef41Sopenharmony_ci * If non-empty, destroy the underlying storage cell 4831cb0ef41Sopenharmony_ci * and create a new one with the contents of other if other is non empty 4841cb0ef41Sopenharmony_ci */ 4851cb0ef41Sopenharmony_citemplate <class T> 4861cb0ef41Sopenharmony_citemplate <class S> 4871cb0ef41Sopenharmony_civoid PersistentBase<T>::Reset(Isolate* isolate, const Local<S>& other) { 4881cb0ef41Sopenharmony_ci static_assert(std::is_base_of<T, S>::value, "type check"); 4891cb0ef41Sopenharmony_ci Reset(); 4901cb0ef41Sopenharmony_ci if (other.IsEmpty()) return; 4911cb0ef41Sopenharmony_ci this->val_ = New(isolate, other.val_); 4921cb0ef41Sopenharmony_ci} 4931cb0ef41Sopenharmony_ci 4941cb0ef41Sopenharmony_ci/** 4951cb0ef41Sopenharmony_ci * If non-empty, destroy the underlying storage cell 4961cb0ef41Sopenharmony_ci * and create a new one with the contents of other if other is non empty 4971cb0ef41Sopenharmony_ci */ 4981cb0ef41Sopenharmony_citemplate <class T> 4991cb0ef41Sopenharmony_citemplate <class S> 5001cb0ef41Sopenharmony_civoid PersistentBase<T>::Reset(Isolate* isolate, 5011cb0ef41Sopenharmony_ci const PersistentBase<S>& other) { 5021cb0ef41Sopenharmony_ci static_assert(std::is_base_of<T, S>::value, "type check"); 5031cb0ef41Sopenharmony_ci Reset(); 5041cb0ef41Sopenharmony_ci if (other.IsEmpty()) return; 5051cb0ef41Sopenharmony_ci this->val_ = New(isolate, other.val_); 5061cb0ef41Sopenharmony_ci} 5071cb0ef41Sopenharmony_ci 5081cb0ef41Sopenharmony_citemplate <class T> 5091cb0ef41Sopenharmony_citemplate <typename P> 5101cb0ef41Sopenharmony_ciV8_INLINE void PersistentBase<T>::SetWeak( 5111cb0ef41Sopenharmony_ci P* parameter, typename WeakCallbackInfo<P>::Callback callback, 5121cb0ef41Sopenharmony_ci WeakCallbackType type) { 5131cb0ef41Sopenharmony_ci using Callback = WeakCallbackInfo<void>::Callback; 5141cb0ef41Sopenharmony_ci#if (__GNUC__ >= 8) && !defined(__clang__) 5151cb0ef41Sopenharmony_ci#pragma GCC diagnostic push 5161cb0ef41Sopenharmony_ci#pragma GCC diagnostic ignored "-Wcast-function-type" 5171cb0ef41Sopenharmony_ci#endif 5181cb0ef41Sopenharmony_ci api_internal::MakeWeak(reinterpret_cast<internal::Address*>(this->val_), 5191cb0ef41Sopenharmony_ci parameter, reinterpret_cast<Callback>(callback), type); 5201cb0ef41Sopenharmony_ci#if (__GNUC__ >= 8) && !defined(__clang__) 5211cb0ef41Sopenharmony_ci#pragma GCC diagnostic pop 5221cb0ef41Sopenharmony_ci#endif 5231cb0ef41Sopenharmony_ci} 5241cb0ef41Sopenharmony_ci 5251cb0ef41Sopenharmony_citemplate <class T> 5261cb0ef41Sopenharmony_civoid PersistentBase<T>::SetWeak() { 5271cb0ef41Sopenharmony_ci api_internal::MakeWeak(reinterpret_cast<internal::Address**>(&this->val_)); 5281cb0ef41Sopenharmony_ci} 5291cb0ef41Sopenharmony_ci 5301cb0ef41Sopenharmony_citemplate <class T> 5311cb0ef41Sopenharmony_citemplate <typename P> 5321cb0ef41Sopenharmony_ciP* PersistentBase<T>::ClearWeak() { 5331cb0ef41Sopenharmony_ci return reinterpret_cast<P*>(api_internal::ClearWeak( 5341cb0ef41Sopenharmony_ci reinterpret_cast<internal::Address*>(this->val_))); 5351cb0ef41Sopenharmony_ci} 5361cb0ef41Sopenharmony_ci 5371cb0ef41Sopenharmony_citemplate <class T> 5381cb0ef41Sopenharmony_civoid PersistentBase<T>::AnnotateStrongRetainer(const char* label) { 5391cb0ef41Sopenharmony_ci api_internal::AnnotateStrongRetainer( 5401cb0ef41Sopenharmony_ci reinterpret_cast<internal::Address*>(this->val_), label); 5411cb0ef41Sopenharmony_ci} 5421cb0ef41Sopenharmony_ci 5431cb0ef41Sopenharmony_citemplate <class T> 5441cb0ef41Sopenharmony_civoid PersistentBase<T>::SetWrapperClassId(uint16_t class_id) { 5451cb0ef41Sopenharmony_ci using I = internal::Internals; 5461cb0ef41Sopenharmony_ci if (this->IsEmpty()) return; 5471cb0ef41Sopenharmony_ci internal::Address* obj = reinterpret_cast<internal::Address*>(this->val_); 5481cb0ef41Sopenharmony_ci uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset; 5491cb0ef41Sopenharmony_ci *reinterpret_cast<uint16_t*>(addr) = class_id; 5501cb0ef41Sopenharmony_ci} 5511cb0ef41Sopenharmony_ci 5521cb0ef41Sopenharmony_citemplate <class T> 5531cb0ef41Sopenharmony_ciuint16_t PersistentBase<T>::WrapperClassId() const { 5541cb0ef41Sopenharmony_ci using I = internal::Internals; 5551cb0ef41Sopenharmony_ci if (this->IsEmpty()) return 0; 5561cb0ef41Sopenharmony_ci internal::Address* obj = reinterpret_cast<internal::Address*>(this->val_); 5571cb0ef41Sopenharmony_ci uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset; 5581cb0ef41Sopenharmony_ci return *reinterpret_cast<uint16_t*>(addr); 5591cb0ef41Sopenharmony_ci} 5601cb0ef41Sopenharmony_ci 5611cb0ef41Sopenharmony_citemplate <class T> 5621cb0ef41Sopenharmony_ciGlobal<T>::Global(Global&& other) : PersistentBase<T>(other.val_) { 5631cb0ef41Sopenharmony_ci if (other.val_ != nullptr) { 5641cb0ef41Sopenharmony_ci api_internal::MoveGlobalReference( 5651cb0ef41Sopenharmony_ci reinterpret_cast<internal::Address**>(&other.val_), 5661cb0ef41Sopenharmony_ci reinterpret_cast<internal::Address**>(&this->val_)); 5671cb0ef41Sopenharmony_ci other.val_ = nullptr; 5681cb0ef41Sopenharmony_ci } 5691cb0ef41Sopenharmony_ci} 5701cb0ef41Sopenharmony_ci 5711cb0ef41Sopenharmony_citemplate <class T> 5721cb0ef41Sopenharmony_citemplate <class S> 5731cb0ef41Sopenharmony_ciGlobal<T>& Global<T>::operator=(Global<S>&& rhs) { 5741cb0ef41Sopenharmony_ci static_assert(std::is_base_of<T, S>::value, "type check"); 5751cb0ef41Sopenharmony_ci if (this != &rhs) { 5761cb0ef41Sopenharmony_ci this->Reset(); 5771cb0ef41Sopenharmony_ci if (rhs.val_ != nullptr) { 5781cb0ef41Sopenharmony_ci this->val_ = rhs.val_; 5791cb0ef41Sopenharmony_ci api_internal::MoveGlobalReference( 5801cb0ef41Sopenharmony_ci reinterpret_cast<internal::Address**>(&rhs.val_), 5811cb0ef41Sopenharmony_ci reinterpret_cast<internal::Address**>(&this->val_)); 5821cb0ef41Sopenharmony_ci rhs.val_ = nullptr; 5831cb0ef41Sopenharmony_ci } 5841cb0ef41Sopenharmony_ci } 5851cb0ef41Sopenharmony_ci return *this; 5861cb0ef41Sopenharmony_ci} 5871cb0ef41Sopenharmony_ci 5881cb0ef41Sopenharmony_ci} // namespace v8 5891cb0ef41Sopenharmony_ci 5901cb0ef41Sopenharmony_ci#endif // INCLUDE_V8_PERSISTENT_HANDLE_H_ 591