| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437 | /********************************************************************* * NAN - Native Abstractions for Node.js * * Copyright (c) 2018 NAN contributors * * MIT License <https://github.com/nodejs/nan/blob/master/LICENSE.md> ********************************************************************/#ifndef NAN_WEAK_H_#define NAN_WEAK_H_static const int kInternalFieldsInWeakCallback = 2;static const int kNoInternalFieldIndex = -1;#if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 ||                      \  (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))# define NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_ \    v8::WeakCallbackInfo<WeakCallbackInfo<T> > const&# define NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_ \    NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_# define NAN_WEAK_PARAMETER_CALLBACK_SIG_ NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_# define NAN_WEAK_TWOFIELD_CALLBACK_SIG_ NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_#elif NODE_MODULE_VERSION > IOJS_1_1_MODULE_VERSION# define NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_ \    v8::PhantomCallbackData<WeakCallbackInfo<T> > const&# define NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_ \    NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_# define NAN_WEAK_PARAMETER_CALLBACK_SIG_ NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_# define NAN_WEAK_TWOFIELD_CALLBACK_SIG_ NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_#elif NODE_MODULE_VERSION > NODE_0_12_MODULE_VERSION# define NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_ \    v8::PhantomCallbackData<WeakCallbackInfo<T> > const&# define NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_ \    v8::InternalFieldsCallbackData<WeakCallbackInfo<T>, void> const&# define NAN_WEAK_PARAMETER_CALLBACK_SIG_ NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_# define NAN_WEAK_TWOFIELD_CALLBACK_SIG_ NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_#elif NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION# define NAN_WEAK_CALLBACK_DATA_TYPE_ \    v8::WeakCallbackData<S, WeakCallbackInfo<T> > const&# define NAN_WEAK_CALLBACK_SIG_ NAN_WEAK_CALLBACK_DATA_TYPE_#else# define NAN_WEAK_CALLBACK_DATA_TYPE_ void *# define NAN_WEAK_CALLBACK_SIG_ \    v8::Persistent<v8::Value>, NAN_WEAK_CALLBACK_DATA_TYPE_#endiftemplate<typename T>class WeakCallbackInfo { public:  typedef void (*Callback)(const WeakCallbackInfo<T>& data);  WeakCallbackInfo(      Persistent<v8::Value> *persistent    , Callback callback    , void *parameter    , void *field1 = 0    , void *field2 = 0) :        callback_(callback), isolate_(0), parameter_(parameter) {    std::memcpy(&persistent_, persistent, sizeof (v8::Persistent<v8::Value>));    internal_fields_[0] = field1;    internal_fields_[1] = field2;  }  inline v8::Isolate *GetIsolate() const { return isolate_; }  inline T *GetParameter() const { return static_cast<T*>(parameter_); }  inline void *GetInternalField(int index) const {    assert((index == 0 || index == 1) && "internal field index out of bounds");    if (index == 0) {      return internal_fields_[0];    } else {      return internal_fields_[1];    }  } private:  NAN_DISALLOW_ASSIGN_COPY_MOVE(WeakCallbackInfo)  Callback callback_;  v8::Isolate *isolate_;  void *parameter_;  void *internal_fields_[kInternalFieldsInWeakCallback];  v8::Persistent<v8::Value> persistent_;  template<typename S, typename M> friend class Persistent;  template<typename S> friend class PersistentBase;#if NODE_MODULE_VERSION <= NODE_0_12_MODULE_VERSION# if NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION  template<typename S>  static void invoke(NAN_WEAK_CALLBACK_SIG_ data);  template<typename S>  static WeakCallbackInfo *unwrap(NAN_WEAK_CALLBACK_DATA_TYPE_ data);# else  static void invoke(NAN_WEAK_CALLBACK_SIG_ data);  static WeakCallbackInfo *unwrap(NAN_WEAK_CALLBACK_DATA_TYPE_ data);# endif#else# if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 ||                     \  (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))  template<bool isFirstPass>  static void invokeparameter(NAN_WEAK_PARAMETER_CALLBACK_SIG_ data);  template<bool isFirstPass>  static void invoketwofield(NAN_WEAK_TWOFIELD_CALLBACK_SIG_ data);# else  static void invokeparameter(NAN_WEAK_PARAMETER_CALLBACK_SIG_ data);  static void invoketwofield(NAN_WEAK_TWOFIELD_CALLBACK_SIG_ data);# endif  static WeakCallbackInfo *unwrapparameter(      NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_ data);  static WeakCallbackInfo *unwraptwofield(      NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_ data);#endif};#if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 ||                      \  (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))template<typename T>template<bool isFirstPass>voidWeakCallbackInfo<T>::invokeparameter(NAN_WEAK_PARAMETER_CALLBACK_SIG_ data) {  WeakCallbackInfo<T> *cbinfo = unwrapparameter(data);  if (isFirstPass) {    cbinfo->persistent_.Reset();    data.SetSecondPassCallback(invokeparameter<false>);  } else {    cbinfo->callback_(*cbinfo);    delete cbinfo;  }}template<typename T>template<bool isFirstPass>voidWeakCallbackInfo<T>::invoketwofield(NAN_WEAK_TWOFIELD_CALLBACK_SIG_ data) {  WeakCallbackInfo<T> *cbinfo = unwraptwofield(data);  if (isFirstPass) {    cbinfo->persistent_.Reset();    data.SetSecondPassCallback(invoketwofield<false>);  } else {    cbinfo->callback_(*cbinfo);    delete cbinfo;  }}template<typename T>WeakCallbackInfo<T> *WeakCallbackInfo<T>::unwrapparameter(    NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_ data) {  WeakCallbackInfo<T> *cbinfo =      static_cast<WeakCallbackInfo<T>*>(data.GetParameter());  cbinfo->isolate_ = data.GetIsolate();  return cbinfo;}template<typename T>WeakCallbackInfo<T> *WeakCallbackInfo<T>::unwraptwofield(    NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_ data) {  WeakCallbackInfo<T> *cbinfo =      static_cast<WeakCallbackInfo<T>*>(data.GetInternalField(0));  cbinfo->isolate_ = data.GetIsolate();  return cbinfo;}#undef NAN_WEAK_PARAMETER_CALLBACK_SIG_#undef NAN_WEAK_TWOFIELD_CALLBACK_SIG_#undef NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_#undef NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_# elif NODE_MODULE_VERSION > NODE_0_12_MODULE_VERSIONtemplate<typename T>voidWeakCallbackInfo<T>::invokeparameter(NAN_WEAK_PARAMETER_CALLBACK_SIG_ data) {  WeakCallbackInfo<T> *cbinfo = unwrapparameter(data);  cbinfo->persistent_.Reset();  cbinfo->callback_(*cbinfo);  delete cbinfo;}template<typename T>voidWeakCallbackInfo<T>::invoketwofield(NAN_WEAK_TWOFIELD_CALLBACK_SIG_ data) {  WeakCallbackInfo<T> *cbinfo = unwraptwofield(data);  cbinfo->persistent_.Reset();  cbinfo->callback_(*cbinfo);  delete cbinfo;}template<typename T>WeakCallbackInfo<T> *WeakCallbackInfo<T>::unwrapparameter(    NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_ data) {  WeakCallbackInfo<T> *cbinfo =       static_cast<WeakCallbackInfo<T>*>(data.GetParameter());  cbinfo->isolate_ = data.GetIsolate();  return cbinfo;}template<typename T>WeakCallbackInfo<T> *WeakCallbackInfo<T>::unwraptwofield(    NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_ data) {  WeakCallbackInfo<T> *cbinfo =       static_cast<WeakCallbackInfo<T>*>(data.GetInternalField1());  cbinfo->isolate_ = data.GetIsolate();  return cbinfo;}#undef NAN_WEAK_PARAMETER_CALLBACK_SIG_#undef NAN_WEAK_TWOFIELD_CALLBACK_SIG_#undef NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_#undef NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_#elif NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSIONtemplate<typename T>template<typename S>void WeakCallbackInfo<T>::invoke(NAN_WEAK_CALLBACK_SIG_ data) {  WeakCallbackInfo<T> *cbinfo = unwrap(data);  cbinfo->persistent_.Reset();  cbinfo->callback_(*cbinfo);  delete cbinfo;}template<typename T>template<typename S>WeakCallbackInfo<T> *WeakCallbackInfo<T>::unwrap(    NAN_WEAK_CALLBACK_DATA_TYPE_ data) {  void *parameter = data.GetParameter();  WeakCallbackInfo<T> *cbinfo =      static_cast<WeakCallbackInfo<T>*>(parameter);  cbinfo->isolate_ = data.GetIsolate();  return cbinfo;}#undef NAN_WEAK_CALLBACK_SIG_#undef NAN_WEAK_CALLBACK_DATA_TYPE_#elsetemplate<typename T>void WeakCallbackInfo<T>::invoke(NAN_WEAK_CALLBACK_SIG_ data) {  WeakCallbackInfo<T> *cbinfo = unwrap(data);  cbinfo->persistent_.Dispose();  cbinfo->persistent_.Clear();  cbinfo->callback_(*cbinfo);  delete cbinfo;}template<typename T>WeakCallbackInfo<T> *WeakCallbackInfo<T>::unwrap(    NAN_WEAK_CALLBACK_DATA_TYPE_ data) {  WeakCallbackInfo<T> *cbinfo =      static_cast<WeakCallbackInfo<T>*>(data);  cbinfo->isolate_ = v8::Isolate::GetCurrent();  return cbinfo;}#undef NAN_WEAK_CALLBACK_SIG_#undef NAN_WEAK_CALLBACK_DATA_TYPE_#endif#if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 ||                      \  (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))template<typename T, typename M>template<typename P>inline void Persistent<T, M>::SetWeak(    P *parameter  , typename WeakCallbackInfo<P>::Callback callback  , WeakCallbackType type) {  WeakCallbackInfo<P> *wcbd;  if (type == WeakCallbackType::kParameter) {    wcbd = new WeakCallbackInfo<P>(        reinterpret_cast<Persistent<v8::Value>*>(this)      , callback      , parameter);    v8::PersistentBase<T>::SetWeak(        wcbd      , WeakCallbackInfo<P>::template invokeparameter<true>      , type);  } else {    v8::Local<v8::Value>* self_v(reinterpret_cast<v8::Local<v8::Value>*>(this));    assert((*self_v)->IsObject());    v8::Local<v8::Object> self((*self_v).As<v8::Object>());    int count = self->InternalFieldCount();    void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};    for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {      internal_fields[i] = self->GetAlignedPointerFromInternalField(i);    }    wcbd = new WeakCallbackInfo<P>(        reinterpret_cast<Persistent<v8::Value>*>(this)      , callback      , 0      , internal_fields[0]      , internal_fields[1]);    self->SetAlignedPointerInInternalField(0, wcbd);    v8::PersistentBase<T>::SetWeak(        static_cast<WeakCallbackInfo<P>*>(0)      , WeakCallbackInfo<P>::template invoketwofield<true>      , type);  }}#elif NODE_MODULE_VERSION > IOJS_1_1_MODULE_VERSIONtemplate<typename T, typename M>template<typename P>inline void Persistent<T, M>::SetWeak(    P *parameter  , typename WeakCallbackInfo<P>::Callback callback  , WeakCallbackType type) {  WeakCallbackInfo<P> *wcbd;  if (type == WeakCallbackType::kParameter) {    wcbd = new WeakCallbackInfo<P>(        reinterpret_cast<Persistent<v8::Value>*>(this)      , callback      , parameter);    v8::PersistentBase<T>::SetPhantom(        wcbd      , WeakCallbackInfo<P>::invokeparameter);  } else {    v8::Local<v8::Value>* self_v(reinterpret_cast<v8::Local<v8::Value>*>(this));    assert((*self_v)->IsObject());    v8::Local<v8::Object> self((*self_v).As<v8::Object>());    int count = self->InternalFieldCount();    void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};    for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {      internal_fields[i] = self->GetAlignedPointerFromInternalField(i);    }    wcbd = new WeakCallbackInfo<P>(        reinterpret_cast<Persistent<v8::Value>*>(this)      , callback      , 0      , internal_fields[0]      , internal_fields[1]);    self->SetAlignedPointerInInternalField(0, wcbd);    v8::PersistentBase<T>::SetPhantom(        static_cast<WeakCallbackInfo<P>*>(0)      , WeakCallbackInfo<P>::invoketwofield      , 0      , count > 1 ? 1 : kNoInternalFieldIndex);  }}#elif NODE_MODULE_VERSION > NODE_0_12_MODULE_VERSIONtemplate<typename T, typename M>template<typename P>inline void Persistent<T, M>::SetWeak(    P *parameter  , typename WeakCallbackInfo<P>::Callback callback  , WeakCallbackType type) {  WeakCallbackInfo<P> *wcbd;  if (type == WeakCallbackType::kParameter) {    wcbd = new WeakCallbackInfo<P>(        reinterpret_cast<Persistent<v8::Value>*>(this)      , callback      , parameter);    v8::PersistentBase<T>::SetPhantom(        wcbd      , WeakCallbackInfo<P>::invokeparameter);  } else {    v8::Local<v8::Value>* self_v(reinterpret_cast<v8::Local<v8::Value>*>(this));    assert((*self_v)->IsObject());    v8::Local<v8::Object> self((*self_v).As<v8::Object>());    int count = self->InternalFieldCount();    void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};    for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {      internal_fields[i] = self->GetAlignedPointerFromInternalField(i);    }    wcbd = new WeakCallbackInfo<P>(        reinterpret_cast<Persistent<v8::Value>*>(this)      , callback      , 0      , internal_fields[0]      , internal_fields[1]);    self->SetAlignedPointerInInternalField(0, wcbd);    v8::PersistentBase<T>::SetPhantom(        WeakCallbackInfo<P>::invoketwofield      , 0      , count > 1 ? 1 : kNoInternalFieldIndex);  }}#elif NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSIONtemplate<typename T, typename M>template<typename P>inline void Persistent<T, M>::SetWeak(    P *parameter  , typename WeakCallbackInfo<P>::Callback callback  , WeakCallbackType type) {  WeakCallbackInfo<P> *wcbd;  if (type == WeakCallbackType::kParameter) {    wcbd = new WeakCallbackInfo<P>(        reinterpret_cast<Persistent<v8::Value>*>(this)      , callback      , parameter);    v8::PersistentBase<T>::SetWeak(wcbd, WeakCallbackInfo<P>::invoke);  } else {    v8::Local<v8::Value>* self_v(reinterpret_cast<v8::Local<v8::Value>*>(this));    assert((*self_v)->IsObject());    v8::Local<v8::Object> self((*self_v).As<v8::Object>());    int count = self->InternalFieldCount();    void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};    for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {      internal_fields[i] = self->GetAlignedPointerFromInternalField(i);    }    wcbd = new WeakCallbackInfo<P>(        reinterpret_cast<Persistent<v8::Value>*>(this)      , callback      , 0      , internal_fields[0]      , internal_fields[1]);    v8::PersistentBase<T>::SetWeak(wcbd, WeakCallbackInfo<P>::invoke);  }}#elsetemplate<typename T>template<typename P>inline void PersistentBase<T>::SetWeak(    P *parameter  , typename WeakCallbackInfo<P>::Callback callback  , WeakCallbackType type) {  WeakCallbackInfo<P> *wcbd;  if (type == WeakCallbackType::kParameter) {    wcbd = new WeakCallbackInfo<P>(        reinterpret_cast<Persistent<v8::Value>*>(this)      , callback      , parameter);    persistent.MakeWeak(wcbd, WeakCallbackInfo<P>::invoke);  } else {    v8::Local<v8::Value>* self_v(reinterpret_cast<v8::Local<v8::Value>*>(this));    assert((*self_v)->IsObject());    v8::Local<v8::Object> self((*self_v).As<v8::Object>());    int count = self->InternalFieldCount();    void *internal_fields[kInternalFieldsInWeakCallback] = {0, 0};    for (int i = 0; i < count && i < kInternalFieldsInWeakCallback; i++) {      internal_fields[i] = self->GetPointerFromInternalField(i);    }    wcbd = new WeakCallbackInfo<P>(        reinterpret_cast<Persistent<v8::Value>*>(this)      , callback      , 0      , internal_fields[0]      , internal_fields[1]);    persistent.MakeWeak(wcbd, WeakCallbackInfo<P>::invoke);  }}#endif#endif  // NAN_WEAK_H_
 |