package.nan_weak.h Maven / Gradle / Ivy
Show all versions of nan Show documentation
/*********************************************************************
* NAN - Native Abstractions for Node.js
*
* Copyright (c) 2018 NAN contributors
*
* MIT License
********************************************************************/
#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 > 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 > 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 > const&
# define NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_ \
v8::InternalFieldsCallbackData, 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 > 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, NAN_WEAK_CALLBACK_DATA_TYPE_
#endif
template
class WeakCallbackInfo {
public:
typedef void (*Callback)(const WeakCallbackInfo& data);
WeakCallbackInfo(
Persistent *persistent
, Callback callback
, void *parameter
, void *field1 = 0
, void *field2 = 0) :
callback_(callback), isolate_(0), parameter_(parameter) {
std::memcpy(&persistent_, persistent, sizeof (v8::Persistent));
internal_fields_[0] = field1;
internal_fields_[1] = field2;
}
inline v8::Isolate *GetIsolate() const { return isolate_; }
inline T *GetParameter() const { return static_cast(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 persistent_;
template friend class Persistent;
template friend class PersistentBase;
#if NODE_MODULE_VERSION <= NODE_0_12_MODULE_VERSION
# if NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
template
static void invoke(NAN_WEAK_CALLBACK_SIG_ data);
template
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
static void invokeparameter(NAN_WEAK_PARAMETER_CALLBACK_SIG_ data);
template
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
template
void
WeakCallbackInfo::invokeparameter(NAN_WEAK_PARAMETER_CALLBACK_SIG_ data) {
WeakCallbackInfo *cbinfo = unwrapparameter(data);
if (isFirstPass) {
cbinfo->persistent_.Reset();
data.SetSecondPassCallback(invokeparameter);
} else {
cbinfo->callback_(*cbinfo);
delete cbinfo;
}
}
template
template
void
WeakCallbackInfo::invoketwofield(NAN_WEAK_TWOFIELD_CALLBACK_SIG_ data) {
WeakCallbackInfo *cbinfo = unwraptwofield(data);
if (isFirstPass) {
cbinfo->persistent_.Reset();
data.SetSecondPassCallback(invoketwofield);
} else {
cbinfo->callback_(*cbinfo);
delete cbinfo;
}
}
template
WeakCallbackInfo *WeakCallbackInfo::unwrapparameter(
NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_ data) {
WeakCallbackInfo *cbinfo =
static_cast*>(data.GetParameter());
cbinfo->isolate_ = data.GetIsolate();
return cbinfo;
}
template
WeakCallbackInfo *WeakCallbackInfo::unwraptwofield(
NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_ data) {
WeakCallbackInfo *cbinfo =
static_cast*>(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
void
WeakCallbackInfo::invokeparameter(NAN_WEAK_PARAMETER_CALLBACK_SIG_ data) {
WeakCallbackInfo *cbinfo = unwrapparameter(data);
cbinfo->persistent_.Reset();
cbinfo->callback_(*cbinfo);
delete cbinfo;
}
template
void
WeakCallbackInfo::invoketwofield(NAN_WEAK_TWOFIELD_CALLBACK_SIG_ data) {
WeakCallbackInfo *cbinfo = unwraptwofield(data);
cbinfo->persistent_.Reset();
cbinfo->callback_(*cbinfo);
delete cbinfo;
}
template
WeakCallbackInfo *WeakCallbackInfo::unwrapparameter(
NAN_WEAK_PARAMETER_CALLBACK_DATA_TYPE_ data) {
WeakCallbackInfo *cbinfo =
static_cast*>(data.GetParameter());
cbinfo->isolate_ = data.GetIsolate();
return cbinfo;
}
template
WeakCallbackInfo *WeakCallbackInfo::unwraptwofield(
NAN_WEAK_TWOFIELD_CALLBACK_DATA_TYPE_ data) {
WeakCallbackInfo *cbinfo =
static_cast*>(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
template
void WeakCallbackInfo::invoke(NAN_WEAK_CALLBACK_SIG_ data) {
WeakCallbackInfo *cbinfo = unwrap(data);
cbinfo->persistent_.Reset();
cbinfo->callback_(*cbinfo);
delete cbinfo;
}
template
template
WeakCallbackInfo *WeakCallbackInfo::unwrap(
NAN_WEAK_CALLBACK_DATA_TYPE_ data) {
void *parameter = data.GetParameter();
WeakCallbackInfo *cbinfo =
static_cast*>(parameter);
cbinfo->isolate_ = data.GetIsolate();
return cbinfo;
}
#undef NAN_WEAK_CALLBACK_SIG_
#undef NAN_WEAK_CALLBACK_DATA_TYPE_
#else
template
void WeakCallbackInfo::invoke(NAN_WEAK_CALLBACK_SIG_ data) {
WeakCallbackInfo *cbinfo = unwrap(data);
cbinfo->persistent_.Dispose();
cbinfo->persistent_.Clear();
cbinfo->callback_(*cbinfo);
delete cbinfo;
}
template
WeakCallbackInfo *WeakCallbackInfo::unwrap(
NAN_WEAK_CALLBACK_DATA_TYPE_ data) {
WeakCallbackInfo *cbinfo =
static_cast*>(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
template
inline void Persistent::SetWeak(
P *parameter
, typename WeakCallbackInfo::Callback callback
, WeakCallbackType type) {
WeakCallbackInfo
*wcbd;
if (type == WeakCallbackType::kParameter) {
wcbd = new WeakCallbackInfo
(
reinterpret_cast*>(this)
, callback
, parameter);
v8::PersistentBase::SetWeak(
wcbd
, WeakCallbackInfo::template invokeparameter
, type);
} else {
v8::Local* self_v(reinterpret_cast*>(this));
assert((*self_v)->IsObject());
v8::Local self((*self_v).As());
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(
reinterpret_cast*>(this)
, callback
, 0
, internal_fields[0]
, internal_fields[1]);
self->SetAlignedPointerInInternalField(0, wcbd);
v8::PersistentBase::SetWeak(
static_cast*>(0)
, WeakCallbackInfo::template invoketwofield
, type);
}
}
#elif NODE_MODULE_VERSION > IOJS_1_1_MODULE_VERSION
template
template
inline void Persistent::SetWeak(
P *parameter
, typename WeakCallbackInfo::Callback callback
, WeakCallbackType type) {
WeakCallbackInfo
*wcbd;
if (type == WeakCallbackType::kParameter) {
wcbd = new WeakCallbackInfo
(
reinterpret_cast*>(this)
, callback
, parameter);
v8::PersistentBase::SetPhantom(
wcbd
, WeakCallbackInfo::invokeparameter);
} else {
v8::Local* self_v(reinterpret_cast*>(this));
assert((*self_v)->IsObject());
v8::Local self((*self_v).As());
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(
reinterpret_cast*>(this)
, callback
, 0
, internal_fields[0]
, internal_fields[1]);
self->SetAlignedPointerInInternalField(0, wcbd);
v8::PersistentBase::SetPhantom(
static_cast*>(0)
, WeakCallbackInfo::invoketwofield
, 0
, count > 1 ? 1 : kNoInternalFieldIndex);
}
}
#elif NODE_MODULE_VERSION > NODE_0_12_MODULE_VERSION
template
template
inline void Persistent::SetWeak(
P *parameter
, typename WeakCallbackInfo::Callback callback
, WeakCallbackType type) {
WeakCallbackInfo
*wcbd;
if (type == WeakCallbackType::kParameter) {
wcbd = new WeakCallbackInfo
(
reinterpret_cast*>(this)
, callback
, parameter);
v8::PersistentBase::SetPhantom(
wcbd
, WeakCallbackInfo::invokeparameter);
} else {
v8::Local* self_v(reinterpret_cast*>(this));
assert((*self_v)->IsObject());
v8::Local self((*self_v).As());
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(
reinterpret_cast*>(this)
, callback
, 0
, internal_fields[0]
, internal_fields[1]);
self->SetAlignedPointerInInternalField(0, wcbd);
v8::PersistentBase::SetPhantom(
WeakCallbackInfo::invoketwofield
, 0
, count > 1 ? 1 : kNoInternalFieldIndex);
}
}
#elif NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
template
template
inline void Persistent::SetWeak(
P *parameter
, typename WeakCallbackInfo::Callback callback
, WeakCallbackType type) {
WeakCallbackInfo
*wcbd;
if (type == WeakCallbackType::kParameter) {
wcbd = new WeakCallbackInfo
(
reinterpret_cast*>(this)
, callback
, parameter);
v8::PersistentBase::SetWeak(wcbd, WeakCallbackInfo::invoke);
} else {
v8::Local* self_v(reinterpret_cast*>(this));
assert((*self_v)->IsObject());
v8::Local self((*self_v).As());
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(
reinterpret_cast*>(this)
, callback
, 0
, internal_fields[0]
, internal_fields[1]);
v8::PersistentBase::SetWeak(wcbd, WeakCallbackInfo::invoke);
}
}
#else
template
template
inline void PersistentBase::SetWeak(
P *parameter
, typename WeakCallbackInfo::Callback callback
, WeakCallbackType type) {
WeakCallbackInfo
*wcbd;
if (type == WeakCallbackType::kParameter) {
wcbd = new WeakCallbackInfo
(
reinterpret_cast*>(this)
, callback
, parameter);
persistent.MakeWeak(wcbd, WeakCallbackInfo::invoke);
} else {
v8::Local* self_v(reinterpret_cast*>(this));
assert((*self_v)->IsObject());
v8::Local self((*self_v).As());
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(
reinterpret_cast*>(this)
, callback
, 0
, internal_fields[0]
, internal_fields[1]);
persistent.MakeWeak(wcbd, WeakCallbackInfo::invoke);
}
}
#endif
#endif // NAN_WEAK_H_