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 | assert(persistent().IsNearDeath());
|
25 | persistent().ClearWeak();
|
26 | persistent().Reset();
|
27 | }
|
28 |
|
29 |
|
30 | template <class T>
|
31 | static inline T* Unwrap(v8::Local<v8::Object> object) {
|
32 | assert(!object.IsEmpty());
|
33 | assert(object->InternalFieldCount() > 0);
|
34 |
|
35 |
|
36 | void* ptr = GetInternalFieldPointer(object, 0);
|
37 | ObjectWrap* wrap = static_cast<ObjectWrap*>(ptr);
|
38 | return static_cast<T*>(wrap);
|
39 | }
|
40 |
|
41 |
|
42 | inline v8::Local<v8::Object> handle() const {
|
43 | return New(handle_);
|
44 | }
|
45 |
|
46 |
|
47 | inline Persistent<v8::Object>& persistent() {
|
48 | return handle_;
|
49 | }
|
50 |
|
51 |
|
52 | protected:
|
53 | inline void Wrap(v8::Local<v8::Object> object) {
|
54 | assert(persistent().IsEmpty());
|
55 | assert(object->InternalFieldCount() > 0);
|
56 | SetInternalFieldPointer(object, 0, this);
|
57 | persistent().Reset(object);
|
58 | MakeWeak();
|
59 | }
|
60 |
|
61 | #if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \
|
62 | (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
|
63 |
|
64 | inline void MakeWeak() {
|
65 | persistent().v8::PersistentBase<v8::Object>::SetWeak(
|
66 | this, WeakCallback, v8::WeakCallbackType::kParameter);
|
67 | persistent().MarkIndependent();
|
68 | }
|
69 |
|
70 | #elif NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
|
71 |
|
72 | inline void MakeWeak() {
|
73 | persistent().v8::PersistentBase<v8::Object>::SetWeak(this, WeakCallback);
|
74 | persistent().MarkIndependent();
|
75 | }
|
76 |
|
77 | #else
|
78 |
|
79 | inline void MakeWeak() {
|
80 | persistent().persistent.MakeWeak(this, WeakCallback);
|
81 | persistent().MarkIndependent();
|
82 | }
|
83 |
|
84 | #endif
|
85 |
|
86 | |
87 |
|
88 |
|
89 |
|
90 | virtual void Ref() {
|
91 | assert(!persistent().IsEmpty());
|
92 | persistent().ClearWeak();
|
93 | refs_++;
|
94 | }
|
95 |
|
96 | |
97 |
|
98 |
|
99 |
|
100 |
|
101 |
|
102 |
|
103 |
|
104 |
|
105 | virtual void Unref() {
|
106 | assert(!persistent().IsEmpty());
|
107 | assert(!persistent().IsWeak());
|
108 | assert(refs_ > 0);
|
109 | if (--refs_ == 0)
|
110 | MakeWeak();
|
111 | }
|
112 |
|
113 | int refs_;
|
114 |
|
115 | private:
|
116 | NAN_DISALLOW_ASSIGN_COPY_MOVE(ObjectWrap)
|
117 | #if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \
|
118 | (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
|
119 |
|
120 | static void
|
121 | WeakCallback(v8::WeakCallbackInfo<ObjectWrap> const& info) {
|
122 | ObjectWrap* wrap = info.GetParameter();
|
123 | assert(wrap->refs_ == 0);
|
124 | assert(wrap->handle_.IsNearDeath());
|
125 | wrap->handle_.Reset();
|
126 | delete wrap;
|
127 | }
|
128 |
|
129 | #elif NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
|
130 |
|
131 | static void
|
132 | WeakCallback(v8::WeakCallbackData<v8::Object, ObjectWrap> const& data) {
|
133 | ObjectWrap* wrap = data.GetParameter();
|
134 | assert(wrap->refs_ == 0);
|
135 | assert(wrap->handle_.IsNearDeath());
|
136 | wrap->handle_.Reset();
|
137 | delete wrap;
|
138 | }
|
139 |
|
140 | #else
|
141 |
|
142 | static void WeakCallback(v8::Persistent<v8::Value> value, void *data) {
|
143 | ObjectWrap *wrap = static_cast<ObjectWrap*>(data);
|
144 | assert(wrap->refs_ == 0);
|
145 | assert(wrap->handle_.IsNearDeath());
|
146 | wrap->handle_.Reset();
|
147 | delete wrap;
|
148 | }
|
149 |
|
150 | #endif
|
151 | Persistent<v8::Object> handle_;
|
152 | };
|
153 |
|
154 |
|
155 | #endif
|