Initial commit
[yaffs-website] / node_modules / nan / nan_weak.h
1 /*********************************************************************
2  * NAN - Native Abstractions for Node.js
3  *
4  * Copyright (c) 2017 NAN contributors
5  *
6  * MIT License <https://github.com/nodejs/nan/blob/master/LICENSE.md>
7  ********************************************************************/
8
9 #ifndef NAN_WEAK_H_
10 #define NAN_WEAK_H_
11
12 static const int kInternalFieldsInWeakCallback = 2;
13 static const int kNoInternalFieldIndex = -1;
14
15 #if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 ||                      \
16   (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
17 # define NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_ \
18     v8::WeakCallbackInfo<WeakCallbackInfo<T> > const&
19 # define NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_ \
20     NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_
21 # define NAN_WEAK_PARAMETER_CALLBACK_SIG_ NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_
22 # define NAN_WEAK_TWOFIELD_CALLBACK_SIG_ NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_
23 #elif NODE_MODULE_VERSION > IOJS_1_1_MODULE_VERSION
24 # define NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_ \
25     v8::PhantomCallbackData<WeakCallbackInfo<T> > const&
26 # define NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_ \
27     NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_
28 # define NAN_WEAK_PARAMETER_CALLBACK_SIG_ NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_
29 # define NAN_WEAK_TWOFIELD_CALLBACK_SIG_ NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_
30 #elif NODE_MODULE_VERSION > NODE_0_12_MODULE_VERSION
31 # define NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_ \
32     v8::PhantomCallbackData<WeakCallbackInfo<T> > const&
33 # define NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_ \
34     v8::InternalFieldsCallbackData<WeakCallbackInfo<T>, void> const&
35 # define NAN_WEAK_PARAMETER_CALLBACK_SIG_ NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_
36 # define NAN_WEAK_TWOFIELD_CALLBACK_SIG_ NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_
37 #elif NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
38 # define NAN_WEAK_CALLBACK_DATA_TYPE_ \
39     v8::WeakCallbackData<S, WeakCallbackInfo<T> > const&
40 # define NAN_WEAK_CALLBACK_SIG_ NAN_WEAK_CALLBACK_DATA_TYPE_
41 #else
42 # define NAN_WEAK_CALLBACK_DATA_TYPE_ void *
43 # define NAN_WEAK_CALLBACK_SIG_ \
44     v8::Persistent<v8::Value>, NAN_WEAK_CALLBACK_DATA_TYPE_
45 #endif
46
47 template<typename T>
48 class WeakCallbackInfo {
49  public:
50   typedef void (*Callback)(const WeakCallbackInfo<T>& data);
51   WeakCallbackInfo(
52       Persistent<v8::Value> *persistent
53     , Callback callback
54     , void *parameter
55     , void *field1 = 0
56     , void *field2 = 0) :
57         callback_(callback), isolate_(0), parameter_(parameter) {
58     std::memcpy(&persistent_, persistent, sizeof (v8::Persistent<v8::Value>));
59     internal_fields_[0] = field1;
60     internal_fields_[1] = field2;
61   }
62   inline v8::Isolate *GetIsolate() const { return isolate_; }
63   inline T *GetParameter() const { return static_cast<T*>(parameter_); }
64   inline void *GetInternalField(int index) const {
65     assert((index == 0 || index == 1) && "internal field index out of bounds");
66     if (index == 0) {
67       return internal_fields_[0];
68     } else {
69       return internal_fields_[1];
70     }
71   }
72
73  private:
74   NAN_DISALLOW_ASSIGN_COPY_MOVE(WeakCallbackInfo)
75   Callback callback_;
76   v8::Isolate *isolate_;
77   void *parameter_;
78   void *internal_fields_[kInternalFieldsInWeakCallback];
79   v8::Persistent<v8::Value> persistent_;
80   template<typename S, typename M> friend class Persistent;
81   template<typename S> friend class PersistentBase;
82 #if NODE_MODULE_VERSION <= NODE_0_12_MODULE_VERSION
83 # if NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
84   template<typename S>
85   static void invoke(NAN_WEAK_CALLBACK_SIG_ data);
86   template<typename S>
87   static WeakCallbackInfo *unwrap(NAN_WEAK_CALLBACK_DATA_TYPE_ data);
88 # else
89   static void invoke(NAN_WEAK_CALLBACK_SIG_ data);
90   static WeakCallbackInfo *unwrap(NAN_WEAK_CALLBACK_DATA_TYPE_ data);
91 # endif
92 #else
93 # if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 ||                     \
94   (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
95   template<bool isFirstPass>
96   static void invokeparameter(NAN_WEAK_PARAMETER_CALLBACK_SIG_ data);
97   template<bool isFirstPass>
98   static void invoketwofield(NAN_WEAK_TWOFIELD_CALLBACK_SIG_ data);
99 # else
100   static void invokeparameter(NAN_WEAK_PARAMETER_CALLBACK_SIG_ data);
101   static void invoketwofield(NAN_WEAK_TWOFIELD_CALLBACK_SIG_ data);
102 # endif
103   static WeakCallbackInfo *unwrapparameter(
104       NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_ data);
105   static WeakCallbackInfo *unwraptwofield(
106       NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_ data);
107 #endif
108 };
109
110
111 #if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 ||                      \
112   (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
113
114 template<typename T>
115 template<bool isFirstPass>
116 void
117 WeakCallbackInfo<T>::invokeparameter(NAN_WEAK_PARAMETER_CALLBACK_SIG_ data) {
118   WeakCallbackInfo<T> *cbinfo = unwrapparameter(data);
119   if (isFirstPass) {
120     cbinfo->persistent_.Reset();
121     data.SetSecondPassCallback(invokeparameter<false>);
122   } else {
123     cbinfo->callback_(*cbinfo);
124     delete cbinfo;
125   }
126 }
127
128 template<typename T>
129 template<bool isFirstPass>
130 void
131 WeakCallbackInfo<T>::invoketwofield(NAN_WEAK_TWOFIELD_CALLBACK_SIG_ data) {
132   WeakCallbackInfo<T> *cbinfo = unwraptwofield(data);
133   if (isFirstPass) {
134     cbinfo->persistent_.Reset();
135     data.SetSecondPassCallback(invoketwofield<false>);
136   } else {
137     cbinfo->callback_(*cbinfo);
138     delete cbinfo;
139   }
140 }
141
142 template<typename T>
143 WeakCallbackInfo<T> *WeakCallbackInfo<T>::unwrapparameter(
144     NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_ data) {
145   WeakCallbackInfo<T> *cbinfo =
146       static_cast<WeakCallbackInfo<T>*>(data.GetParameter());
147   cbinfo->isolate_ = data.GetIsolate();
148   return cbinfo;
149 }
150
151 template<typename T>
152 WeakCallbackInfo<T> *WeakCallbackInfo<T>::unwraptwofield(
153     NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_ data) {
154   WeakCallbackInfo<T> *cbinfo =
155       static_cast<WeakCallbackInfo<T>*>(data.GetInternalField(0));
156   cbinfo->isolate_ = data.GetIsolate();
157   return cbinfo;
158 }
159
160 #undef NAN_WEAK_PARAMETER_CALLBACK_SIG_
161 #undef NAN_WEAK_TWOFIELD_CALLBACK_SIG_
162 #undef NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_
163 #undef NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_
164 # elif NODE_MODULE_VERSION > NODE_0_12_MODULE_VERSION
165
166 template<typename T>
167 void
168 WeakCallbackInfo<T>::invokeparameter(NAN_WEAK_PARAMETER_CALLBACK_SIG_ data) {
169   WeakCallbackInfo<T> *cbinfo = unwrapparameter(data);
170   cbinfo->persistent_.Reset();
171   cbinfo->callback_(*cbinfo);
172   delete cbinfo;
173 }
174
175 template<typename T>
176 void
177 WeakCallbackInfo<T>::invoketwofield(NAN_WEAK_TWOFIELD_CALLBACK_SIG_ data) {
178   WeakCallbackInfo<T> *cbinfo = unwraptwofield(data);
179   cbinfo->persistent_.Reset();
180   cbinfo->callback_(*cbinfo);
181   delete cbinfo;
182 }
183
184 template<typename T>
185 WeakCallbackInfo<T> *WeakCallbackInfo<T>::unwrapparameter(
186     NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_ data) {
187   WeakCallbackInfo<T> *cbinfo =
188        static_cast<WeakCallbackInfo<T>*>(data.GetParameter());
189   cbinfo->isolate_ = data.GetIsolate();
190   return cbinfo;
191 }
192
193 template<typename T>
194 WeakCallbackInfo<T> *WeakCallbackInfo<T>::unwraptwofield(
195     NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_ data) {
196   WeakCallbackInfo<T> *cbinfo =
197        static_cast<WeakCallbackInfo<T>*>(data.GetInternalField1());
198   cbinfo->isolate_ = data.GetIsolate();
199   return cbinfo;
200 }
201
202 #undef NAN_WEAK_PARAMETER_CALLBACK_SIG_
203 #undef NAN_WEAK_TWOFIELD_CALLBACK_SIG_
204 #undef NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_
205 #undef NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_
206 #elif NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
207
208 template<typename T>
209 template<typename S>
210 void WeakCallbackInfo<T>::invoke(NAN_WEAK_CALLBACK_SIG_ data) {
211   WeakCallbackInfo<T> *cbinfo = unwrap(data);
212   cbinfo->persistent_.Reset();
213   cbinfo->callback_(*cbinfo);
214   delete cbinfo;
215 }
216
217 template<typename T>
218 template<typename S>
219 WeakCallbackInfo<T> *WeakCallbackInfo<T>::unwrap(
220     NAN_WEAK_CALLBACK_DATA_TYPE_ data) {
221   void *parameter = data.GetParameter();
222   WeakCallbackInfo<T> *cbinfo =
223       static_cast<WeakCallbackInfo<T>*>(parameter);
224   cbinfo->isolate_ = data.GetIsolate();
225   return cbinfo;
226 }
227
228 #undef NAN_WEAK_CALLBACK_SIG_
229 #undef NAN_WEAK_CALLBACK_DATA_TYPE_
230 #else
231
232 template<typename T>
233 void WeakCallbackInfo<T>::invoke(NAN_WEAK_CALLBACK_SIG_ data) {
234   WeakCallbackInfo<T> *cbinfo = unwrap(data);
235   cbinfo->persistent_.Dispose();
236   cbinfo->persistent_.Clear();
237   cbinfo->callback_(*cbinfo);
238   delete cbinfo;
239 }
240
241 template<typename T>
242 WeakCallbackInfo<T> *WeakCallbackInfo<T>::unwrap(
243     NAN_WEAK_CALLBACK_DATA_TYPE_ data) {
244   WeakCallbackInfo<T> *cbinfo =
245       static_cast<WeakCallbackInfo<T>*>(data);
246   cbinfo->isolate_ = v8::Isolate::GetCurrent();
247   return cbinfo;
248 }
249
250 #undef NAN_WEAK_CALLBACK_SIG_
251 #undef NAN_WEAK_CALLBACK_DATA_TYPE_
252 #endif
253
254 #if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 ||                      \
255   (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
256 template<typename T, typename M>
257 template<typename P>
258 inline void Persistent<T, M>::SetWeak(
259     P *parameter
260   , typename WeakCallbackInfo<P>::Callback callback
261   , WeakCallbackType type) {
262   WeakCallbackInfo<P> *wcbd;
263   if (type == WeakCallbackType::kParameter) {
264     wcbd = new WeakCallbackInfo<P>(
265         reinterpret_cast<Persistent<v8::Value>*>(this)
266       , callback
267       , parameter);
268     v8::PersistentBase<T>::SetWeak(
269         wcbd
270       , WeakCallbackInfo<P>::template invokeparameter<true>
271       , type);
272   } else {
273     v8::Local<T>* self = reinterpret_cast<v8::Local<T>*>(this);
274     assert((*self)->IsObject());
275     int count = (*self)->InternalFieldCount();
276     void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};
277     for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {
278       internal_fields[i] = (*self)->GetAlignedPointerFromInternalField(i);
279     }
280     wcbd = new WeakCallbackInfo<P>(
281         reinterpret_cast<Persistent<v8::Value>*>(this)
282       , callback
283       , 0
284       , internal_fields[0]
285       , internal_fields[1]);
286     (*self)->SetAlignedPointerInInternalField(0, wcbd);
287     v8::PersistentBase<T>::SetWeak(
288         static_cast<WeakCallbackInfo<P>*>(0)
289       , WeakCallbackInfo<P>::template invoketwofield<true>
290       , type);
291   }
292 }
293 #elif NODE_MODULE_VERSION > IOJS_1_1_MODULE_VERSION
294 template<typename T, typename M>
295 template<typename P>
296 inline void Persistent<T, M>::SetWeak(
297     P *parameter
298   , typename WeakCallbackInfo<P>::Callback callback
299   , WeakCallbackType type) {
300   WeakCallbackInfo<P> *wcbd;
301   if (type == WeakCallbackType::kParameter) {
302     wcbd = new WeakCallbackInfo<P>(
303         reinterpret_cast<Persistent<v8::Value>*>(this)
304       , callback
305       , parameter);
306     v8::PersistentBase<T>::SetPhantom(
307         wcbd
308       , WeakCallbackInfo<P>::invokeparameter);
309   } else {
310     v8::Local<T>* self = reinterpret_cast<v8::Local<T>*>(this);
311     assert((*self)->IsObject());
312     int count = (*self)->InternalFieldCount();
313     void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};
314     for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {
315       internal_fields[i] = (*self)->GetAlignedPointerFromInternalField(i);
316     }
317     wcbd = new WeakCallbackInfo<P>(
318         reinterpret_cast<Persistent<v8::Value>*>(this)
319       , callback
320       , 0
321       , internal_fields[0]
322       , internal_fields[1]);
323     (*self)->SetAlignedPointerInInternalField(0, wcbd);
324     v8::PersistentBase<T>::SetPhantom(
325         static_cast<WeakCallbackInfo<P>*>(0)
326       , WeakCallbackInfo<P>::invoketwofield
327       , 0
328       , count > 1 ? 1 : kNoInternalFieldIndex);
329   }
330 }
331 #elif NODE_MODULE_VERSION > NODE_0_12_MODULE_VERSION
332 template<typename T, typename M>
333 template<typename P>
334 inline void Persistent<T, M>::SetWeak(
335     P *parameter
336   , typename WeakCallbackInfo<P>::Callback callback
337   , WeakCallbackType type) {
338   WeakCallbackInfo<P> *wcbd;
339   if (type == WeakCallbackType::kParameter) {
340     wcbd = new WeakCallbackInfo<P>(
341         reinterpret_cast<Persistent<v8::Value>*>(this)
342       , callback
343       , parameter);
344     v8::PersistentBase<T>::SetPhantom(
345         wcbd
346       , WeakCallbackInfo<P>::invokeparameter);
347   } else {
348     v8::Local<T>* self = reinterpret_cast<v8::Local<T>*>(this);
349     assert((*self)->IsObject());
350     int count = (*self)->InternalFieldCount();
351     void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};
352     for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {
353       internal_fields[i] = (*self)->GetAlignedPointerFromInternalField(i);
354     }
355     wcbd = new WeakCallbackInfo<P>(
356         reinterpret_cast<Persistent<v8::Value>*>(this)
357       , callback
358       , 0
359       , internal_fields[0]
360       , internal_fields[1]);
361     (*self)->SetAlignedPointerInInternalField(0, wcbd);
362     v8::PersistentBase<T>::SetPhantom(
363         WeakCallbackInfo<P>::invoketwofield
364       , 0
365       , count > 1 ? 1 : kNoInternalFieldIndex);
366   }
367 }
368 #elif NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
369 template<typename T, typename M>
370 template<typename P>
371 inline void Persistent<T, M>::SetWeak(
372     P *parameter
373   , typename WeakCallbackInfo<P>::Callback callback
374   , WeakCallbackType type) {
375   WeakCallbackInfo<P> *wcbd;
376   if (type == WeakCallbackType::kParameter) {
377     wcbd = new WeakCallbackInfo<P>(
378         reinterpret_cast<Persistent<v8::Value>*>(this)
379       , callback
380       , parameter);
381     v8::PersistentBase<T>::SetWeak(wcbd, WeakCallbackInfo<P>::invoke);
382   } else {
383     v8::Local<T>* self = reinterpret_cast<v8::Local<T>*>(this);
384     assert((*self)->IsObject());
385     int count = (*self)->InternalFieldCount();
386     void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};
387     for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {
388       internal_fields[i] = (*self)->GetAlignedPointerFromInternalField(i);
389     }
390     wcbd = new WeakCallbackInfo<P>(
391         reinterpret_cast<Persistent<v8::Value>*>(this)
392       , callback
393       , 0
394       , internal_fields[0]
395       , internal_fields[1]);
396     v8::PersistentBase<T>::SetWeak(wcbd, WeakCallbackInfo<P>::invoke);
397   }
398 }
399 #else
400 template<typename T>
401 template<typename P>
402 inline void PersistentBase<T>::SetWeak(
403     P *parameter
404   , typename WeakCallbackInfo<P>::Callback callback
405   , WeakCallbackType type) {
406   WeakCallbackInfo<P> *wcbd;
407   if (type == WeakCallbackType::kParameter) {
408     wcbd = new WeakCallbackInfo<P>(
409         reinterpret_cast<Persistent<v8::Value>*>(this)
410       , callback
411       , parameter);
412     persistent.MakeWeak(wcbd, WeakCallbackInfo<P>::invoke);
413   } else {
414     v8::Local<T>* self = reinterpret_cast<v8::Local<T>*>(this);
415     assert((*self)->IsObject());
416     int count = (*self)->InternalFieldCount();
417     void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};
418     for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {
419       internal_fields[i] = (*self)->GetPointerFromInternalField(i);
420     }
421     wcbd = new WeakCallbackInfo<P>(
422         reinterpret_cast<Persistent<v8::Value>*>(this)
423       , callback
424       , 0
425       , internal_fields[0]
426       , internal_fields[1]);
427     persistent.MakeWeak(wcbd, WeakCallbackInfo<P>::invoke);
428   }
429 }
430 #endif
431
432 #endif  // NAN_WEAK_H_