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_TRACED_HANDLE_H_ 61cb0ef41Sopenharmony_ci#define INCLUDE_V8_TRACED_HANDLE_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include <stddef.h> 91cb0ef41Sopenharmony_ci#include <stdint.h> 101cb0ef41Sopenharmony_ci#include <stdio.h> 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ci#include <atomic> 131cb0ef41Sopenharmony_ci#include <memory> 141cb0ef41Sopenharmony_ci#include <type_traits> 151cb0ef41Sopenharmony_ci#include <utility> 161cb0ef41Sopenharmony_ci 171cb0ef41Sopenharmony_ci#include "v8-internal.h" // NOLINT(build/include_directory) 181cb0ef41Sopenharmony_ci#include "v8-local-handle.h" // NOLINT(build/include_directory) 191cb0ef41Sopenharmony_ci#include "v8-weak-callback-info.h" // NOLINT(build/include_directory) 201cb0ef41Sopenharmony_ci#include "v8config.h" // NOLINT(build/include_directory) 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_cinamespace v8 { 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_ciclass Value; 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_cinamespace internal { 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ciclass BasicTracedReferenceExtractor; 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_cienum class GlobalHandleStoreMode { 311cb0ef41Sopenharmony_ci kInitializingStore, 321cb0ef41Sopenharmony_ci kAssigningStore, 331cb0ef41Sopenharmony_ci}; 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ciV8_EXPORT internal::Address* GlobalizeTracedReference( 361cb0ef41Sopenharmony_ci internal::Isolate* isolate, internal::Address value, 371cb0ef41Sopenharmony_ci internal::Address* slot, GlobalHandleStoreMode store_mode); 381cb0ef41Sopenharmony_ciV8_EXPORT void MoveTracedReference(internal::Address** from, 391cb0ef41Sopenharmony_ci internal::Address** to); 401cb0ef41Sopenharmony_ciV8_EXPORT void CopyTracedReference(const internal::Address* const* from, 411cb0ef41Sopenharmony_ci internal::Address** to); 421cb0ef41Sopenharmony_ciV8_EXPORT void DisposeTracedReference(internal::Address* global_handle); 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_ci} // namespace internal 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ci/** 471cb0ef41Sopenharmony_ci * An indirect handle, where the indirect pointer points to a GlobalHandles 481cb0ef41Sopenharmony_ci * node. 491cb0ef41Sopenharmony_ci */ 501cb0ef41Sopenharmony_ciclass TracedReferenceBase : public IndirectHandleBase { 511cb0ef41Sopenharmony_ci public: 521cb0ef41Sopenharmony_ci /** 531cb0ef41Sopenharmony_ci * If non-empty, destroy the underlying storage cell. |IsEmpty| will return 541cb0ef41Sopenharmony_ci * true after this call. 551cb0ef41Sopenharmony_ci */ 561cb0ef41Sopenharmony_ci V8_INLINE void Reset(); 571cb0ef41Sopenharmony_ci 581cb0ef41Sopenharmony_ci /** 591cb0ef41Sopenharmony_ci * Construct a Local<Value> from this handle. 601cb0ef41Sopenharmony_ci */ 611cb0ef41Sopenharmony_ci V8_INLINE Local<Value> Get(Isolate* isolate) const { 621cb0ef41Sopenharmony_ci if (IsEmpty()) return Local<Value>(); 631cb0ef41Sopenharmony_ci return Local<Value>::New(isolate, this->value<Value>()); 641cb0ef41Sopenharmony_ci } 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ci /** 671cb0ef41Sopenharmony_ci * Returns true if this TracedReference is empty, i.e., has not been 681cb0ef41Sopenharmony_ci * assigned an object. This version of IsEmpty is thread-safe. 691cb0ef41Sopenharmony_ci */ 701cb0ef41Sopenharmony_ci bool IsEmptyThreadSafe() const { 711cb0ef41Sopenharmony_ci return this->GetSlotThreadSafe() == nullptr; 721cb0ef41Sopenharmony_ci } 731cb0ef41Sopenharmony_ci 741cb0ef41Sopenharmony_ci /** 751cb0ef41Sopenharmony_ci * Assigns a wrapper class ID to the handle. 761cb0ef41Sopenharmony_ci */ 771cb0ef41Sopenharmony_ci V8_INLINE void SetWrapperClassId(uint16_t class_id); 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_ci /** 801cb0ef41Sopenharmony_ci * Returns the class ID previously assigned to this handle or 0 if no class ID 811cb0ef41Sopenharmony_ci * was previously assigned. 821cb0ef41Sopenharmony_ci */ 831cb0ef41Sopenharmony_ci V8_INLINE uint16_t WrapperClassId() const; 841cb0ef41Sopenharmony_ci 851cb0ef41Sopenharmony_ci protected: 861cb0ef41Sopenharmony_ci V8_INLINE TracedReferenceBase() = default; 871cb0ef41Sopenharmony_ci 881cb0ef41Sopenharmony_ci /** 891cb0ef41Sopenharmony_ci * Update this reference in a thread-safe way. 901cb0ef41Sopenharmony_ci */ 911cb0ef41Sopenharmony_ci void SetSlotThreadSafe(void* new_val) { 921cb0ef41Sopenharmony_ci reinterpret_cast<std::atomic<void*>*>(&slot())->store( 931cb0ef41Sopenharmony_ci new_val, std::memory_order_relaxed); 941cb0ef41Sopenharmony_ci } 951cb0ef41Sopenharmony_ci 961cb0ef41Sopenharmony_ci /** 971cb0ef41Sopenharmony_ci * Get this reference in a thread-safe way 981cb0ef41Sopenharmony_ci */ 991cb0ef41Sopenharmony_ci const void* GetSlotThreadSafe() const { 1001cb0ef41Sopenharmony_ci return reinterpret_cast<std::atomic<const void*> const*>(&slot())->load( 1011cb0ef41Sopenharmony_ci std::memory_order_relaxed); 1021cb0ef41Sopenharmony_ci } 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci V8_EXPORT void CheckValue() const; 1051cb0ef41Sopenharmony_ci 1061cb0ef41Sopenharmony_ci friend class internal::BasicTracedReferenceExtractor; 1071cb0ef41Sopenharmony_ci template <typename F> 1081cb0ef41Sopenharmony_ci friend class Local; 1091cb0ef41Sopenharmony_ci template <typename U> 1101cb0ef41Sopenharmony_ci friend bool operator==(const TracedReferenceBase&, const Local<U>&); 1111cb0ef41Sopenharmony_ci friend bool operator==(const TracedReferenceBase&, 1121cb0ef41Sopenharmony_ci const TracedReferenceBase&); 1131cb0ef41Sopenharmony_ci}; 1141cb0ef41Sopenharmony_ci 1151cb0ef41Sopenharmony_ci/** 1161cb0ef41Sopenharmony_ci * A traced handle with copy and move semantics. The handle is to be used 1171cb0ef41Sopenharmony_ci * together as part of GarbageCollected objects (see v8-cppgc.h) or from stack 1181cb0ef41Sopenharmony_ci * and specifies edges from C++ objects to JavaScript. 1191cb0ef41Sopenharmony_ci * 1201cb0ef41Sopenharmony_ci * The exact semantics are: 1211cb0ef41Sopenharmony_ci * - Tracing garbage collections using CppHeap. 1221cb0ef41Sopenharmony_ci * - Non-tracing garbage collections refer to 1231cb0ef41Sopenharmony_ci * |v8::EmbedderRootsHandler::IsRoot()| whether the handle should 1241cb0ef41Sopenharmony_ci * be treated as root or not. 1251cb0ef41Sopenharmony_ci * 1261cb0ef41Sopenharmony_ci * Note that the base class cannot be instantiated itself, use |TracedReference| 1271cb0ef41Sopenharmony_ci * instead. 1281cb0ef41Sopenharmony_ci */ 1291cb0ef41Sopenharmony_citemplate <typename T> 1301cb0ef41Sopenharmony_ciclass BasicTracedReference : public TracedReferenceBase { 1311cb0ef41Sopenharmony_ci public: 1321cb0ef41Sopenharmony_ci /** 1331cb0ef41Sopenharmony_ci * Construct a Local<T> from this handle. 1341cb0ef41Sopenharmony_ci */ 1351cb0ef41Sopenharmony_ci Local<T> Get(Isolate* isolate) const { return Local<T>::New(isolate, *this); } 1361cb0ef41Sopenharmony_ci 1371cb0ef41Sopenharmony_ci template <class S> 1381cb0ef41Sopenharmony_ci V8_INLINE BasicTracedReference<S>& As() const { 1391cb0ef41Sopenharmony_ci return reinterpret_cast<BasicTracedReference<S>&>( 1401cb0ef41Sopenharmony_ci const_cast<BasicTracedReference<T>&>(*this)); 1411cb0ef41Sopenharmony_ci } 1421cb0ef41Sopenharmony_ci 1431cb0ef41Sopenharmony_ci V8_DEPRECATE_SOON("Use Get to convert to Local instead") 1441cb0ef41Sopenharmony_ci V8_INLINE T* operator->() const { 1451cb0ef41Sopenharmony_ci#ifdef V8_ENABLE_CHECKS 1461cb0ef41Sopenharmony_ci CheckValue(); 1471cb0ef41Sopenharmony_ci#endif // V8_ENABLE_CHECKS 1481cb0ef41Sopenharmony_ci return this->template value<T>(); 1491cb0ef41Sopenharmony_ci } 1501cb0ef41Sopenharmony_ci 1511cb0ef41Sopenharmony_ci V8_DEPRECATE_SOON("Use Get to convert to Local instead") 1521cb0ef41Sopenharmony_ci V8_INLINE T* operator*() const { return this->operator->(); } 1531cb0ef41Sopenharmony_ci 1541cb0ef41Sopenharmony_ci private: 1551cb0ef41Sopenharmony_ci /** 1561cb0ef41Sopenharmony_ci * An empty BasicTracedReference without storage cell. 1571cb0ef41Sopenharmony_ci */ 1581cb0ef41Sopenharmony_ci BasicTracedReference() = default; 1591cb0ef41Sopenharmony_ci 1601cb0ef41Sopenharmony_ci V8_INLINE static internal::Address* New( 1611cb0ef41Sopenharmony_ci Isolate* isolate, T* that, internal::Address** slot, 1621cb0ef41Sopenharmony_ci internal::GlobalHandleStoreMode store_mode); 1631cb0ef41Sopenharmony_ci 1641cb0ef41Sopenharmony_ci template <typename F> 1651cb0ef41Sopenharmony_ci friend class Local; 1661cb0ef41Sopenharmony_ci friend class Object; 1671cb0ef41Sopenharmony_ci template <typename F> 1681cb0ef41Sopenharmony_ci friend class TracedReference; 1691cb0ef41Sopenharmony_ci template <typename F> 1701cb0ef41Sopenharmony_ci friend class BasicTracedReference; 1711cb0ef41Sopenharmony_ci template <typename F> 1721cb0ef41Sopenharmony_ci friend class ReturnValue; 1731cb0ef41Sopenharmony_ci}; 1741cb0ef41Sopenharmony_ci 1751cb0ef41Sopenharmony_ci/** 1761cb0ef41Sopenharmony_ci * A traced handle without destructor that clears the handle. The embedder needs 1771cb0ef41Sopenharmony_ci * to ensure that the handle is not accessed once the V8 object has been 1781cb0ef41Sopenharmony_ci * reclaimed. For more details see BasicTracedReference. 1791cb0ef41Sopenharmony_ci */ 1801cb0ef41Sopenharmony_citemplate <typename T> 1811cb0ef41Sopenharmony_ciclass TracedReference : public BasicTracedReference<T> { 1821cb0ef41Sopenharmony_ci public: 1831cb0ef41Sopenharmony_ci using BasicTracedReference<T>::Reset; 1841cb0ef41Sopenharmony_ci 1851cb0ef41Sopenharmony_ci /** 1861cb0ef41Sopenharmony_ci * An empty TracedReference without storage cell. 1871cb0ef41Sopenharmony_ci */ 1881cb0ef41Sopenharmony_ci V8_INLINE TracedReference() = default; 1891cb0ef41Sopenharmony_ci 1901cb0ef41Sopenharmony_ci /** 1911cb0ef41Sopenharmony_ci * Construct a TracedReference from a Local. 1921cb0ef41Sopenharmony_ci * 1931cb0ef41Sopenharmony_ci * When the Local is non-empty, a new storage cell is created 1941cb0ef41Sopenharmony_ci * pointing to the same object. 1951cb0ef41Sopenharmony_ci */ 1961cb0ef41Sopenharmony_ci template <class S> 1971cb0ef41Sopenharmony_ci TracedReference(Isolate* isolate, Local<S> that) : BasicTracedReference<T>() { 1981cb0ef41Sopenharmony_ci this->slot() = 1991cb0ef41Sopenharmony_ci this->New(isolate, *that, &this->slot(), 2001cb0ef41Sopenharmony_ci internal::GlobalHandleStoreMode::kInitializingStore); 2011cb0ef41Sopenharmony_ci static_assert(std::is_base_of<T, S>::value, "type check"); 2021cb0ef41Sopenharmony_ci } 2031cb0ef41Sopenharmony_ci 2041cb0ef41Sopenharmony_ci /** 2051cb0ef41Sopenharmony_ci * Move constructor initializing TracedReference from an 2061cb0ef41Sopenharmony_ci * existing one. 2071cb0ef41Sopenharmony_ci */ 2081cb0ef41Sopenharmony_ci V8_INLINE TracedReference(TracedReference&& other) noexcept { 2091cb0ef41Sopenharmony_ci // Forward to operator=. 2101cb0ef41Sopenharmony_ci *this = std::move(other); 2111cb0ef41Sopenharmony_ci } 2121cb0ef41Sopenharmony_ci 2131cb0ef41Sopenharmony_ci /** 2141cb0ef41Sopenharmony_ci * Move constructor initializing TracedReference from an 2151cb0ef41Sopenharmony_ci * existing one. 2161cb0ef41Sopenharmony_ci */ 2171cb0ef41Sopenharmony_ci template <typename S> 2181cb0ef41Sopenharmony_ci V8_INLINE TracedReference(TracedReference<S>&& other) noexcept { 2191cb0ef41Sopenharmony_ci // Forward to operator=. 2201cb0ef41Sopenharmony_ci *this = std::move(other); 2211cb0ef41Sopenharmony_ci } 2221cb0ef41Sopenharmony_ci 2231cb0ef41Sopenharmony_ci /** 2241cb0ef41Sopenharmony_ci * Copy constructor initializing TracedReference from an 2251cb0ef41Sopenharmony_ci * existing one. 2261cb0ef41Sopenharmony_ci */ 2271cb0ef41Sopenharmony_ci V8_INLINE TracedReference(const TracedReference& other) { 2281cb0ef41Sopenharmony_ci // Forward to operator=; 2291cb0ef41Sopenharmony_ci *this = other; 2301cb0ef41Sopenharmony_ci } 2311cb0ef41Sopenharmony_ci 2321cb0ef41Sopenharmony_ci /** 2331cb0ef41Sopenharmony_ci * Copy constructor initializing TracedReference from an 2341cb0ef41Sopenharmony_ci * existing one. 2351cb0ef41Sopenharmony_ci */ 2361cb0ef41Sopenharmony_ci template <typename S> 2371cb0ef41Sopenharmony_ci V8_INLINE TracedReference(const TracedReference<S>& other) { 2381cb0ef41Sopenharmony_ci // Forward to operator=; 2391cb0ef41Sopenharmony_ci *this = other; 2401cb0ef41Sopenharmony_ci } 2411cb0ef41Sopenharmony_ci 2421cb0ef41Sopenharmony_ci /** 2431cb0ef41Sopenharmony_ci * Move assignment operator initializing TracedReference from an existing one. 2441cb0ef41Sopenharmony_ci */ 2451cb0ef41Sopenharmony_ci V8_INLINE TracedReference& operator=(TracedReference&& rhs) noexcept; 2461cb0ef41Sopenharmony_ci 2471cb0ef41Sopenharmony_ci /** 2481cb0ef41Sopenharmony_ci * Move assignment operator initializing TracedReference from an existing one. 2491cb0ef41Sopenharmony_ci */ 2501cb0ef41Sopenharmony_ci template <class S> 2511cb0ef41Sopenharmony_ci V8_INLINE TracedReference& operator=(TracedReference<S>&& rhs) noexcept; 2521cb0ef41Sopenharmony_ci 2531cb0ef41Sopenharmony_ci /** 2541cb0ef41Sopenharmony_ci * Copy assignment operator initializing TracedReference from an existing one. 2551cb0ef41Sopenharmony_ci */ 2561cb0ef41Sopenharmony_ci V8_INLINE TracedReference& operator=(const TracedReference& rhs); 2571cb0ef41Sopenharmony_ci 2581cb0ef41Sopenharmony_ci /** 2591cb0ef41Sopenharmony_ci * Copy assignment operator initializing TracedReference from an existing one. 2601cb0ef41Sopenharmony_ci */ 2611cb0ef41Sopenharmony_ci template <class S> 2621cb0ef41Sopenharmony_ci V8_INLINE TracedReference& operator=(const TracedReference<S>& rhs); 2631cb0ef41Sopenharmony_ci 2641cb0ef41Sopenharmony_ci /** 2651cb0ef41Sopenharmony_ci * If non-empty, destroy the underlying storage cell and create a new one with 2661cb0ef41Sopenharmony_ci * the contents of other if other is non empty 2671cb0ef41Sopenharmony_ci */ 2681cb0ef41Sopenharmony_ci template <class S> 2691cb0ef41Sopenharmony_ci V8_INLINE void Reset(Isolate* isolate, const Local<S>& other); 2701cb0ef41Sopenharmony_ci 2711cb0ef41Sopenharmony_ci template <class S> 2721cb0ef41Sopenharmony_ci V8_INLINE TracedReference<S>& As() const { 2731cb0ef41Sopenharmony_ci return reinterpret_cast<TracedReference<S>&>( 2741cb0ef41Sopenharmony_ci const_cast<TracedReference<T>&>(*this)); 2751cb0ef41Sopenharmony_ci } 2761cb0ef41Sopenharmony_ci}; 2771cb0ef41Sopenharmony_ci 2781cb0ef41Sopenharmony_ci// --- Implementation --- 2791cb0ef41Sopenharmony_citemplate <class T> 2801cb0ef41Sopenharmony_ciinternal::Address* BasicTracedReference<T>::New( 2811cb0ef41Sopenharmony_ci Isolate* isolate, T* that, internal::Address** slot, 2821cb0ef41Sopenharmony_ci internal::GlobalHandleStoreMode store_mode) { 2831cb0ef41Sopenharmony_ci if (internal::ValueHelper::IsEmpty(that)) return nullptr; 2841cb0ef41Sopenharmony_ci return internal::GlobalizeTracedReference( 2851cb0ef41Sopenharmony_ci reinterpret_cast<internal::Isolate*>(isolate), 2861cb0ef41Sopenharmony_ci internal::ValueHelper::ValueAsAddress(that), 2871cb0ef41Sopenharmony_ci reinterpret_cast<internal::Address*>(slot), store_mode); 2881cb0ef41Sopenharmony_ci} 2891cb0ef41Sopenharmony_ci 2901cb0ef41Sopenharmony_civoid TracedReferenceBase::Reset() { 2911cb0ef41Sopenharmony_ci if (IsEmpty()) return; 2921cb0ef41Sopenharmony_ci internal::DisposeTracedReference(slot()); 2931cb0ef41Sopenharmony_ci SetSlotThreadSafe(nullptr); 2941cb0ef41Sopenharmony_ci} 2951cb0ef41Sopenharmony_ci 2961cb0ef41Sopenharmony_ciV8_INLINE bool operator==(const TracedReferenceBase& lhs, 2971cb0ef41Sopenharmony_ci const TracedReferenceBase& rhs) { 2981cb0ef41Sopenharmony_ci return internal::HandleHelper::EqualHandles(lhs, rhs); 2991cb0ef41Sopenharmony_ci} 3001cb0ef41Sopenharmony_ci 3011cb0ef41Sopenharmony_citemplate <typename U> 3021cb0ef41Sopenharmony_ciV8_INLINE bool operator==(const TracedReferenceBase& lhs, 3031cb0ef41Sopenharmony_ci const v8::Local<U>& rhs) { 3041cb0ef41Sopenharmony_ci return internal::HandleHelper::EqualHandles(lhs, rhs); 3051cb0ef41Sopenharmony_ci} 3061cb0ef41Sopenharmony_ci 3071cb0ef41Sopenharmony_citemplate <typename U> 3081cb0ef41Sopenharmony_ciV8_INLINE bool operator==(const v8::Local<U>& lhs, 3091cb0ef41Sopenharmony_ci const TracedReferenceBase& rhs) { 3101cb0ef41Sopenharmony_ci return rhs == lhs; 3111cb0ef41Sopenharmony_ci} 3121cb0ef41Sopenharmony_ci 3131cb0ef41Sopenharmony_ciV8_INLINE bool operator!=(const TracedReferenceBase& lhs, 3141cb0ef41Sopenharmony_ci const TracedReferenceBase& rhs) { 3151cb0ef41Sopenharmony_ci return !(lhs == rhs); 3161cb0ef41Sopenharmony_ci} 3171cb0ef41Sopenharmony_ci 3181cb0ef41Sopenharmony_citemplate <typename U> 3191cb0ef41Sopenharmony_ciV8_INLINE bool operator!=(const TracedReferenceBase& lhs, 3201cb0ef41Sopenharmony_ci const v8::Local<U>& rhs) { 3211cb0ef41Sopenharmony_ci return !(lhs == rhs); 3221cb0ef41Sopenharmony_ci} 3231cb0ef41Sopenharmony_ci 3241cb0ef41Sopenharmony_citemplate <typename U> 3251cb0ef41Sopenharmony_ciV8_INLINE bool operator!=(const v8::Local<U>& lhs, 3261cb0ef41Sopenharmony_ci const TracedReferenceBase& rhs) { 3271cb0ef41Sopenharmony_ci return !(rhs == lhs); 3281cb0ef41Sopenharmony_ci} 3291cb0ef41Sopenharmony_ci 3301cb0ef41Sopenharmony_citemplate <class T> 3311cb0ef41Sopenharmony_citemplate <class S> 3321cb0ef41Sopenharmony_civoid TracedReference<T>::Reset(Isolate* isolate, const Local<S>& other) { 3331cb0ef41Sopenharmony_ci static_assert(std::is_base_of<T, S>::value, "type check"); 3341cb0ef41Sopenharmony_ci this->Reset(); 3351cb0ef41Sopenharmony_ci if (other.IsEmpty()) return; 3361cb0ef41Sopenharmony_ci this->SetSlotThreadSafe( 3371cb0ef41Sopenharmony_ci this->New(isolate, *other, &this->slot(), 3381cb0ef41Sopenharmony_ci internal::GlobalHandleStoreMode::kAssigningStore)); 3391cb0ef41Sopenharmony_ci} 3401cb0ef41Sopenharmony_ci 3411cb0ef41Sopenharmony_citemplate <class T> 3421cb0ef41Sopenharmony_citemplate <class S> 3431cb0ef41Sopenharmony_ciTracedReference<T>& TracedReference<T>::operator=( 3441cb0ef41Sopenharmony_ci TracedReference<S>&& rhs) noexcept { 3451cb0ef41Sopenharmony_ci static_assert(std::is_base_of<T, S>::value, "type check"); 3461cb0ef41Sopenharmony_ci *this = std::move(rhs.template As<T>()); 3471cb0ef41Sopenharmony_ci return *this; 3481cb0ef41Sopenharmony_ci} 3491cb0ef41Sopenharmony_ci 3501cb0ef41Sopenharmony_citemplate <class T> 3511cb0ef41Sopenharmony_citemplate <class S> 3521cb0ef41Sopenharmony_ciTracedReference<T>& TracedReference<T>::operator=( 3531cb0ef41Sopenharmony_ci const TracedReference<S>& rhs) { 3541cb0ef41Sopenharmony_ci static_assert(std::is_base_of<T, S>::value, "type check"); 3551cb0ef41Sopenharmony_ci *this = rhs.template As<T>(); 3561cb0ef41Sopenharmony_ci return *this; 3571cb0ef41Sopenharmony_ci} 3581cb0ef41Sopenharmony_ci 3591cb0ef41Sopenharmony_citemplate <class T> 3601cb0ef41Sopenharmony_ciTracedReference<T>& TracedReference<T>::operator=( 3611cb0ef41Sopenharmony_ci TracedReference&& rhs) noexcept { 3621cb0ef41Sopenharmony_ci if (this != &rhs) { 3631cb0ef41Sopenharmony_ci internal::MoveTracedReference(&rhs.slot(), &this->slot()); 3641cb0ef41Sopenharmony_ci } 3651cb0ef41Sopenharmony_ci return *this; 3661cb0ef41Sopenharmony_ci} 3671cb0ef41Sopenharmony_ci 3681cb0ef41Sopenharmony_citemplate <class T> 3691cb0ef41Sopenharmony_ciTracedReference<T>& TracedReference<T>::operator=(const TracedReference& rhs) { 3701cb0ef41Sopenharmony_ci if (this != &rhs) { 3711cb0ef41Sopenharmony_ci this->Reset(); 3721cb0ef41Sopenharmony_ci if (!rhs.IsEmpty()) { 3731cb0ef41Sopenharmony_ci internal::CopyTracedReference(&rhs.slot(), &this->slot()); 3741cb0ef41Sopenharmony_ci } 3751cb0ef41Sopenharmony_ci } 3761cb0ef41Sopenharmony_ci return *this; 3771cb0ef41Sopenharmony_ci} 3781cb0ef41Sopenharmony_ci 3791cb0ef41Sopenharmony_civoid TracedReferenceBase::SetWrapperClassId(uint16_t class_id) { 3801cb0ef41Sopenharmony_ci using I = internal::Internals; 3811cb0ef41Sopenharmony_ci if (IsEmpty()) return; 3821cb0ef41Sopenharmony_ci uint8_t* addr = 3831cb0ef41Sopenharmony_ci reinterpret_cast<uint8_t*>(slot()) + I::kTracedNodeClassIdOffset; 3841cb0ef41Sopenharmony_ci *reinterpret_cast<uint16_t*>(addr) = class_id; 3851cb0ef41Sopenharmony_ci} 3861cb0ef41Sopenharmony_ci 3871cb0ef41Sopenharmony_ciuint16_t TracedReferenceBase::WrapperClassId() const { 3881cb0ef41Sopenharmony_ci using I = internal::Internals; 3891cb0ef41Sopenharmony_ci if (IsEmpty()) return 0; 3901cb0ef41Sopenharmony_ci uint8_t* addr = 3911cb0ef41Sopenharmony_ci reinterpret_cast<uint8_t*>(slot()) + I::kTracedNodeClassIdOffset; 3921cb0ef41Sopenharmony_ci return *reinterpret_cast<uint16_t*>(addr); 3931cb0ef41Sopenharmony_ci} 3941cb0ef41Sopenharmony_ci 3951cb0ef41Sopenharmony_ci} // namespace v8 3961cb0ef41Sopenharmony_ci 3971cb0ef41Sopenharmony_ci#endif // INCLUDE_V8_TRACED_HANDLE_H_ 398