Skip to content

Commit

Permalink
Add convenience getter for Local from Persistent
Browse files Browse the repository at this point in the history
  • Loading branch information
kkoopa committed Oct 11, 2015
1 parent 9f42b4c commit c469041
Show file tree
Hide file tree
Showing 8 changed files with 226 additions and 88 deletions.
9 changes: 3 additions & 6 deletions nan.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,15 +169,12 @@ typedef v8::String::ExternalOneByteStringResource

#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
template<typename T>
class NonCopyablePersistentTraits :
public v8::NonCopyablePersistentTraits<T> {};
class NonCopyablePersistentTraits;
template<typename T>
class CopyablePersistentTraits :
public v8::CopyablePersistentTraits<T> {};
class CopyablePersistentTraits;

template<typename T>
class PersistentBase :
public v8::PersistentBase<T> {};
class PersistentBase;

template<typename T, typename M = v8::NonCopyablePersistentTraits<T> >
class Persistent;
Expand Down
2 changes: 1 addition & 1 deletion nan_callbacks_12_inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class ReturnValue {
(V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && \
(V8_MINOR_VERSION > 5 || (V8_MINOR_VERSION == 5 && \
defined(V8_BUILD_NUMBER) && V8_BUILD_NUMBER >= 8))))
value_.Set(handle);
value_.Set(handle.persistent);
#else
value_.Set(*reinterpret_cast<const v8::Persistent<S>*>(&handle));
const_cast<Global<S> &>(handle).Reset();
Expand Down
4 changes: 2 additions & 2 deletions nan_implementation_12_inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -393,12 +393,12 @@ inline v8::Local<T> New(v8::Persistent<T, M> const& p) {

template <typename T, typename M>
inline v8::Local<T> New(Persistent<T, M> const& p) {
return v8::Local<T>::New(v8::Isolate::GetCurrent(), p);
return v8::Local<T>::New(v8::Isolate::GetCurrent(), p.persistent);
}

template <typename T>
inline v8::Local<T> New(Global<T> const& p) {
return v8::Local<T>::New(v8::Isolate::GetCurrent(), p);
return v8::Local<T>::New(v8::Isolate::GetCurrent(), p.persistent);
}

#endif // NAN_IMPLEMENTATION_12_INL_H_
4 changes: 2 additions & 2 deletions nan_object_wrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,15 @@ class ObjectWrap {
(V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))

inline void MakeWeak() {
persistent().v8::PersistentBase<v8::Object>::SetWeak(
persistent().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().persistent.v8::PersistentBase<v8::Object>::SetWeak(this, WeakCallback);
persistent().MarkIndependent();
}

Expand Down
257 changes: 197 additions & 60 deletions nan_persistent_12_inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,56 @@
#ifndef NAN_PERSISTENT_12_INL_H_
#define NAN_PERSISTENT_12_INL_H_

template<typename T, typename M> class Persistent :
public v8::Persistent<T, M> {
template<typename T> class PersistentBase {
v8::Persistent<T> persistent;

template<typename U>
friend v8::Local<U> New(const PersistentBase<U> &p);
template<typename U, typename M>
friend v8::Local<U> New(const Persistent<U, M> &p);
template<typename U>
friend v8::Local<U> New(const Global<U> &p);
template<typename S> friend class ReturnValue;

public:
NAN_INLINE Persistent() : v8::Persistent<T, M>() {}
NAN_INLINE void Reset() {
persistent.Reset();
}

template<typename S> NAN_INLINE Persistent(v8::Local<S> that) :
v8::Persistent<T, M>(v8::Isolate::GetCurrent(), that) {}
template<typename S>
NAN_INLINE void Reset(const v8::Local<S> &other) {
TYPE_CHECK(T, S);
persistent.Reset(v8::Isolate::GetCurrent(), other);
}

template<typename S, typename M2>
NAN_INLINE Persistent(const v8::Persistent<S, M2> &that) :
v8::Persistent<T, M2>(v8::Isolate::GetCurrent(), that) {}
template<typename S>
NAN_INLINE void Reset(const PersistentBase<S> &other) {
TYPE_CHECK(T, S);
persistent.Reset(v8::Isolate::GetCurrent(), other.persistent);
}

NAN_INLINE void Reset() { v8::PersistentBase<T>::Reset(); }
NAN_INLINE bool IsEmpty() const { return persistent.IsEmpty(); }

template <typename S>
NAN_INLINE void Reset(const v8::Local<S> &other) {
v8::PersistentBase<T>::Reset(v8::Isolate::GetCurrent(), other);
NAN_INLINE void Empty() { persistent.Empty(); }

template<typename S>
NAN_INLINE bool operator==(const PersistentBase<S> &that) {
return this->persistent == that.persistent;
}

template <typename S>
NAN_INLINE void Reset(const v8::PersistentBase<S> &other) {
v8::PersistentBase<T>::Reset(v8::Isolate::GetCurrent(), other);
template<typename S>
NAN_INLINE bool operator==(const v8::Local<S> &that) {
return this->persistent == that;
}

template<typename S>
NAN_INLINE bool operator!=(const PersistentBase<S> &that) {
return !operator==(that);
}

template<typename S>
NAN_INLINE bool operator!=(const v8::Local<S> &that) {
return !operator==(that);
}

template<typename P>
Expand All @@ -39,6 +67,89 @@ template<typename T, typename M> class Persistent :
, typename WeakCallbackInfo<P>::Callback callback
, WeakCallbackType type);

NAN_INLINE void ClearWeak() { persistent.ClearWeak(); }

NAN_INLINE void MarkIndependent() { persistent.MarkIndependent(); }

NAN_INLINE bool IsIndependent() const { return persistent.IsIndependent(); }

NAN_INLINE bool IsNearDeath() const { return persistent.IsNearDeath(); }

NAN_INLINE bool IsWeak() const { return persistent.IsWeak(); }

NAN_INLINE v8::Local<T> Get() const {
return v8::Local<T>::New(v8::Isolate::GetCurrent(), persistent);
}

private:
NAN_INLINE PersistentBase() :
persistent() {}
NAN_INLINE explicit PersistentBase(v8::Persistent<T> that) :
persistent(v8::Isolate::GetCurrent(), that) { }
NAN_INLINE explicit PersistentBase(v8::Local<T> that) :
persistent(v8::Isolate::GetCurrent(), that) { }
template<typename S, typename M> friend class Persistent;
template<typename S> friend class Global;
friend class ObjectWrap;
};

template<typename T>
class NonCopyablePersistentTraits {
public:
typedef Persistent<T, NonCopyablePersistentTraits<T> >
NonCopyablePersistent;
static const bool kResetInDestructor = false;
template<typename S, typename M>
NAN_INLINE static void Copy(const Persistent<S, M> &source,
NonCopyablePersistent *dest) {
Uncompilable<v8::Object>();
}

template<typename O> NAN_INLINE static void Uncompilable() {
TYPE_CHECK(O, v8::Primitive);
}
};

template<typename T>
struct CopyablePersistentTraits {
typedef Persistent<T, CopyablePersistentTraits<T> > CopyablePersistent;
static const bool kResetInDestructor = true;
template<typename S, typename M>
static NAN_INLINE void Copy(const Persistent<S, M> &source,
CopyablePersistent *dest) {}
};

template<typename T, typename M> class Persistent :
public PersistentBase<T> {
public:
NAN_INLINE Persistent() : PersistentBase<T>() {}

template<typename S> NAN_INLINE Persistent(v8::Local<S> that) :
PersistentBase<T>(that) {
TYPE_CHECK(T, S);
}

template<typename S, typename M2>
NAN_INLINE Persistent(const Persistent<S, M2> &that) :
PersistentBase<T>() {
Copy(that);
}

NAN_INLINE Persistent& operator=(const Persistent& that) { // NOLINT
Copy(that);
return *this;
}

template<typename S, typename M2>
NAN_INLINE Persistent& operator=(const Persistent<S, M2>& that) { // NOLINT
Copy(that);
return *this;
}

NAN_INLINE ~Persistent() {
if (M::kResetInDestructor) this->Reset();
}

private:
NAN_INLINE T *operator*() const { return *PersistentBase<T>::persistent; }

Expand All @@ -58,71 +169,97 @@ template<typename T, typename M> class Persistent :
#if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \
(V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
template<typename T>
class Global : public v8::Global<T> {
class Global : public PersistentBase<T> {
public:
NAN_INLINE Global() : v8::Global<T>() {}

template<typename S> NAN_INLINE Global(v8::Local<S> that) :
v8::Global<T>(v8::Isolate::GetCurrent(), that) {}
NAN_INLINE Global() : PersistentBase<T>() {}

template<typename S>
NAN_INLINE Global(const v8::PersistentBase<S> &that) :
v8::Global<S>(v8::Isolate::GetCurrent(), that) {}

NAN_INLINE void Reset() { v8::PersistentBase<T>::Reset(); }
template <class S>
NAN_INLINE Global(v8::Local<S> that)
: PersistentBase<T>(that) {
TYPE_CHECK(T, S);
}

template <typename S>
NAN_INLINE void Reset(const v8::Local<S> &other) {
v8::PersistentBase<T>::Reset(v8::Isolate::GetCurrent(), other);
template <class S>
NAN_INLINE Global(const PersistentBase<S>& that)
: PersistentBase<T>(that) {
TYPE_CHECK(T, S);
}

template <typename S>
NAN_INLINE void Reset(const v8::PersistentBase<S> &other) {
v8::PersistentBase<T>::Reset(v8::Isolate::GetCurrent(), other);
NAN_INLINE Global(Global&& other) : PersistentBase<T>(other.persistent) {
other.Reset();
}

template<typename P>
NAN_INLINE void SetWeak(
P *parameter
, typename WeakCallbackInfo<P>::Callback callback
, WeakCallbackType type) {
reinterpret_cast<Persistent<T>*>(this)->SetWeak(
parameter, callback, type);
NAN_INLINE ~Global() { this->Reset(); }

template <class S>
NAN_INLINE Global& operator=(Global<S>&& rhs) {
TYPE_CHECK(T, S);
if (this != &rhs) {
this->Reset(rhs.persistent);
rhs.Reset();
}
return *this;
}

Global Pass() { return static_cast<Global&&>(*this); }

private:
Global(Global&) = delete;
void operator=(Global&) = delete;
};
#else
template<typename T>
class Global : public v8::UniquePersistent<T> {
public:
NAN_INLINE Global() : v8::UniquePersistent<T>() {}
class Global : public PersistentBase<T> {
struct RValue {
NAN_INLINE explicit RValue(Global* obj) : object(obj) {}
Global* object;
};

template<typename S> NAN_INLINE Global(v8::Local<S> that) :
v8::UniquePersistent<T>(v8::Isolate::GetCurrent(), that) {}

template<typename S>
NAN_INLINE Global(const v8::PersistentBase<S> &that) :
v8::UniquePersistent<S>(v8::Isolate::GetCurrent(), that) {}

NAN_INLINE void Reset() { v8::PersistentBase<T>::Reset(); }
public:
NAN_INLINE Global() : PersistentBase<T>() { }

template <typename S>
NAN_INLINE void Reset(const v8::Local<S> &other) {
v8::PersistentBase<T>::Reset(v8::Isolate::GetCurrent(), other);
NAN_INLINE Global(v8::Local<S> that)
: PersistentBase<T>(that) {
TYPE_CHECK(T, S);
}

template <typename S>
NAN_INLINE void Reset(const v8::PersistentBase<S> &other) {
v8::PersistentBase<T>::Reset(v8::Isolate::GetCurrent(), other);
NAN_INLINE Global(const PersistentBase<S> &that)
: PersistentBase<T>(that) {
TYPE_CHECK(T, S);
}

template<typename P>
NAN_INLINE void SetWeak(
P *parameter
, typename WeakCallbackInfo<P>::Callback callback
, WeakCallbackType type) {
reinterpret_cast<Persistent<T>*>(this)->SetWeak(
parameter, callback, type);
/**
* Move constructor.
*/
NAN_INLINE Global(RValue rvalue)
: PersistentBase<T>(rvalue.object.persistent) {
rvalue.object->Reset();
}

NAN_INLINE ~Global() { this->Reset(); }

/**
* Move via assignment.
*/
template<typename S>
NAN_INLINE Global &operator=(Global<S> rhs) {
TYPE_CHECK(T, S);
this->Reset(rhs.persistent);
rhs.Reset();
return *this;
}

/**
* Cast operator for moves.
*/
NAN_INLINE operator RValue() { return RValue(this); }

/**
* Pass allows returning uniques from functions, etc.
*/
Global Pass() { return Global(RValue(this)); }
};
#endif

Expand Down
4 changes: 4 additions & 0 deletions nan_persistent_pre_12_inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ class PersistentBase {

NAN_INLINE bool IsWeak() const { return persistent.IsWeak(); }

NAN_INLINE v8::Local<T> Get() const {
return v8::Local<T>::New(persistent);
}

private:
NAN_INLINE explicit PersistentBase(v8::Persistent<T> that) :
persistent(that) { }
Expand Down
Loading

0 comments on commit c469041

Please sign in to comment.