Projekt

Obecné

Profil

Stáhnout (15 KB) Statistiky
| Větev: | Revize:
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_
(25-25/26)