|
|
/*********************************************************************
* 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_ #endif
template<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> void WeakCallbackInfo<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> void WeakCallbackInfo<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_VERSION
template<typename T> void WeakCallbackInfo<T>::invokeparameter(NAN_WEAK_PARAMETER_CALLBACK_SIG_ data) { WeakCallbackInfo<T> *cbinfo = unwrapparameter(data); cbinfo->persistent_.Reset(); cbinfo->callback_(*cbinfo); delete cbinfo; }
template<typename T> void WeakCallbackInfo<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_VERSION
template<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_
#else
template<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_VERSION
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>::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_VERSION
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>::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_VERSION
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>::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); } } #else
template<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_
|