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