|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef NAN_OBJECT_WRAP_H_ |
|
#define NAN_OBJECT_WRAP_H_ |
|
|
|
class ObjectWrap { |
|
public: |
|
ObjectWrap() { |
|
refs_ = 0; |
|
} |
|
|
|
|
|
virtual ~ObjectWrap() { |
|
if (persistent().IsEmpty()) { |
|
return; |
|
} |
|
|
|
assert(persistent().IsNearDeath()); |
|
persistent().ClearWeak(); |
|
persistent().Reset(); |
|
} |
|
|
|
|
|
template <class T> |
|
static inline T* Unwrap(v8::Local<v8::Object> object) { |
|
assert(!object.IsEmpty()); |
|
assert(object->InternalFieldCount() > 0); |
|
|
|
|
|
void* ptr = GetInternalFieldPointer(object, 0); |
|
ObjectWrap* wrap = static_cast<ObjectWrap*>(ptr); |
|
return static_cast<T*>(wrap); |
|
} |
|
|
|
|
|
inline v8::Local<v8::Object> handle() const { |
|
return New(handle_); |
|
} |
|
|
|
|
|
inline Persistent<v8::Object>& persistent() { |
|
return handle_; |
|
} |
|
|
|
|
|
protected: |
|
inline void Wrap(v8::Local<v8::Object> object) { |
|
assert(persistent().IsEmpty()); |
|
assert(object->InternalFieldCount() > 0); |
|
SetInternalFieldPointer(object, 0, this); |
|
persistent().Reset(object); |
|
MakeWeak(); |
|
} |
|
|
|
#if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \ |
|
(V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3)) |
|
|
|
inline void MakeWeak() { |
|
persistent().v8::PersistentBase<v8::Object>::SetWeak( |
|
this, WeakCallback, v8::WeakCallbackType::kParameter); |
|
persistent().MarkIndependent(); |
|
} |
|
|
|
#elif NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION |
|
|
|
inline void MakeWeak() { |
|
persistent().v8::PersistentBase<v8::Object>::SetWeak(this, WeakCallback); |
|
persistent().MarkIndependent(); |
|
} |
|
|
|
#else |
|
|
|
inline void MakeWeak() { |
|
persistent().persistent.MakeWeak(this, WeakCallback); |
|
persistent().MarkIndependent(); |
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
virtual void Ref() { |
|
assert(!persistent().IsEmpty()); |
|
persistent().ClearWeak(); |
|
refs_++; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
virtual void Unref() { |
|
assert(!persistent().IsEmpty()); |
|
assert(!persistent().IsWeak()); |
|
assert(refs_ > 0); |
|
if (--refs_ == 0) |
|
MakeWeak(); |
|
} |
|
|
|
int refs_; |
|
|
|
private: |
|
NAN_DISALLOW_ASSIGN_COPY_MOVE(ObjectWrap) |
|
#if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \ |
|
(V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3)) |
|
|
|
static void |
|
WeakCallback(v8::WeakCallbackInfo<ObjectWrap> const& info) { |
|
ObjectWrap* wrap = info.GetParameter(); |
|
assert(wrap->refs_ == 0); |
|
assert(wrap->handle_.IsNearDeath()); |
|
wrap->handle_.Reset(); |
|
delete wrap; |
|
} |
|
|
|
#elif NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION |
|
|
|
static void |
|
WeakCallback(v8::WeakCallbackData<v8::Object, ObjectWrap> const& data) { |
|
ObjectWrap* wrap = data.GetParameter(); |
|
assert(wrap->refs_ == 0); |
|
assert(wrap->handle_.IsNearDeath()); |
|
wrap->handle_.Reset(); |
|
delete wrap; |
|
} |
|
|
|
#else |
|
|
|
static void WeakCallback(v8::Persistent<v8::Value> value, void *data) { |
|
ObjectWrap *wrap = static_cast<ObjectWrap*>(data); |
|
assert(wrap->refs_ == 0); |
|
assert(wrap->handle_.IsNearDeath()); |
|
wrap->handle_.Reset(); |
|
delete wrap; |
|
} |
|
|
|
#endif |
|
Persistent<v8::Object> handle_; |
|
}; |
|
|
|
|
|
#endif |
|
|