File indexing completed on 2025-02-21 10:05:25
0001
0002
0003
0004
0005 #ifndef INCLUDE_V8_PERSISTENT_HANDLE_H_
0006 #define INCLUDE_V8_PERSISTENT_HANDLE_H_
0007
0008 #include "v8-internal.h" // NOLINT(build/include_directory)
0009 #include "v8-local-handle.h" // NOLINT(build/include_directory)
0010 #include "v8-weak-callback-info.h" // NOLINT(build/include_directory)
0011 #include "v8config.h" // NOLINT(build/include_directory)
0012
0013 namespace v8 {
0014
0015 class Isolate;
0016 template <class K, class V, class T>
0017 class PersistentValueMapBase;
0018 template <class V, class T>
0019 class PersistentValueVector;
0020 template <class T>
0021 class Global;
0022 template <class T>
0023 class PersistentBase;
0024 template <class K, class V, class T>
0025 class PersistentValueMap;
0026 class Value;
0027
0028 namespace api_internal {
0029 V8_EXPORT internal::Address* Eternalize(v8::Isolate* isolate, Value* handle);
0030 V8_EXPORT internal::Address* CopyGlobalReference(internal::Address* from);
0031 V8_EXPORT void DisposeGlobal(internal::Address* global_handle);
0032 V8_EXPORT void MakeWeak(internal::Address** location_addr);
0033 V8_EXPORT void* ClearWeak(internal::Address* location);
0034 V8_EXPORT void AnnotateStrongRetainer(internal::Address* location,
0035 const char* label);
0036 V8_EXPORT internal::Address* GlobalizeReference(internal::Isolate* isolate,
0037 internal::Address value);
0038 V8_EXPORT void MoveGlobalReference(internal::Address** from,
0039 internal::Address** to);
0040 }
0041
0042
0043
0044
0045
0046 template <class T>
0047 class Eternal : public api_internal::IndirectHandleBase {
0048 public:
0049 V8_INLINE Eternal() = default;
0050
0051 template <class S>
0052 V8_INLINE Eternal(Isolate* isolate, Local<S> handle) {
0053 Set(isolate, handle);
0054 }
0055
0056
0057 V8_INLINE Local<T> Get(Isolate* isolate) const {
0058
0059
0060 return Local<T>::FromSlot(slot());
0061 }
0062
0063 template <class S>
0064 void Set(Isolate* isolate, Local<S> handle) {
0065 static_assert(std::is_base_of<T, S>::value, "type check");
0066 slot() =
0067 api_internal::Eternalize(isolate, *handle.template UnsafeAs<Value>());
0068 }
0069 };
0070
0071 namespace api_internal {
0072 V8_EXPORT void MakeWeak(internal::Address* location, void* data,
0073 WeakCallbackInfo<void>::Callback weak_callback,
0074 WeakCallbackType type);
0075 }
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090 template <class T>
0091 class PersistentBase : public api_internal::IndirectHandleBase {
0092 public:
0093
0094
0095
0096
0097 V8_INLINE void Reset();
0098
0099
0100
0101
0102
0103 template <class S>
0104 V8_INLINE void Reset(Isolate* isolate, const Local<S>& other);
0105
0106
0107
0108
0109
0110 template <class S>
0111 V8_INLINE void Reset(Isolate* isolate, const PersistentBase<S>& other);
0112
0113 V8_INLINE Local<T> Get(Isolate* isolate) const {
0114 return Local<T>::New(isolate, *this);
0115 }
0116
0117 template <class S>
0118 V8_INLINE bool operator==(const PersistentBase<S>& that) const {
0119 return internal::HandleHelper::EqualHandles(*this, that);
0120 }
0121
0122 template <class S>
0123 V8_INLINE bool operator==(const Local<S>& that) const {
0124 return internal::HandleHelper::EqualHandles(*this, that);
0125 }
0126
0127 template <class S>
0128 V8_INLINE bool operator!=(const PersistentBase<S>& that) const {
0129 return !operator==(that);
0130 }
0131
0132 template <class S>
0133 V8_INLINE bool operator!=(const Local<S>& that) const {
0134 return !operator==(that);
0135 }
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149 template <typename P>
0150 V8_INLINE void SetWeak(P* parameter,
0151 typename WeakCallbackInfo<P>::Callback callback,
0152 WeakCallbackType type);
0153
0154
0155
0156
0157
0158
0159 V8_INLINE void SetWeak();
0160
0161 template <typename P>
0162 V8_INLINE P* ClearWeak();
0163
0164
0165 V8_INLINE void ClearWeak() { ClearWeak<void>(); }
0166
0167
0168
0169
0170
0171
0172
0173 V8_INLINE void AnnotateStrongRetainer(const char* label);
0174
0175
0176 V8_INLINE bool IsWeak() const;
0177
0178
0179
0180
0181 V8_INLINE void SetWrapperClassId(uint16_t class_id);
0182
0183
0184
0185
0186
0187 V8_INLINE uint16_t WrapperClassId() const;
0188
0189 PersistentBase(const PersistentBase& other) = delete;
0190 void operator=(const PersistentBase&) = delete;
0191
0192 private:
0193 friend class Isolate;
0194 friend class Utils;
0195 template <class F>
0196 friend class Local;
0197 template <class F1, class F2>
0198 friend class Persistent;
0199 template <class F>
0200 friend class Global;
0201 template <class F>
0202 friend class PersistentBase;
0203 template <class F>
0204 friend class ReturnValue;
0205 template <class F1, class F2, class F3>
0206 friend class PersistentValueMapBase;
0207 template <class F1, class F2>
0208 friend class PersistentValueVector;
0209 friend class Object;
0210 friend class internal::ValueHelper;
0211
0212 V8_INLINE PersistentBase() = default;
0213
0214 V8_INLINE explicit PersistentBase(internal::Address* location)
0215 : IndirectHandleBase(location) {}
0216
0217 V8_INLINE static internal::Address* New(Isolate* isolate, T* that);
0218 };
0219
0220
0221
0222
0223
0224
0225
0226 template <class T>
0227 class NonCopyablePersistentTraits {
0228 public:
0229 using NonCopyablePersistent = Persistent<T, NonCopyablePersistentTraits<T>>;
0230 static const bool kResetInDestructor = false;
0231 template <class S, class M>
0232 V8_INLINE static void Copy(const Persistent<S, M>& source,
0233 NonCopyablePersistent* dest) {
0234 static_assert(sizeof(S) < 0,
0235 "NonCopyablePersistentTraits::Copy is not instantiable");
0236 }
0237 };
0238
0239
0240
0241
0242
0243 template <class T>
0244 struct CopyablePersistentTraits {
0245 using CopyablePersistent = Persistent<T, CopyablePersistentTraits<T>>;
0246 static const bool kResetInDestructor = true;
0247 template <class S, class M>
0248 static V8_INLINE void Copy(const Persistent<S, M>& source,
0249 CopyablePersistent* dest) {
0250
0251 }
0252 };
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264 template <class T, class M>
0265 class Persistent : public PersistentBase<T> {
0266 public:
0267
0268
0269
0270 V8_INLINE Persistent() = default;
0271
0272
0273
0274
0275
0276
0277 template <class S>
0278 V8_INLINE Persistent(Isolate* isolate, Local<S> that)
0279 : PersistentBase<T>(
0280 PersistentBase<T>::New(isolate, that.template value<S>())) {
0281 static_assert(std::is_base_of<T, S>::value, "type check");
0282 }
0283
0284
0285
0286
0287
0288
0289 template <class S, class M2>
0290 V8_INLINE Persistent(Isolate* isolate, const Persistent<S, M2>& that)
0291 : PersistentBase<T>(
0292 PersistentBase<T>::New(isolate, that.template value<S>())) {
0293 static_assert(std::is_base_of<T, S>::value, "type check");
0294 }
0295
0296
0297
0298
0299
0300
0301
0302 V8_INLINE Persistent(const Persistent& that) : PersistentBase<T>() {
0303 Copy(that);
0304 }
0305 template <class S, class M2>
0306 V8_INLINE Persistent(const Persistent<S, M2>& that) : PersistentBase<T>() {
0307 Copy(that);
0308 }
0309 V8_INLINE Persistent& operator=(const Persistent& that) {
0310 Copy(that);
0311 return *this;
0312 }
0313 template <class S, class M2>
0314 V8_INLINE Persistent& operator=(const Persistent<S, M2>& that) {
0315 Copy(that);
0316 return *this;
0317 }
0318
0319
0320
0321
0322
0323
0324 V8_INLINE ~Persistent() {
0325 if (M::kResetInDestructor) this->Reset();
0326 }
0327
0328
0329 template <class S, class M2>
0330 V8_INLINE static Persistent<T, M>& Cast(const Persistent<S, M2>& that) {
0331 #ifdef V8_ENABLE_CHECKS
0332
0333
0334 if (!that.IsEmpty()) T::Cast(that.template value<S>());
0335 #endif
0336 return reinterpret_cast<Persistent<T, M>&>(
0337 const_cast<Persistent<S, M2>&>(that));
0338 }
0339
0340
0341 template <class S, class M2>
0342 V8_INLINE Persistent<S, M2>& As() const {
0343 return Persistent<S, M2>::Cast(*this);
0344 }
0345
0346 private:
0347 friend class Isolate;
0348 friend class Utils;
0349 template <class F>
0350 friend class Local;
0351 template <class F1, class F2>
0352 friend class Persistent;
0353 template <class F>
0354 friend class ReturnValue;
0355
0356 template <class S, class M2>
0357 V8_INLINE void Copy(const Persistent<S, M2>& that);
0358 };
0359
0360
0361
0362
0363
0364
0365 template <class T>
0366 class Global : public PersistentBase<T> {
0367 public:
0368
0369
0370
0371 V8_INLINE Global() = default;
0372
0373
0374
0375
0376
0377
0378 template <class S>
0379 V8_INLINE Global(Isolate* isolate, Local<S> that)
0380 : PersistentBase<T>(
0381 PersistentBase<T>::New(isolate, that.template value<S>())) {
0382 static_assert(std::is_base_of<T, S>::value, "type check");
0383 }
0384
0385
0386
0387
0388
0389
0390 template <class S>
0391 V8_INLINE Global(Isolate* isolate, const PersistentBase<S>& that)
0392 : PersistentBase<T>(
0393 PersistentBase<T>::New(isolate, that.template value<S>())) {
0394 static_assert(std::is_base_of<T, S>::value, "type check");
0395 }
0396
0397
0398
0399
0400 V8_INLINE Global(Global&& other);
0401
0402 V8_INLINE ~Global() { this->Reset(); }
0403
0404
0405
0406
0407 template <class S>
0408 V8_INLINE Global& operator=(Global<S>&& rhs);
0409
0410
0411
0412
0413 Global Pass() { return static_cast<Global&&>(*this); }
0414
0415
0416
0417
0418 using MoveOnlyTypeForCPP03 = void;
0419
0420 Global(const Global&) = delete;
0421 void operator=(const Global&) = delete;
0422
0423 private:
0424 template <class F>
0425 friend class ReturnValue;
0426 };
0427
0428
0429 template <class T>
0430 using UniquePersistent = Global<T>;
0431
0432
0433
0434
0435 class V8_EXPORT PersistentHandleVisitor {
0436 public:
0437 virtual ~PersistentHandleVisitor() = default;
0438 virtual void VisitPersistentHandle(Persistent<Value>* value,
0439 uint16_t class_id) {}
0440 };
0441
0442 template <class T>
0443 internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
0444 if (internal::ValueHelper::IsEmpty(that)) return nullptr;
0445 return api_internal::GlobalizeReference(
0446 reinterpret_cast<internal::Isolate*>(isolate),
0447 internal::ValueHelper::ValueAsAddress(that));
0448 }
0449
0450 template <class T, class M>
0451 template <class S, class M2>
0452 void Persistent<T, M>::Copy(const Persistent<S, M2>& that) {
0453 static_assert(std::is_base_of<T, S>::value, "type check");
0454 this->Reset();
0455 if (that.IsEmpty()) return;
0456 this->slot() = api_internal::CopyGlobalReference(that.slot());
0457 M::Copy(that, this);
0458 }
0459
0460 template <class T>
0461 bool PersistentBase<T>::IsWeak() const {
0462 using I = internal::Internals;
0463 if (this->IsEmpty()) return false;
0464 return I::GetNodeState(this->slot()) == I::kNodeStateIsWeakValue;
0465 }
0466
0467 template <class T>
0468 void PersistentBase<T>::Reset() {
0469 if (this->IsEmpty()) return;
0470 api_internal::DisposeGlobal(this->slot());
0471 this->Clear();
0472 }
0473
0474
0475
0476
0477
0478 template <class T>
0479 template <class S>
0480 void PersistentBase<T>::Reset(Isolate* isolate, const Local<S>& other) {
0481 static_assert(std::is_base_of<T, S>::value, "type check");
0482 Reset();
0483 if (other.IsEmpty()) return;
0484 this->slot() = New(isolate, *other);
0485 }
0486
0487
0488
0489
0490
0491 template <class T>
0492 template <class S>
0493 void PersistentBase<T>::Reset(Isolate* isolate,
0494 const PersistentBase<S>& other) {
0495 static_assert(std::is_base_of<T, S>::value, "type check");
0496 Reset();
0497 if (other.IsEmpty()) return;
0498 this->slot() = New(isolate, other.template value<S>());
0499 }
0500
0501 template <class T>
0502 template <typename P>
0503 V8_INLINE void PersistentBase<T>::SetWeak(
0504 P* parameter, typename WeakCallbackInfo<P>::Callback callback,
0505 WeakCallbackType type) {
0506 using Callback = WeakCallbackInfo<void>::Callback;
0507 #if (__GNUC__ >= 8) && !defined(__clang__)
0508 #pragma GCC diagnostic push
0509 #pragma GCC diagnostic ignored "-Wcast-function-type"
0510 #endif
0511 api_internal::MakeWeak(this->slot(), parameter,
0512 reinterpret_cast<Callback>(callback), type);
0513 #if (__GNUC__ >= 8) && !defined(__clang__)
0514 #pragma GCC diagnostic pop
0515 #endif
0516 }
0517
0518 template <class T>
0519 void PersistentBase<T>::SetWeak() {
0520 api_internal::MakeWeak(&this->slot());
0521 }
0522
0523 template <class T>
0524 template <typename P>
0525 P* PersistentBase<T>::ClearWeak() {
0526 return reinterpret_cast<P*>(api_internal::ClearWeak(this->slot()));
0527 }
0528
0529 template <class T>
0530 void PersistentBase<T>::AnnotateStrongRetainer(const char* label) {
0531 api_internal::AnnotateStrongRetainer(this->slot(), label);
0532 }
0533
0534 template <class T>
0535 void PersistentBase<T>::SetWrapperClassId(uint16_t class_id) {
0536 using I = internal::Internals;
0537 if (this->IsEmpty()) return;
0538 uint8_t* addr = reinterpret_cast<uint8_t*>(slot()) + I::kNodeClassIdOffset;
0539 *reinterpret_cast<uint16_t*>(addr) = class_id;
0540 }
0541
0542 template <class T>
0543 uint16_t PersistentBase<T>::WrapperClassId() const {
0544 using I = internal::Internals;
0545 if (this->IsEmpty()) return 0;
0546 uint8_t* addr = reinterpret_cast<uint8_t*>(slot()) + I::kNodeClassIdOffset;
0547 return *reinterpret_cast<uint16_t*>(addr);
0548 }
0549
0550 template <class T>
0551 Global<T>::Global(Global&& other) : PersistentBase<T>(other.slot()) {
0552 if (!other.IsEmpty()) {
0553 api_internal::MoveGlobalReference(&other.slot(), &this->slot());
0554 other.Clear();
0555 }
0556 }
0557
0558 template <class T>
0559 template <class S>
0560 Global<T>& Global<T>::operator=(Global<S>&& rhs) {
0561 static_assert(std::is_base_of<T, S>::value, "type check");
0562 if (this != &rhs) {
0563 this->Reset();
0564 if (!rhs.IsEmpty()) {
0565 this->slot() = rhs.slot();
0566 api_internal::MoveGlobalReference(&rhs.slot(), &this->slot());
0567 rhs.Clear();
0568 }
0569 }
0570 return *this;
0571 }
0572
0573 }
0574
0575 #endif