You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
242 lines
6.0 KiB
242 lines
6.0 KiB
/********************************************************************* |
|
* NAN - Native Abstractions for Node.js |
|
* |
|
* Copyright (c) 2018 NAN contributors |
|
* |
|
* MIT License <https://github.com/nodejs/nan/blob/master/LICENSE.md> |
|
********************************************************************/ |
|
|
|
#ifndef NAN_PERSISTENT_PRE_12_INL_H_ |
|
#define NAN_PERSISTENT_PRE_12_INL_H_ |
|
|
|
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: |
|
inline PersistentBase() : |
|
persistent() {} |
|
|
|
inline void Reset() { |
|
persistent.Dispose(); |
|
persistent.Clear(); |
|
} |
|
|
|
template<typename S> |
|
inline void Reset(const v8::Local<S> &other) { |
|
TYPE_CHECK(T, S); |
|
|
|
if (!persistent.IsEmpty()) { |
|
persistent.Dispose(); |
|
} |
|
|
|
if (other.IsEmpty()) { |
|
persistent.Clear(); |
|
} else { |
|
persistent = v8::Persistent<T>::New(other); |
|
} |
|
} |
|
|
|
template<typename S> |
|
inline void Reset(const PersistentBase<S> &other) { |
|
TYPE_CHECK(T, S); |
|
|
|
if (!persistent.IsEmpty()) { |
|
persistent.Dispose(); |
|
} |
|
|
|
if (other.IsEmpty()) { |
|
persistent.Clear(); |
|
} else { |
|
persistent = v8::Persistent<T>::New(other.persistent); |
|
} |
|
} |
|
|
|
inline bool IsEmpty() const { return persistent.IsEmpty(); } |
|
|
|
inline void Empty() { persistent.Clear(); } |
|
|
|
template<typename S> |
|
inline bool operator==(const PersistentBase<S> &that) const { |
|
return this->persistent == that.persistent; |
|
} |
|
|
|
template<typename S> |
|
inline bool operator==(const v8::Local<S> &that) const { |
|
return this->persistent == that; |
|
} |
|
|
|
template<typename S> |
|
inline bool operator!=(const PersistentBase<S> &that) const { |
|
return !operator==(that); |
|
} |
|
|
|
template<typename S> |
|
inline bool operator!=(const v8::Local<S> &that) const { |
|
return !operator==(that); |
|
} |
|
|
|
template<typename P> |
|
inline void SetWeak( |
|
P *parameter |
|
, typename WeakCallbackInfo<P>::Callback callback |
|
, WeakCallbackType type); |
|
|
|
inline void ClearWeak() { persistent.ClearWeak(); } |
|
|
|
inline void MarkIndependent() { persistent.MarkIndependent(); } |
|
|
|
inline bool IsIndependent() const { return persistent.IsIndependent(); } |
|
|
|
inline bool IsNearDeath() const { return persistent.IsNearDeath(); } |
|
|
|
inline bool IsWeak() const { return persistent.IsWeak(); } |
|
|
|
private: |
|
inline explicit PersistentBase(v8::Persistent<T> that) : |
|
persistent(that) { } |
|
inline explicit PersistentBase(T *val) : persistent(val) {} |
|
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> |
|
inline static void Copy(const Persistent<S, M> &source, |
|
NonCopyablePersistent *dest) { |
|
Uncompilable<v8::Object>(); |
|
} |
|
|
|
template<typename O> 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 inline void Copy(const Persistent<S, M> &source, |
|
CopyablePersistent *dest) {} |
|
}; |
|
|
|
template<typename T, typename M> class Persistent : |
|
public PersistentBase<T> { |
|
public: |
|
inline Persistent() {} |
|
|
|
template<typename S> inline Persistent(v8::Handle<S> that) |
|
: PersistentBase<T>(v8::Persistent<T>::New(that)) { |
|
TYPE_CHECK(T, S); |
|
} |
|
|
|
inline Persistent(const Persistent &that) : PersistentBase<T>() { |
|
Copy(that); |
|
} |
|
|
|
template<typename S, typename M2> |
|
inline Persistent(const Persistent<S, M2> &that) : |
|
PersistentBase<T>() { |
|
Copy(that); |
|
} |
|
|
|
inline Persistent &operator=(const Persistent &that) { |
|
Copy(that); |
|
return *this; |
|
} |
|
|
|
template <class S, class M2> |
|
inline Persistent &operator=(const Persistent<S, M2> &that) { |
|
Copy(that); |
|
return *this; |
|
} |
|
|
|
inline ~Persistent() { |
|
if (M::kResetInDestructor) this->Reset(); |
|
} |
|
|
|
private: |
|
inline T *operator*() const { return *PersistentBase<T>::persistent; } |
|
|
|
template<typename S, typename M2> |
|
inline void Copy(const Persistent<S, M2> &that) { |
|
TYPE_CHECK(T, S); |
|
|
|
this->Reset(); |
|
|
|
if (!that.IsEmpty()) { |
|
this->persistent = v8::Persistent<T>::New(that.persistent); |
|
M::Copy(that, this); |
|
} |
|
} |
|
}; |
|
|
|
template<typename T> |
|
class Global : public PersistentBase<T> { |
|
struct RValue { |
|
inline explicit RValue(Global* obj) : object(obj) {} |
|
Global* object; |
|
}; |
|
|
|
public: |
|
inline Global() : PersistentBase<T>(0) { } |
|
|
|
template <typename S> |
|
inline Global(v8::Local<S> that) // NOLINT(runtime/explicit) |
|
: PersistentBase<T>(v8::Persistent<T>::New(that)) { |
|
TYPE_CHECK(T, S); |
|
} |
|
|
|
template <typename S> |
|
inline Global(const PersistentBase<S> &that) // NOLINT(runtime/explicit) |
|
: PersistentBase<T>(that) { |
|
TYPE_CHECK(T, S); |
|
} |
|
/** |
|
* Move constructor. |
|
*/ |
|
inline Global(RValue rvalue) // NOLINT(runtime/explicit) |
|
: PersistentBase<T>(rvalue.object->persistent) { |
|
rvalue.object->Reset(); |
|
} |
|
inline ~Global() { this->Reset(); } |
|
/** |
|
* Move via assignment. |
|
*/ |
|
template<typename S> |
|
inline Global &operator=(Global<S> rhs) { |
|
TYPE_CHECK(T, S); |
|
this->Reset(rhs.persistent); |
|
rhs.Reset(); |
|
return *this; |
|
} |
|
/** |
|
* Cast operator for moves. |
|
*/ |
|
inline operator RValue() { return RValue(this); } |
|
/** |
|
* Pass allows returning uniques from functions, etc. |
|
*/ |
|
Global Pass() { return Global(RValue(this)); } |
|
|
|
private: |
|
Global(Global &); |
|
void operator=(Global &); |
|
template<typename S> friend class ReturnValue; |
|
}; |
|
|
|
#endif // NAN_PERSISTENT_PRE_12_INL_H_
|
|
|