Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add convenience getter for Local from Persistent #492

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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
258 changes: 198 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,90 @@ 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) {
std::memcpy(&that, &persistent, sizeof (v8::Persistent<T>));
}
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 +170,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>(v8::Persistent<T>(v8::Isolate::GetCurrent(), that.persistent)) {
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.Empty();
}

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) {
std::memcpy(&rhs.persistent, &this->persistent, sizeof (v8::PersistentBase<S>));
rhs.Empty();
}
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>(v8::Persistent<T>(v8::Isolate::GetCurrent(), that.persistent)) {
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->Empty();
}

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

/**
* Move via assignment.
*/
template<typename S>
NAN_INLINE Global &operator=(Global<S> rhs) {
TYPE_CHECK(T, S);
std::memcpy(&rhs.persistent, &this->persistent, sizeof (v8::Persistent<T>));
rhs.Empty();
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