nan_weak.h
Go to the documentation of this file.
00001 /*********************************************************************
00002  * NAN - Native Abstractions for Node.js
00003  *
00004  * Copyright (c) 2016 NAN contributors
00005  *
00006  * MIT License <https://github.com/nodejs/nan/blob/master/LICENSE.md>
00007  ********************************************************************/
00008 
00009 #ifndef NAN_WEAK_H_
00010 #define NAN_WEAK_H_
00011 
00012 static const int kInternalFieldsInWeakCallback = 2;
00013 static const int kNoInternalFieldIndex = -1;
00014 
00015 #if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 ||                      \
00016   (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
00017 # define NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_ \
00018     v8::WeakCallbackInfo<WeakCallbackInfo<T> > const&
00019 # define NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_ \
00020     NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_
00021 # define NAN_WEAK_PARAMETER_CALLBACK_SIG_ NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_
00022 # define NAN_WEAK_TWOFIELD_CALLBACK_SIG_ NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_
00023 #elif NODE_MODULE_VERSION > IOJS_1_1_MODULE_VERSION
00024 # define NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_ \
00025     v8::PhantomCallbackData<WeakCallbackInfo<T> > const&
00026 # define NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_ \
00027     NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_
00028 # define NAN_WEAK_PARAMETER_CALLBACK_SIG_ NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_
00029 # define NAN_WEAK_TWOFIELD_CALLBACK_SIG_ NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_
00030 #elif NODE_MODULE_VERSION > NODE_0_12_MODULE_VERSION
00031 # define NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_ \
00032     v8::PhantomCallbackData<WeakCallbackInfo<T> > const&
00033 # define NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_ \
00034     v8::InternalFieldsCallbackData<WeakCallbackInfo<T>, void> const&
00035 # define NAN_WEAK_PARAMETER_CALLBACK_SIG_ NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_
00036 # define NAN_WEAK_TWOFIELD_CALLBACK_SIG_ NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_
00037 #elif NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
00038 # define NAN_WEAK_CALLBACK_DATA_TYPE_ \
00039     v8::WeakCallbackData<S, WeakCallbackInfo<T> > const&
00040 # define NAN_WEAK_CALLBACK_SIG_ NAN_WEAK_CALLBACK_DATA_TYPE_
00041 #else
00042 # define NAN_WEAK_CALLBACK_DATA_TYPE_ void *
00043 # define NAN_WEAK_CALLBACK_SIG_ \
00044     v8::Persistent<v8::Value>, NAN_WEAK_CALLBACK_DATA_TYPE_
00045 #endif
00046 
00047 template<typename T>
00048 class WeakCallbackInfo {
00049  public:
00050   typedef void (*Callback)(const WeakCallbackInfo<T>& data);
00051   WeakCallbackInfo(
00052       Persistent<v8::Value> *persistent
00053     , Callback callback
00054     , void *parameter
00055     , void *field1 = 0
00056     , void *field2 = 0) :
00057         callback_(callback), isolate_(0), parameter_(parameter) {
00058     std::memcpy(&persistent_, persistent, sizeof (v8::Persistent<v8::Value>));
00059     internal_fields_[0] = field1;
00060     internal_fields_[1] = field2;
00061   }
00062   inline v8::Isolate *GetIsolate() const { return isolate_; }
00063   inline T *GetParameter() const { return static_cast<T*>(parameter_); }
00064   inline void *GetInternalField(int index) const {
00065     assert((index == 0 || index == 1) && "internal field index out of bounds");
00066     if (index == 0) {
00067       return internal_fields_[0];
00068     } else {
00069       return internal_fields_[1];
00070     }
00071   }
00072 
00073  private:
00074   NAN_DISALLOW_ASSIGN_COPY_MOVE(WeakCallbackInfo)
00075   Callback callback_;
00076   v8::Isolate *isolate_;
00077   void *parameter_;
00078   void *internal_fields_[kInternalFieldsInWeakCallback];
00079   v8::Persistent<v8::Value> persistent_;
00080   template<typename S, typename M> friend class Persistent;
00081   template<typename S> friend class PersistentBase;
00082 #if NODE_MODULE_VERSION <= NODE_0_12_MODULE_VERSION
00083 # if NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
00084   template<typename S>
00085   static void invoke(NAN_WEAK_CALLBACK_SIG_ data);
00086   template<typename S>
00087   static WeakCallbackInfo *unwrap(NAN_WEAK_CALLBACK_DATA_TYPE_ data);
00088 # else
00089   static void invoke(NAN_WEAK_CALLBACK_SIG_ data);
00090   static WeakCallbackInfo *unwrap(NAN_WEAK_CALLBACK_DATA_TYPE_ data);
00091 # endif
00092 #else
00093 # if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 ||                     \
00094   (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
00095   template<bool isFirstPass>
00096   static void invokeparameter(NAN_WEAK_PARAMETER_CALLBACK_SIG_ data);
00097   template<bool isFirstPass>
00098   static void invoketwofield(NAN_WEAK_TWOFIELD_CALLBACK_SIG_ data);
00099 # else
00100   static void invokeparameter(NAN_WEAK_PARAMETER_CALLBACK_SIG_ data);
00101   static void invoketwofield(NAN_WEAK_TWOFIELD_CALLBACK_SIG_ data);
00102 # endif
00103   static WeakCallbackInfo *unwrapparameter(
00104       NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_ data);
00105   static WeakCallbackInfo *unwraptwofield(
00106       NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_ data);
00107 #endif
00108 };
00109 
00110 
00111 #if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 ||                      \
00112   (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
00113 
00114 template<typename T>
00115 template<bool isFirstPass>
00116 void
00117 WeakCallbackInfo<T>::invokeparameter(NAN_WEAK_PARAMETER_CALLBACK_SIG_ data) {
00118   WeakCallbackInfo<T> *cbinfo = unwrapparameter(data);
00119   if (isFirstPass) {
00120     cbinfo->persistent_.Reset();
00121     data.SetSecondPassCallback(invokeparameter<false>);
00122   } else {
00123     cbinfo->callback_(*cbinfo);
00124     delete cbinfo;
00125   }
00126 }
00127 
00128 template<typename T>
00129 template<bool isFirstPass>
00130 void
00131 WeakCallbackInfo<T>::invoketwofield(NAN_WEAK_TWOFIELD_CALLBACK_SIG_ data) {
00132   WeakCallbackInfo<T> *cbinfo = unwraptwofield(data);
00133   if (isFirstPass) {
00134     cbinfo->persistent_.Reset();
00135     data.SetSecondPassCallback(invoketwofield<false>);
00136   } else {
00137     cbinfo->callback_(*cbinfo);
00138     delete cbinfo;
00139   }
00140 }
00141 
00142 template<typename T>
00143 WeakCallbackInfo<T> *WeakCallbackInfo<T>::unwrapparameter(
00144     NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_ data) {
00145   WeakCallbackInfo<T> *cbinfo =
00146       static_cast<WeakCallbackInfo<T>*>(data.GetParameter());
00147   cbinfo->isolate_ = data.GetIsolate();
00148   return cbinfo;
00149 }
00150 
00151 template<typename T>
00152 WeakCallbackInfo<T> *WeakCallbackInfo<T>::unwraptwofield(
00153     NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_ data) {
00154   WeakCallbackInfo<T> *cbinfo =
00155       static_cast<WeakCallbackInfo<T>*>(data.GetInternalField(0));
00156   cbinfo->isolate_ = data.GetIsolate();
00157   return cbinfo;
00158 }
00159 
00160 #undef NAN_WEAK_PARAMETER_CALLBACK_SIG_
00161 #undef NAN_WEAK_TWOFIELD_CALLBACK_SIG_
00162 #undef NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_
00163 #undef NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_
00164 # elif NODE_MODULE_VERSION > NODE_0_12_MODULE_VERSION
00165 
00166 template<typename T>
00167 void
00168 WeakCallbackInfo<T>::invokeparameter(NAN_WEAK_PARAMETER_CALLBACK_SIG_ data) {
00169   WeakCallbackInfo<T> *cbinfo = unwrapparameter(data);
00170   cbinfo->persistent_.Reset();
00171   cbinfo->callback_(*cbinfo);
00172   delete cbinfo;
00173 }
00174 
00175 template<typename T>
00176 void
00177 WeakCallbackInfo<T>::invoketwofield(NAN_WEAK_TWOFIELD_CALLBACK_SIG_ data) {
00178   WeakCallbackInfo<T> *cbinfo = unwraptwofield(data);
00179   cbinfo->persistent_.Reset();
00180   cbinfo->callback_(*cbinfo);
00181   delete cbinfo;
00182 }
00183 
00184 template<typename T>
00185 WeakCallbackInfo<T> *WeakCallbackInfo<T>::unwrapparameter(
00186     NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_ data) {
00187   WeakCallbackInfo<T> *cbinfo =
00188        static_cast<WeakCallbackInfo<T>*>(data.GetParameter());
00189   cbinfo->isolate_ = data.GetIsolate();
00190   return cbinfo;
00191 }
00192 
00193 template<typename T>
00194 WeakCallbackInfo<T> *WeakCallbackInfo<T>::unwraptwofield(
00195     NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_ data) {
00196   WeakCallbackInfo<T> *cbinfo =
00197        static_cast<WeakCallbackInfo<T>*>(data.GetInternalField1());
00198   cbinfo->isolate_ = data.GetIsolate();
00199   return cbinfo;
00200 }
00201 
00202 #undef NAN_WEAK_PARAMETER_CALLBACK_SIG_
00203 #undef NAN_WEAK_TWOFIELD_CALLBACK_SIG_
00204 #undef NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_
00205 #undef NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_
00206 #elif NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
00207 
00208 template<typename T>
00209 template<typename S>
00210 void WeakCallbackInfo<T>::invoke(NAN_WEAK_CALLBACK_SIG_ data) {
00211   WeakCallbackInfo<T> *cbinfo = unwrap(data);
00212   cbinfo->persistent_.Reset();
00213   cbinfo->callback_(*cbinfo);
00214   delete cbinfo;
00215 }
00216 
00217 template<typename T>
00218 template<typename S>
00219 WeakCallbackInfo<T> *WeakCallbackInfo<T>::unwrap(
00220     NAN_WEAK_CALLBACK_DATA_TYPE_ data) {
00221   void *parameter = data.GetParameter();
00222   WeakCallbackInfo<T> *cbinfo =
00223       static_cast<WeakCallbackInfo<T>*>(parameter);
00224   cbinfo->isolate_ = data.GetIsolate();
00225   return cbinfo;
00226 }
00227 
00228 #undef NAN_WEAK_CALLBACK_SIG_
00229 #undef NAN_WEAK_CALLBACK_DATA_TYPE_
00230 #else
00231 
00232 template<typename T>
00233 void WeakCallbackInfo<T>::invoke(NAN_WEAK_CALLBACK_SIG_ data) {
00234   WeakCallbackInfo<T> *cbinfo = unwrap(data);
00235   cbinfo->persistent_.Dispose();
00236   cbinfo->persistent_.Clear();
00237   cbinfo->callback_(*cbinfo);
00238   delete cbinfo;
00239 }
00240 
00241 template<typename T>
00242 WeakCallbackInfo<T> *WeakCallbackInfo<T>::unwrap(
00243     NAN_WEAK_CALLBACK_DATA_TYPE_ data) {
00244   WeakCallbackInfo<T> *cbinfo =
00245       static_cast<WeakCallbackInfo<T>*>(data);
00246   cbinfo->isolate_ = v8::Isolate::GetCurrent();
00247   return cbinfo;
00248 }
00249 
00250 #undef NAN_WEAK_CALLBACK_SIG_
00251 #undef NAN_WEAK_CALLBACK_DATA_TYPE_
00252 #endif
00253 
00254 #if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 ||                      \
00255   (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
00256 template<typename T, typename M>
00257 template<typename P>
00258 inline void Persistent<T, M>::SetWeak(
00259     P *parameter
00260   , typename WeakCallbackInfo<P>::Callback callback
00261   , WeakCallbackType type) {
00262   WeakCallbackInfo<P> *wcbd;
00263   if (type == WeakCallbackType::kParameter) {
00264     wcbd = new WeakCallbackInfo<P>(
00265         reinterpret_cast<Persistent<v8::Value>*>(this)
00266       , callback
00267       , parameter);
00268     v8::PersistentBase<T>::SetWeak(
00269         wcbd
00270       , WeakCallbackInfo<P>::template invokeparameter<true>
00271       , type);
00272   } else {
00273     v8::Local<T>* self = reinterpret_cast<v8::Local<T>*>(this);
00274     assert((*self)->IsObject());
00275     int count = (*self)->InternalFieldCount();
00276     void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};
00277     for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {
00278       internal_fields[i] = (*self)->GetAlignedPointerFromInternalField(i);
00279     }
00280     wcbd = new WeakCallbackInfo<P>(
00281         reinterpret_cast<Persistent<v8::Value>*>(this)
00282       , callback
00283       , 0
00284       , internal_fields[0]
00285       , internal_fields[1]);
00286     (*self)->SetAlignedPointerInInternalField(0, wcbd);
00287     v8::PersistentBase<T>::SetWeak(
00288         static_cast<WeakCallbackInfo<P>*>(0)
00289       , WeakCallbackInfo<P>::template invoketwofield<true>
00290       , type);
00291   }
00292 }
00293 #elif NODE_MODULE_VERSION > IOJS_1_1_MODULE_VERSION
00294 template<typename T, typename M>
00295 template<typename P>
00296 inline void Persistent<T, M>::SetWeak(
00297     P *parameter
00298   , typename WeakCallbackInfo<P>::Callback callback
00299   , WeakCallbackType type) {
00300   WeakCallbackInfo<P> *wcbd;
00301   if (type == WeakCallbackType::kParameter) {
00302     wcbd = new WeakCallbackInfo<P>(
00303         reinterpret_cast<Persistent<v8::Value>*>(this)
00304       , callback
00305       , parameter);
00306     v8::PersistentBase<T>::SetPhantom(
00307         wcbd
00308       , WeakCallbackInfo<P>::invokeparameter);
00309   } else {
00310     v8::Local<T>* self = reinterpret_cast<v8::Local<T>*>(this);
00311     assert((*self)->IsObject());
00312     int count = (*self)->InternalFieldCount();
00313     void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};
00314     for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {
00315       internal_fields[i] = (*self)->GetAlignedPointerFromInternalField(i);
00316     }
00317     wcbd = new WeakCallbackInfo<P>(
00318         reinterpret_cast<Persistent<v8::Value>*>(this)
00319       , callback
00320       , 0
00321       , internal_fields[0]
00322       , internal_fields[1]);
00323     (*self)->SetAlignedPointerInInternalField(0, wcbd);
00324     v8::PersistentBase<T>::SetPhantom(
00325         static_cast<WeakCallbackInfo<P>*>(0)
00326       , WeakCallbackInfo<P>::invoketwofield
00327       , 0
00328       , count > 1 ? 1 : kNoInternalFieldIndex);
00329   }
00330 }
00331 #elif NODE_MODULE_VERSION > NODE_0_12_MODULE_VERSION
00332 template<typename T, typename M>
00333 template<typename P>
00334 inline void Persistent<T, M>::SetWeak(
00335     P *parameter
00336   , typename WeakCallbackInfo<P>::Callback callback
00337   , WeakCallbackType type) {
00338   WeakCallbackInfo<P> *wcbd;
00339   if (type == WeakCallbackType::kParameter) {
00340     wcbd = new WeakCallbackInfo<P>(
00341         reinterpret_cast<Persistent<v8::Value>*>(this)
00342       , callback
00343       , parameter);
00344     v8::PersistentBase<T>::SetPhantom(
00345         wcbd
00346       , WeakCallbackInfo<P>::invokeparameter);
00347   } else {
00348     v8::Local<T>* self = reinterpret_cast<v8::Local<T>*>(this);
00349     assert((*self)->IsObject());
00350     int count = (*self)->InternalFieldCount();
00351     void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};
00352     for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {
00353       internal_fields[i] = (*self)->GetAlignedPointerFromInternalField(i);
00354     }
00355     wcbd = new WeakCallbackInfo<P>(
00356         reinterpret_cast<Persistent<v8::Value>*>(this)
00357       , callback
00358       , 0
00359       , internal_fields[0]
00360       , internal_fields[1]);
00361     (*self)->SetAlignedPointerInInternalField(0, wcbd);
00362     v8::PersistentBase<T>::SetPhantom(
00363         WeakCallbackInfo<P>::invoketwofield
00364       , 0
00365       , count > 1 ? 1 : kNoInternalFieldIndex);
00366   }
00367 }
00368 #elif NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
00369 template<typename T, typename M>
00370 template<typename P>
00371 inline void Persistent<T, M>::SetWeak(
00372     P *parameter
00373   , typename WeakCallbackInfo<P>::Callback callback
00374   , WeakCallbackType type) {
00375   WeakCallbackInfo<P> *wcbd;
00376   if (type == WeakCallbackType::kParameter) {
00377     wcbd = new WeakCallbackInfo<P>(
00378         reinterpret_cast<Persistent<v8::Value>*>(this)
00379       , callback
00380       , parameter);
00381     v8::PersistentBase<T>::SetWeak(wcbd, WeakCallbackInfo<P>::invoke);
00382   } else {
00383     v8::Local<T>* self = reinterpret_cast<v8::Local<T>*>(this);
00384     assert((*self)->IsObject());
00385     int count = (*self)->InternalFieldCount();
00386     void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};
00387     for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {
00388       internal_fields[i] = (*self)->GetAlignedPointerFromInternalField(i);
00389     }
00390     wcbd = new WeakCallbackInfo<P>(
00391         reinterpret_cast<Persistent<v8::Value>*>(this)
00392       , callback
00393       , 0
00394       , internal_fields[0]
00395       , internal_fields[1]);
00396     v8::PersistentBase<T>::SetWeak(wcbd, WeakCallbackInfo<P>::invoke);
00397   }
00398 }
00399 #else
00400 template<typename T>
00401 template<typename P>
00402 inline void PersistentBase<T>::SetWeak(
00403     P *parameter
00404   , typename WeakCallbackInfo<P>::Callback callback
00405   , WeakCallbackType type) {
00406   WeakCallbackInfo<P> *wcbd;
00407   if (type == WeakCallbackType::kParameter) {
00408     wcbd = new WeakCallbackInfo<P>(
00409         reinterpret_cast<Persistent<v8::Value>*>(this)
00410       , callback
00411       , parameter);
00412     persistent.MakeWeak(wcbd, WeakCallbackInfo<P>::invoke);
00413   } else {
00414     v8::Local<T>* self = reinterpret_cast<v8::Local<T>*>(this);
00415     assert((*self)->IsObject());
00416     int count = (*self)->InternalFieldCount();
00417     void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};
00418     for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {
00419       internal_fields[i] = (*self)->GetPointerFromInternalField(i);
00420     }
00421     wcbd = new WeakCallbackInfo<P>(
00422         reinterpret_cast<Persistent<v8::Value>*>(this)
00423       , callback
00424       , 0
00425       , internal_fields[0]
00426       , internal_fields[1]);
00427     persistent.MakeWeak(wcbd, WeakCallbackInfo<P>::invoke);
00428   }
00429 }
00430 #endif
00431 
00432 #endif  // NAN_WEAK_H_


dji_ronin
Author(s):
autogenerated on Sat Jun 8 2019 20:15:31