installed pty
[VSoRC/.git] / node_modules / node-pty / node_modules / nan / nan_weak.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_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<v8::Value>* self_v(reinterpret_cast<v8::Local<v8::Value>*>(this));
274     assert((*self_v)->IsObject());
275     v8::Local<v8::Object> self((*self_v).As<v8::Object>());
276     int count = self->InternalFieldCount();
277     void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};
278     for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {
279       internal_fields[i] = self->GetAlignedPointerFromInternalField(i);
280     }
281     wcbd = new WeakCallbackInfo<P>(
282         reinterpret_cast<Persistent<v8::Value>*>(this)
283       , callback
284       , 0
285       , internal_fields[0]
286       , internal_fields[1]);
287     self->SetAlignedPointerInInternalField(0, wcbd);
288     v8::PersistentBase<T>::SetWeak(
289         static_cast<WeakCallbackInfo<P>*>(0)
290       , WeakCallbackInfo<P>::template invoketwofield<true>
291       , type);
292   }
293 }
294 #elif NODE_MODULE_VERSION > IOJS_1_1_MODULE_VERSION
295 template<typename T, typename M>
296 template<typename P>
297 inline void Persistent<T, M>::SetWeak(
298     P *parameter
299   , typename WeakCallbackInfo<P>::Callback callback
300   , WeakCallbackType type) {
301   WeakCallbackInfo<P> *wcbd;
302   if (type == WeakCallbackType::kParameter) {
303     wcbd = new WeakCallbackInfo<P>(
304         reinterpret_cast<Persistent<v8::Value>*>(this)
305       , callback
306       , parameter);
307     v8::PersistentBase<T>::SetPhantom(
308         wcbd
309       , WeakCallbackInfo<P>::invokeparameter);
310   } else {
311     v8::Local<v8::Value>* self_v(reinterpret_cast<v8::Local<v8::Value>*>(this));
312     assert((*self_v)->IsObject());
313     v8::Local<v8::Object> self((*self_v).As<v8::Object>());
314     int count = self->InternalFieldCount();
315     void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};
316     for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {
317       internal_fields[i] = self->GetAlignedPointerFromInternalField(i);
318     }
319     wcbd = new WeakCallbackInfo<P>(
320         reinterpret_cast<Persistent<v8::Value>*>(this)
321       , callback
322       , 0
323       , internal_fields[0]
324       , internal_fields[1]);
325     self->SetAlignedPointerInInternalField(0, wcbd);
326     v8::PersistentBase<T>::SetPhantom(
327         static_cast<WeakCallbackInfo<P>*>(0)
328       , WeakCallbackInfo<P>::invoketwofield
329       , 0
330       , count > 1 ? 1 : kNoInternalFieldIndex);
331   }
332 }
333 #elif NODE_MODULE_VERSION > NODE_0_12_MODULE_VERSION
334 template<typename T, typename M>
335 template<typename P>
336 inline void Persistent<T, M>::SetWeak(
337     P *parameter
338   , typename WeakCallbackInfo<P>::Callback callback
339   , WeakCallbackType type) {
340   WeakCallbackInfo<P> *wcbd;
341   if (type == WeakCallbackType::kParameter) {
342     wcbd = new WeakCallbackInfo<P>(
343         reinterpret_cast<Persistent<v8::Value>*>(this)
344       , callback
345       , parameter);
346     v8::PersistentBase<T>::SetPhantom(
347         wcbd
348       , WeakCallbackInfo<P>::invokeparameter);
349   } else {
350     v8::Local<v8::Value>* self_v(reinterpret_cast<v8::Local<v8::Value>*>(this));
351     assert((*self_v)->IsObject());
352     v8::Local<v8::Object> self((*self_v).As<v8::Object>());
353     int count = self->InternalFieldCount();
354     void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};
355     for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {
356       internal_fields[i] = self->GetAlignedPointerFromInternalField(i);
357     }
358     wcbd = new WeakCallbackInfo<P>(
359         reinterpret_cast<Persistent<v8::Value>*>(this)
360       , callback
361       , 0
362       , internal_fields[0]
363       , internal_fields[1]);
364     self->SetAlignedPointerInInternalField(0, wcbd);
365     v8::PersistentBase<T>::SetPhantom(
366         WeakCallbackInfo<P>::invoketwofield
367       , 0
368       , count > 1 ? 1 : kNoInternalFieldIndex);
369   }
370 }
371 #elif NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
372 template<typename T, typename M>
373 template<typename P>
374 inline void Persistent<T, M>::SetWeak(
375     P *parameter
376   , typename WeakCallbackInfo<P>::Callback callback
377   , WeakCallbackType type) {
378   WeakCallbackInfo<P> *wcbd;
379   if (type == WeakCallbackType::kParameter) {
380     wcbd = new WeakCallbackInfo<P>(
381         reinterpret_cast<Persistent<v8::Value>*>(this)
382       , callback
383       , parameter);
384     v8::PersistentBase<T>::SetWeak(wcbd, WeakCallbackInfo<P>::invoke);
385   } else {
386     v8::Local<v8::Value>* self_v(reinterpret_cast<v8::Local<v8::Value>*>(this));
387     assert((*self_v)->IsObject());
388     v8::Local<v8::Object> self((*self_v).As<v8::Object>());
389     int count = self->InternalFieldCount();
390     void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};
391     for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {
392       internal_fields[i] = self->GetAlignedPointerFromInternalField(i);
393     }
394     wcbd = new WeakCallbackInfo<P>(
395         reinterpret_cast<Persistent<v8::Value>*>(this)
396       , callback
397       , 0
398       , internal_fields[0]
399       , internal_fields[1]);
400     v8::PersistentBase<T>::SetWeak(wcbd, WeakCallbackInfo<P>::invoke);
401   }
402 }
403 #else
404 template<typename T>
405 template<typename P>
406 inline void PersistentBase<T>::SetWeak(
407     P *parameter
408   , typename WeakCallbackInfo<P>::Callback callback
409   , WeakCallbackType type) {
410   WeakCallbackInfo<P> *wcbd;
411   if (type == WeakCallbackType::kParameter) {
412     wcbd = new WeakCallbackInfo<P>(
413         reinterpret_cast<Persistent<v8::Value>*>(this)
414       , callback
415       , parameter);
416     persistent.MakeWeak(wcbd, WeakCallbackInfo<P>::invoke);
417   } else {
418     v8::Local<v8::Value>* self_v(reinterpret_cast<v8::Local<v8::Value>*>(this));
419     assert((*self_v)->IsObject());
420     v8::Local<v8::Object> self((*self_v).As<v8::Object>());
421     int count = self->InternalFieldCount();
422     void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};
423     for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {
424       internal_fields[i] = self->GetPointerFromInternalField(i);
425     }
426     wcbd = new WeakCallbackInfo<P>(
427         reinterpret_cast<Persistent<v8::Value>*>(this)
428       , callback
429       , 0
430       , internal_fields[0]
431       , internal_fields[1]);
432     persistent.MakeWeak(wcbd, WeakCallbackInfo<P>::invoke);
433   }
434 }
435 #endif
436
437 #endif  // NAN_WEAK_H_