Subversion Repositories php-qbpwcf

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 liveuser 1
/*********************************************************************
2
 * NAN - Native Abstractions for Node.js
3
 *
4
 * Copyright (c) 2016 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_