11cb0ef41Sopenharmony_ci// Copyright Joyent, Inc. and other Node contributors.
21cb0ef41Sopenharmony_ci//
31cb0ef41Sopenharmony_ci// Permission is hereby granted, free of charge, to any person obtaining a
41cb0ef41Sopenharmony_ci// copy of this software and associated documentation files (the
51cb0ef41Sopenharmony_ci// "Software"), to deal in the Software without restriction, including
61cb0ef41Sopenharmony_ci// without limitation the rights to use, copy, modify, merge, publish,
71cb0ef41Sopenharmony_ci// distribute, sublicense, and/or sell copies of the Software, and to permit
81cb0ef41Sopenharmony_ci// persons to whom the Software is furnished to do so, subject to the
91cb0ef41Sopenharmony_ci// following conditions:
101cb0ef41Sopenharmony_ci//
111cb0ef41Sopenharmony_ci// The above copyright notice and this permission notice shall be included
121cb0ef41Sopenharmony_ci// in all copies or substantial portions of the Software.
131cb0ef41Sopenharmony_ci//
141cb0ef41Sopenharmony_ci// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
151cb0ef41Sopenharmony_ci// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
161cb0ef41Sopenharmony_ci// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
171cb0ef41Sopenharmony_ci// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
181cb0ef41Sopenharmony_ci// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
191cb0ef41Sopenharmony_ci// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
201cb0ef41Sopenharmony_ci// USE OR OTHER DEALINGS IN THE SOFTWARE.
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci#ifndef SRC_BASE_OBJECT_H_
231cb0ef41Sopenharmony_ci#define SRC_BASE_OBJECT_H_
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_ci#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_ci#include <type_traits>  // std::remove_reference
281cb0ef41Sopenharmony_ci#include "base_object_types.h"
291cb0ef41Sopenharmony_ci#include "memory_tracker.h"
301cb0ef41Sopenharmony_ci#include "v8.h"
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_cinamespace node {
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ciclass Environment;
351cb0ef41Sopenharmony_ciclass IsolateData;
361cb0ef41Sopenharmony_ciclass Realm;
371cb0ef41Sopenharmony_citemplate <typename T, bool kIsWeak>
381cb0ef41Sopenharmony_ciclass BaseObjectPtrImpl;
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_cinamespace worker {
411cb0ef41Sopenharmony_ciclass TransferData;
421cb0ef41Sopenharmony_ci}
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ciextern uint16_t kNodeEmbedderId;
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ciclass BaseObject : public MemoryRetainer {
471cb0ef41Sopenharmony_ci public:
481cb0ef41Sopenharmony_ci  enum InternalFields { kEmbedderType, kSlot, kInternalFieldCount };
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ci  // Associates this object with `object`. It uses the 1st internal field for
511cb0ef41Sopenharmony_ci  // that, and in particular aborts if there is no such field.
521cb0ef41Sopenharmony_ci  // This is the designated constructor.
531cb0ef41Sopenharmony_ci  BaseObject(Realm* realm, v8::Local<v8::Object> object);
541cb0ef41Sopenharmony_ci  // Convenient constructor for constructing BaseObject in the principal realm.
551cb0ef41Sopenharmony_ci  inline BaseObject(Environment* env, v8::Local<v8::Object> object);
561cb0ef41Sopenharmony_ci  ~BaseObject() override;
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ci  BaseObject() = delete;
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci  // Returns the wrapped object.  Returns an empty handle when
611cb0ef41Sopenharmony_ci  // persistent.IsEmpty() is true.
621cb0ef41Sopenharmony_ci  inline v8::Local<v8::Object> object() const;
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci  // Same as the above, except it additionally verifies that this object
651cb0ef41Sopenharmony_ci  // is associated with the passed Isolate in debug mode.
661cb0ef41Sopenharmony_ci  inline v8::Local<v8::Object> object(v8::Isolate* isolate) const;
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_ci  inline v8::Global<v8::Object>& persistent();
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_ci  inline Environment* env() const;
711cb0ef41Sopenharmony_ci  inline Realm* realm() const;
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ci  // Get a BaseObject* pointer, or subclass pointer, for the JS object that
741cb0ef41Sopenharmony_ci  // was also passed to the `BaseObject()` constructor initially.
751cb0ef41Sopenharmony_ci  // This may return `nullptr` if the C++ object has not been constructed yet,
761cb0ef41Sopenharmony_ci  // e.g. when the JS object used `MakeLazilyInitializedJSTemplate`.
771cb0ef41Sopenharmony_ci  static inline void SetInternalFields(v8::Local<v8::Object> object,
781cb0ef41Sopenharmony_ci                                       void* slot);
791cb0ef41Sopenharmony_ci  static inline void TagNodeObject(v8::Local<v8::Object> object);
801cb0ef41Sopenharmony_ci  static void LazilyInitializedJSTemplateConstructor(
811cb0ef41Sopenharmony_ci      const v8::FunctionCallbackInfo<v8::Value>& args);
821cb0ef41Sopenharmony_ci  static inline BaseObject* FromJSObject(v8::Local<v8::Value> object);
831cb0ef41Sopenharmony_ci  template <typename T>
841cb0ef41Sopenharmony_ci  static inline T* FromJSObject(v8::Local<v8::Value> object);
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_ci  // Make the `v8::Global` a weak reference and, `delete` this object once
871cb0ef41Sopenharmony_ci  // the JS object has been garbage collected and there are no (strong)
881cb0ef41Sopenharmony_ci  // BaseObjectPtr references to it.
891cb0ef41Sopenharmony_ci  void MakeWeak();
901cb0ef41Sopenharmony_ci
911cb0ef41Sopenharmony_ci  // Undo `MakeWeak()`, i.e. turn this into a strong reference that is a GC
921cb0ef41Sopenharmony_ci  // root and will not be touched by the garbage collector.
931cb0ef41Sopenharmony_ci  inline void ClearWeak();
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci  // Reports whether this BaseObject is using a weak reference or detached,
961cb0ef41Sopenharmony_ci  // i.e. whether is can be deleted by GC once no strong BaseObjectPtrs refer
971cb0ef41Sopenharmony_ci  // to it anymore.
981cb0ef41Sopenharmony_ci  inline bool IsWeakOrDetached() const;
991cb0ef41Sopenharmony_ci
1001cb0ef41Sopenharmony_ci  inline v8::EmbedderGraph::Node::Detachedness GetDetachedness() const override;
1011cb0ef41Sopenharmony_ci
1021cb0ef41Sopenharmony_ci  // Utility to create a FunctionTemplate with one internal field (used for
1031cb0ef41Sopenharmony_ci  // the `BaseObject*` pointer) and a constructor that initializes that field
1041cb0ef41Sopenharmony_ci  // to `nullptr`.
1051cb0ef41Sopenharmony_ci  static v8::Local<v8::FunctionTemplate> MakeLazilyInitializedJSTemplate(
1061cb0ef41Sopenharmony_ci      IsolateData* isolate);
1071cb0ef41Sopenharmony_ci  static v8::Local<v8::FunctionTemplate> MakeLazilyInitializedJSTemplate(
1081cb0ef41Sopenharmony_ci      Environment* env);
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci  // Setter/Getter pair for internal fields that can be passed to SetAccessor.
1111cb0ef41Sopenharmony_ci  template <int Field>
1121cb0ef41Sopenharmony_ci  static void InternalFieldGet(v8::Local<v8::String> property,
1131cb0ef41Sopenharmony_ci                               const v8::PropertyCallbackInfo<v8::Value>& info);
1141cb0ef41Sopenharmony_ci  template <int Field, bool (v8::Value::*typecheck)() const>
1151cb0ef41Sopenharmony_ci  static void InternalFieldSet(v8::Local<v8::String> property,
1161cb0ef41Sopenharmony_ci                               v8::Local<v8::Value> value,
1171cb0ef41Sopenharmony_ci                               const v8::PropertyCallbackInfo<void>& info);
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_ci  // This is a bit of a hack. See the override in async_wrap.cc for details.
1201cb0ef41Sopenharmony_ci  virtual bool IsDoneInitializing() const;
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ci  // Can be used to avoid this object keeping itself alive as a GC root
1231cb0ef41Sopenharmony_ci  // indefinitely, for example when this object is owned and deleted by another
1241cb0ef41Sopenharmony_ci  // BaseObject once that is torn down. This can only be called when there is
1251cb0ef41Sopenharmony_ci  // a BaseObjectPtr to this object.
1261cb0ef41Sopenharmony_ci  inline void Detach();
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_ci  static inline v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
1291cb0ef41Sopenharmony_ci      Environment* env);
1301cb0ef41Sopenharmony_ci  static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
1311cb0ef41Sopenharmony_ci      IsolateData* isolate_data);
1321cb0ef41Sopenharmony_ci
1331cb0ef41Sopenharmony_ci  // Interface for transferring BaseObject instances using the .postMessage()
1341cb0ef41Sopenharmony_ci  // method of MessagePorts (and, by extension, Workers).
1351cb0ef41Sopenharmony_ci  // GetTransferMode() returns a transfer mode that indicates how to deal with
1361cb0ef41Sopenharmony_ci  // the current object:
1371cb0ef41Sopenharmony_ci  // - kUntransferable:
1381cb0ef41Sopenharmony_ci  //     No transfer is possible, either because this type of BaseObject does
1391cb0ef41Sopenharmony_ci  //     not know how to be transferred, or because it is not in a state in
1401cb0ef41Sopenharmony_ci  //     which it is possible to do so (e.g. because it has already been
1411cb0ef41Sopenharmony_ci  //     transferred).
1421cb0ef41Sopenharmony_ci  // - kTransferable:
1431cb0ef41Sopenharmony_ci  //     This object can be transferred in a destructive fashion, i.e. will be
1441cb0ef41Sopenharmony_ci  //     rendered unusable on the sending side of the channel in the process
1451cb0ef41Sopenharmony_ci  //     of being transferred. (In C++ this would be referred to as movable but
1461cb0ef41Sopenharmony_ci  //     not copyable.) Objects of this type need to be listed in the
1471cb0ef41Sopenharmony_ci  //     `transferList` argument of the relevant postMessage() call in order to
1481cb0ef41Sopenharmony_ci  //     make sure that they are not accidentally destroyed on the sending side.
1491cb0ef41Sopenharmony_ci  //     TransferForMessaging() will be called to get a representation of the
1501cb0ef41Sopenharmony_ci  //     object that is used for subsequent deserialization.
1511cb0ef41Sopenharmony_ci  //     The NestedTransferables() method can be used to transfer other objects
1521cb0ef41Sopenharmony_ci  //     along with this one, if a situation requires it.
1531cb0ef41Sopenharmony_ci  // - kCloneable:
1541cb0ef41Sopenharmony_ci  //     This object can be cloned without being modified.
1551cb0ef41Sopenharmony_ci  //     CloneForMessaging() will be called to get a representation of the
1561cb0ef41Sopenharmony_ci  //     object that is used for subsequent deserialization, unless the
1571cb0ef41Sopenharmony_ci  //     object is listed in transferList, in which case TransferForMessaging()
1581cb0ef41Sopenharmony_ci  //     is attempted first.
1591cb0ef41Sopenharmony_ci  // After a successful clone, FinalizeTransferRead() is called on the receiving
1601cb0ef41Sopenharmony_ci  // end, and can read deserialize JS data possibly serialized by a previous
1611cb0ef41Sopenharmony_ci  // FinalizeTransferWrite() call.
1621cb0ef41Sopenharmony_ci  enum class TransferMode {
1631cb0ef41Sopenharmony_ci    kUntransferable,
1641cb0ef41Sopenharmony_ci    kTransferable,
1651cb0ef41Sopenharmony_ci    kCloneable
1661cb0ef41Sopenharmony_ci  };
1671cb0ef41Sopenharmony_ci  virtual TransferMode GetTransferMode() const;
1681cb0ef41Sopenharmony_ci  virtual std::unique_ptr<worker::TransferData> TransferForMessaging();
1691cb0ef41Sopenharmony_ci  virtual std::unique_ptr<worker::TransferData> CloneForMessaging() const;
1701cb0ef41Sopenharmony_ci  virtual v8::Maybe<std::vector<BaseObjectPtrImpl<BaseObject, false>>>
1711cb0ef41Sopenharmony_ci      NestedTransferables() const;
1721cb0ef41Sopenharmony_ci  virtual v8::Maybe<bool> FinalizeTransferRead(
1731cb0ef41Sopenharmony_ci      v8::Local<v8::Context> context, v8::ValueDeserializer* deserializer);
1741cb0ef41Sopenharmony_ci
1751cb0ef41Sopenharmony_ci  // Indicates whether this object is expected to use a strong reference during
1761cb0ef41Sopenharmony_ci  // a clean process exit (due to an empty event loop).
1771cb0ef41Sopenharmony_ci  virtual bool IsNotIndicativeOfMemoryLeakAtExit() const;
1781cb0ef41Sopenharmony_ci
1791cb0ef41Sopenharmony_ci  virtual inline void OnGCCollect();
1801cb0ef41Sopenharmony_ci
1811cb0ef41Sopenharmony_ci  virtual inline bool is_snapshotable() const { return false; }
1821cb0ef41Sopenharmony_ci
1831cb0ef41Sopenharmony_ci private:
1841cb0ef41Sopenharmony_ci  v8::Local<v8::Object> WrappedObject() const override;
1851cb0ef41Sopenharmony_ci  bool IsRootNode() const override;
1861cb0ef41Sopenharmony_ci  static void DeleteMe(void* data);
1871cb0ef41Sopenharmony_ci
1881cb0ef41Sopenharmony_ci  // persistent_handle_ needs to be at a fixed offset from the start of the
1891cb0ef41Sopenharmony_ci  // class because it is used by src/node_postmortem_metadata.cc to calculate
1901cb0ef41Sopenharmony_ci  // offsets and generate debug symbols for BaseObject, which assumes that the
1911cb0ef41Sopenharmony_ci  // position of members in memory are predictable. For more information please
1921cb0ef41Sopenharmony_ci  // refer to `doc/contributing/node-postmortem-support.md`
1931cb0ef41Sopenharmony_ci  friend int GenDebugSymbols();
1941cb0ef41Sopenharmony_ci  friend class CleanupQueue;
1951cb0ef41Sopenharmony_ci  template <typename T, bool kIsWeak>
1961cb0ef41Sopenharmony_ci  friend class BaseObjectPtrImpl;
1971cb0ef41Sopenharmony_ci
1981cb0ef41Sopenharmony_ci  v8::Global<v8::Object> persistent_handle_;
1991cb0ef41Sopenharmony_ci
2001cb0ef41Sopenharmony_ci  // Metadata that is associated with this BaseObject if there are BaseObjectPtr
2011cb0ef41Sopenharmony_ci  // or BaseObjectWeakPtr references to it.
2021cb0ef41Sopenharmony_ci  // This object is deleted when the BaseObject itself is destroyed, and there
2031cb0ef41Sopenharmony_ci  // are no weak references to it.
2041cb0ef41Sopenharmony_ci  struct PointerData {
2051cb0ef41Sopenharmony_ci    // Number of BaseObjectPtr instances that refer to this object. If this
2061cb0ef41Sopenharmony_ci    // is non-zero, the BaseObject is always a GC root and will not be destroyed
2071cb0ef41Sopenharmony_ci    // during cleanup until the count drops to zero again.
2081cb0ef41Sopenharmony_ci    unsigned int strong_ptr_count = 0;
2091cb0ef41Sopenharmony_ci    // Number of BaseObjectWeakPtr instances that refer to this object.
2101cb0ef41Sopenharmony_ci    unsigned int weak_ptr_count = 0;
2111cb0ef41Sopenharmony_ci    // Indicates whether MakeWeak() has been called.
2121cb0ef41Sopenharmony_ci    bool wants_weak_jsobj = false;
2131cb0ef41Sopenharmony_ci    // Indicates whether Detach() has been called. If that is the case, this
2141cb0ef41Sopenharmony_ci    // object will be destroyed once the strong pointer count drops to zero.
2151cb0ef41Sopenharmony_ci    bool is_detached = false;
2161cb0ef41Sopenharmony_ci    // Reference to the original BaseObject. This is used by weak pointers.
2171cb0ef41Sopenharmony_ci    BaseObject* self = nullptr;
2181cb0ef41Sopenharmony_ci  };
2191cb0ef41Sopenharmony_ci
2201cb0ef41Sopenharmony_ci  inline bool has_pointer_data() const;
2211cb0ef41Sopenharmony_ci  // This creates a PointerData struct if none was associated with this
2221cb0ef41Sopenharmony_ci  // BaseObject before.
2231cb0ef41Sopenharmony_ci  PointerData* pointer_data();
2241cb0ef41Sopenharmony_ci
2251cb0ef41Sopenharmony_ci  // Functions that adjust the strong pointer count.
2261cb0ef41Sopenharmony_ci  void decrease_refcount();
2271cb0ef41Sopenharmony_ci  void increase_refcount();
2281cb0ef41Sopenharmony_ci
2291cb0ef41Sopenharmony_ci  Realm* realm_;
2301cb0ef41Sopenharmony_ci  PointerData* pointer_data_ = nullptr;
2311cb0ef41Sopenharmony_ci};
2321cb0ef41Sopenharmony_ci
2331cb0ef41Sopenharmony_ci// Global alias for FromJSObject() to avoid churn.
2341cb0ef41Sopenharmony_citemplate <typename T>
2351cb0ef41Sopenharmony_ciinline T* Unwrap(v8::Local<v8::Value> obj) {
2361cb0ef41Sopenharmony_ci  return BaseObject::FromJSObject<T>(obj);
2371cb0ef41Sopenharmony_ci}
2381cb0ef41Sopenharmony_ci
2391cb0ef41Sopenharmony_ci#define ASSIGN_OR_RETURN_UNWRAP(ptr, obj, ...)                                 \
2401cb0ef41Sopenharmony_ci  do {                                                                         \
2411cb0ef41Sopenharmony_ci    *ptr = static_cast<typename std::remove_reference<decltype(*ptr)>::type>(  \
2421cb0ef41Sopenharmony_ci        BaseObject::FromJSObject(obj));                                        \
2431cb0ef41Sopenharmony_ci    if (*ptr == nullptr) return __VA_ARGS__;                                   \
2441cb0ef41Sopenharmony_ci  } while (0)
2451cb0ef41Sopenharmony_ci
2461cb0ef41Sopenharmony_ci// Implementation of a generic strong or weak pointer to a BaseObject.
2471cb0ef41Sopenharmony_ci// If strong, this will keep the target BaseObject alive regardless of other
2481cb0ef41Sopenharmony_ci// circumstances such as the GC or Environment cleanup.
2491cb0ef41Sopenharmony_ci// If weak, destruction behaviour is not affected, but the pointer will be
2501cb0ef41Sopenharmony_ci// reset to nullptr once the BaseObject is destroyed.
2511cb0ef41Sopenharmony_ci// The API matches std::shared_ptr closely. However, this class is not thread
2521cb0ef41Sopenharmony_ci// safe, that is, we can't have different BaseObjectPtrImpl instances in
2531cb0ef41Sopenharmony_ci// different threads referring to the same BaseObject instance.
2541cb0ef41Sopenharmony_citemplate <typename T, bool kIsWeak>
2551cb0ef41Sopenharmony_ciclass BaseObjectPtrImpl final {
2561cb0ef41Sopenharmony_ci public:
2571cb0ef41Sopenharmony_ci  inline BaseObjectPtrImpl();
2581cb0ef41Sopenharmony_ci  inline ~BaseObjectPtrImpl();
2591cb0ef41Sopenharmony_ci  inline explicit BaseObjectPtrImpl(T* target);
2601cb0ef41Sopenharmony_ci
2611cb0ef41Sopenharmony_ci  // Copy and move constructors. Note that the templated version is not a copy
2621cb0ef41Sopenharmony_ci  // or move constructor in the C++ sense of the word, so an identical
2631cb0ef41Sopenharmony_ci  // untemplated version is provided.
2641cb0ef41Sopenharmony_ci  template <typename U, bool kW>
2651cb0ef41Sopenharmony_ci  inline BaseObjectPtrImpl(const BaseObjectPtrImpl<U, kW>& other);
2661cb0ef41Sopenharmony_ci  inline BaseObjectPtrImpl(const BaseObjectPtrImpl& other);
2671cb0ef41Sopenharmony_ci  template <typename U, bool kW>
2681cb0ef41Sopenharmony_ci  inline BaseObjectPtrImpl& operator=(const BaseObjectPtrImpl<U, kW>& other);
2691cb0ef41Sopenharmony_ci  inline BaseObjectPtrImpl& operator=(const BaseObjectPtrImpl& other);
2701cb0ef41Sopenharmony_ci  inline BaseObjectPtrImpl(BaseObjectPtrImpl&& other);
2711cb0ef41Sopenharmony_ci  inline BaseObjectPtrImpl& operator=(BaseObjectPtrImpl&& other);
2721cb0ef41Sopenharmony_ci
2731cb0ef41Sopenharmony_ci  inline void reset(T* ptr = nullptr);
2741cb0ef41Sopenharmony_ci  inline T* get() const;
2751cb0ef41Sopenharmony_ci  inline T& operator*() const;
2761cb0ef41Sopenharmony_ci  inline T* operator->() const;
2771cb0ef41Sopenharmony_ci  inline operator bool() const;
2781cb0ef41Sopenharmony_ci
2791cb0ef41Sopenharmony_ci  template <typename U, bool kW>
2801cb0ef41Sopenharmony_ci  inline bool operator ==(const BaseObjectPtrImpl<U, kW>& other) const;
2811cb0ef41Sopenharmony_ci  template <typename U, bool kW>
2821cb0ef41Sopenharmony_ci  inline bool operator !=(const BaseObjectPtrImpl<U, kW>& other) const;
2831cb0ef41Sopenharmony_ci
2841cb0ef41Sopenharmony_ci private:
2851cb0ef41Sopenharmony_ci  union {
2861cb0ef41Sopenharmony_ci    BaseObject* target;                     // Used for strong pointers.
2871cb0ef41Sopenharmony_ci    BaseObject::PointerData* pointer_data;  // Used for weak pointers.
2881cb0ef41Sopenharmony_ci  } data_;
2891cb0ef41Sopenharmony_ci
2901cb0ef41Sopenharmony_ci  inline BaseObject* get_base_object() const;
2911cb0ef41Sopenharmony_ci  inline BaseObject::PointerData* pointer_data() const;
2921cb0ef41Sopenharmony_ci};
2931cb0ef41Sopenharmony_ci
2941cb0ef41Sopenharmony_citemplate <typename T>
2951cb0ef41Sopenharmony_ciusing BaseObjectPtr = BaseObjectPtrImpl<T, false>;
2961cb0ef41Sopenharmony_citemplate <typename T>
2971cb0ef41Sopenharmony_ciusing BaseObjectWeakPtr = BaseObjectPtrImpl<T, true>;
2981cb0ef41Sopenharmony_ci
2991cb0ef41Sopenharmony_ci// Create a BaseObject instance and return a pointer to it.
3001cb0ef41Sopenharmony_ci// This variant leaves the object as a GC root by default.
3011cb0ef41Sopenharmony_citemplate <typename T, typename... Args>
3021cb0ef41Sopenharmony_ciinline BaseObjectPtr<T> MakeBaseObject(Args&&... args);
3031cb0ef41Sopenharmony_ci// Create a BaseObject instance and return a pointer to it.
3041cb0ef41Sopenharmony_ci// This variant detaches the object by default, meaning that the caller fully
3051cb0ef41Sopenharmony_ci// owns it, and once the last BaseObjectPtr to it is destroyed, the object
3061cb0ef41Sopenharmony_ci// itself is also destroyed.
3071cb0ef41Sopenharmony_citemplate <typename T, typename... Args>
3081cb0ef41Sopenharmony_ciinline BaseObjectPtr<T> MakeDetachedBaseObject(Args&&... args);
3091cb0ef41Sopenharmony_ci
3101cb0ef41Sopenharmony_ci}  // namespace node
3111cb0ef41Sopenharmony_ci
3121cb0ef41Sopenharmony_ci#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
3131cb0ef41Sopenharmony_ci
3141cb0ef41Sopenharmony_ci#endif  // SRC_BASE_OBJECT_H_
315