nan_object_wrap.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*********************************************************************
  2. * NAN - Native Abstractions for Node.js
  3. *
  4. * Copyright (c) 2018 NAN contributors
  5. *
  6. * MIT License <https://github.com/nodejs/nan/blob/master/LICENSE.md>
  7. ********************************************************************/
  8. #ifndef NAN_OBJECT_WRAP_H_
  9. #define NAN_OBJECT_WRAP_H_
  10. class ObjectWrap {
  11. public:
  12. ObjectWrap() {
  13. refs_ = 0;
  14. }
  15. virtual ~ObjectWrap() {
  16. if (persistent().IsEmpty()) {
  17. return;
  18. }
  19. assert(persistent().IsNearDeath());
  20. persistent().ClearWeak();
  21. persistent().Reset();
  22. }
  23. template <class T>
  24. static inline T* Unwrap(v8::Local<v8::Object> object) {
  25. assert(!object.IsEmpty());
  26. assert(object->InternalFieldCount() > 0);
  27. // Cast to ObjectWrap before casting to T. A direct cast from void
  28. // to T won't work right when T has more than one base class.
  29. void* ptr = GetInternalFieldPointer(object, 0);
  30. ObjectWrap* wrap = static_cast<ObjectWrap*>(ptr);
  31. return static_cast<T*>(wrap);
  32. }
  33. inline v8::Local<v8::Object> handle() const {
  34. return New(handle_);
  35. }
  36. inline Persistent<v8::Object>& persistent() {
  37. return handle_;
  38. }
  39. protected:
  40. inline void Wrap(v8::Local<v8::Object> object) {
  41. assert(persistent().IsEmpty());
  42. assert(object->InternalFieldCount() > 0);
  43. SetInternalFieldPointer(object, 0, this);
  44. persistent().Reset(object);
  45. MakeWeak();
  46. }
  47. #if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \
  48. (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
  49. inline void MakeWeak() {
  50. persistent().v8::PersistentBase<v8::Object>::SetWeak(
  51. this, WeakCallback, v8::WeakCallbackType::kParameter);
  52. #if NODE_MAJOR_VERSION < 10
  53. // FIXME(bnoordhuis) Probably superfluous in older Node.js versions too.
  54. persistent().MarkIndependent();
  55. #endif
  56. }
  57. #elif NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
  58. inline void MakeWeak() {
  59. persistent().v8::PersistentBase<v8::Object>::SetWeak(this, WeakCallback);
  60. persistent().MarkIndependent();
  61. }
  62. #else
  63. inline void MakeWeak() {
  64. persistent().persistent.MakeWeak(this, WeakCallback);
  65. persistent().MarkIndependent();
  66. }
  67. #endif
  68. /* Ref() marks the object as being attached to an event loop.
  69. * Refed objects will not be garbage collected, even if
  70. * all references are lost.
  71. */
  72. virtual void Ref() {
  73. assert(!persistent().IsEmpty());
  74. persistent().ClearWeak();
  75. refs_++;
  76. }
  77. /* Unref() marks an object as detached from the event loop. This is its
  78. * default state. When an object with a "weak" reference changes from
  79. * attached to detached state it will be freed. Be careful not to access
  80. * the object after making this call as it might be gone!
  81. * (A "weak reference" means an object that only has a
  82. * persistant handle.)
  83. *
  84. * DO NOT CALL THIS FROM DESTRUCTOR
  85. */
  86. virtual void Unref() {
  87. assert(!persistent().IsEmpty());
  88. assert(!persistent().IsWeak());
  89. assert(refs_ > 0);
  90. if (--refs_ == 0)
  91. MakeWeak();
  92. }
  93. int refs_; // ro
  94. private:
  95. NAN_DISALLOW_ASSIGN_COPY_MOVE(ObjectWrap)
  96. #if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \
  97. (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
  98. static void
  99. WeakCallback(v8::WeakCallbackInfo<ObjectWrap> const& info) {
  100. ObjectWrap* wrap = info.GetParameter();
  101. assert(wrap->refs_ == 0);
  102. assert(wrap->handle_.IsNearDeath());
  103. wrap->handle_.Reset();
  104. delete wrap;
  105. }
  106. #elif NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
  107. static void
  108. WeakCallback(v8::WeakCallbackData<v8::Object, ObjectWrap> const& data) {
  109. ObjectWrap* wrap = data.GetParameter();
  110. assert(wrap->refs_ == 0);
  111. assert(wrap->handle_.IsNearDeath());
  112. wrap->handle_.Reset();
  113. delete wrap;
  114. }
  115. #else
  116. static void WeakCallback(v8::Persistent<v8::Value> value, void *data) {
  117. ObjectWrap *wrap = static_cast<ObjectWrap*>(data);
  118. assert(wrap->refs_ == 0);
  119. assert(wrap->handle_.IsNearDeath());
  120. wrap->handle_.Reset();
  121. delete wrap;
  122. }
  123. #endif
  124. Persistent<v8::Object> handle_;
  125. };
  126. #endif // NAN_OBJECT_WRAP_H_