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_
- #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_
|