1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
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 |
|
34 |
|
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 |
|
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 | |
89 |
|
90 |
|
91 |
|
92 | virtual void Ref() {
|
93 | assert(!persistent().IsEmpty());
|
94 | persistent().ClearWeak();
|
95 | refs_++;
|
96 | }
|
97 |
|
98 | |
99 |
|
100 |
|
101 |
|
102 |
|
103 |
|
104 |
|
105 |
|
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_;
|
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
|