99#ifndef NAN_PERSISTENT_12_INL_H_
1010#define NAN_PERSISTENT_12_INL_H_
1111
12- template <typename T, typename M> class Persistent :
13- public v8::Persistent<T, M> {
12+ template <typename T> class PersistentBase {
13+ v8::Persistent<T> persistent;
14+
15+ template <typename U>
16+ friend v8::Local<U> New (const PersistentBase<U> &p);
17+ template <typename U, typename M>
18+ friend v8::Local<U> New (const Persistent<U, M> &p);
19+ template <typename U>
20+ friend v8::Local<U> New (const Global<U> &p);
21+ template <typename S> friend class ReturnValue ;
22+
1423 public:
15- NAN_INLINE Persistent () : v8::Persistent<T, M>() {}
24+ NAN_INLINE void Reset () {
25+ persistent.Reset ();
26+ }
1627
17- template <typename S> NAN_INLINE Persistent (v8::Local<S> that) :
18- v8::Persistent<T, M>(v8::Isolate::GetCurrent(), that) {}
28+ template <typename S>
29+ NAN_INLINE void Reset (const v8::Local<S> &other) {
30+ TYPE_CHECK (T, S);
31+ persistent.Reset (v8::Isolate::GetCurrent (), other);
32+ }
1933
20- template <typename S, typename M2>
21- NAN_INLINE Persistent (const v8::Persistent<S, M2> &that) :
22- v8::Persistent<T, M2>(v8::Isolate::GetCurrent(), that) {}
34+ template <typename S>
35+ NAN_INLINE void Reset (const PersistentBase<S> &other) {
36+ TYPE_CHECK (T, S);
37+ persistent.Reset (v8::Isolate::GetCurrent (), other.persistent );
38+ }
2339
24- NAN_INLINE void Reset () { v8::PersistentBase<T>:: Reset (); }
40+ NAN_INLINE bool IsEmpty () const { return persistent. IsEmpty (); }
2541
26- template <typename S>
27- NAN_INLINE void Reset (const v8::Local<S> &other) {
28- v8::PersistentBase<T>::Reset (v8::Isolate::GetCurrent (), other);
42+ NAN_INLINE void Empty () { persistent.Empty (); }
43+
44+ template <typename S>
45+ NAN_INLINE bool operator ==(const PersistentBase<S> &that) {
46+ return this ->persistent == that.persistent ;
2947 }
3048
31- template <typename S>
32- NAN_INLINE void Reset (const v8::PersistentBase<S> &other) {
33- v8::PersistentBase<T>::Reset (v8::Isolate::GetCurrent (), other);
49+ template <typename S>
50+ NAN_INLINE bool operator ==(const v8::Local<S> &that) {
51+ return this ->persistent == that;
52+ }
53+
54+ template <typename S>
55+ NAN_INLINE bool operator !=(const PersistentBase<S> &that) {
56+ return !operator ==(that);
57+ }
58+
59+ template <typename S>
60+ NAN_INLINE bool operator !=(const v8::Local<S> &that) {
61+ return !operator ==(that);
3462 }
3563
3664 template <typename P>
@@ -39,6 +67,89 @@ template<typename T, typename M> class Persistent :
3967 , typename WeakCallbackInfo<P>::Callback callback
4068 , WeakCallbackType type);
4169
70+ NAN_INLINE void ClearWeak () { persistent.ClearWeak (); }
71+
72+ NAN_INLINE void MarkIndependent () { persistent.MarkIndependent (); }
73+
74+ NAN_INLINE bool IsIndependent () const { return persistent.IsIndependent (); }
75+
76+ NAN_INLINE bool IsNearDeath () const { return persistent.IsNearDeath (); }
77+
78+ NAN_INLINE bool IsWeak () const { return persistent.IsWeak (); }
79+
80+ NAN_INLINE v8::Local<T> Get () const {
81+ return v8::Local<T>::New (v8::Isolate::GetCurrent (), persistent);
82+ }
83+
84+ private:
85+ NAN_INLINE PersistentBase () :
86+ persistent() {}
87+ NAN_INLINE explicit PersistentBase (v8::Persistent<T> that) :
88+ persistent(v8::Isolate::GetCurrent(), that) { }
89+ NAN_INLINE explicit PersistentBase (v8::Local<T> that) :
90+ persistent(v8::Isolate::GetCurrent(), that) { }
91+ template <typename S, typename M> friend class Persistent ;
92+ template <typename S> friend class Global ;
93+ friend class ObjectWrap ;
94+ };
95+
96+ template <typename T>
97+ class NonCopyablePersistentTraits {
98+ public:
99+ typedef Persistent<T, NonCopyablePersistentTraits<T> >
100+ NonCopyablePersistent;
101+ static const bool kResetInDestructor = false ;
102+ template <typename S, typename M>
103+ NAN_INLINE static void Copy (const Persistent<S, M> &source,
104+ NonCopyablePersistent *dest) {
105+ Uncompilable<v8::Object>();
106+ }
107+
108+ template <typename O> NAN_INLINE static void Uncompilable () {
109+ TYPE_CHECK (O, v8::Primitive);
110+ }
111+ };
112+
113+ template <typename T>
114+ struct CopyablePersistentTraits {
115+ typedef Persistent<T, CopyablePersistentTraits<T> > CopyablePersistent;
116+ static const bool kResetInDestructor = true ;
117+ template <typename S, typename M>
118+ static NAN_INLINE void Copy (const Persistent<S, M> &source,
119+ CopyablePersistent *dest) {}
120+ };
121+
122+ template <typename T, typename M> class Persistent :
123+ public PersistentBase<T> {
124+ public:
125+ NAN_INLINE Persistent () : PersistentBase<T>() {}
126+
127+ template <typename S> NAN_INLINE Persistent (v8::Local<S> that) :
128+ PersistentBase<T>(that) {
129+ TYPE_CHECK (T, S);
130+ }
131+
132+ template <typename S, typename M2>
133+ NAN_INLINE Persistent (const Persistent<S, M2> &that) :
134+ PersistentBase<T>() {
135+ Copy (that);
136+ }
137+
138+ NAN_INLINE Persistent& operator =(const Persistent& that) { // NOLINT
139+ Copy (that);
140+ return *this ;
141+ }
142+
143+ template <typename S, typename M2>
144+ NAN_INLINE Persistent& operator =(const Persistent<S, M2>& that) { // NOLINT
145+ Copy (that);
146+ return *this ;
147+ }
148+
149+ NAN_INLINE ~Persistent () {
150+ if (M::kResetInDestructor ) this ->Reset ();
151+ }
152+
42153 private:
43154 NAN_INLINE T *operator *() const { return *PersistentBase<T>::persistent; }
44155
@@ -58,71 +169,97 @@ template<typename T, typename M> class Persistent :
58169#if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \
59170 (V8_MAJOR_VERSION == 4 && defined (V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3 ))
60171template <typename T>
61- class Global : public v8 ::Global <T> {
172+ class Global : public PersistentBase <T> {
62173 public:
63- NAN_INLINE Global () : v8::Global<T>() {}
64-
65- template <typename S> NAN_INLINE Global (v8::Local<S> that) :
66- v8::Global<T>(v8::Isolate::GetCurrent(), that) {}
174+ NAN_INLINE Global () : PersistentBase<T>() {}
67175
68- template < typename S>
69- NAN_INLINE Global (const v8::PersistentBase <S> & that) :
70- v8::Global<S>(v8::Isolate::GetCurrent(), that) {}
71-
72- NAN_INLINE void Reset () { v8::PersistentBase<T>:: Reset (); }
176+ template < class S >
177+ NAN_INLINE Global (v8::Local <S> that)
178+ : PersistentBase<T>( that) {
179+ TYPE_CHECK (T, S);
180+ }
73181
74- template <typename S>
75- NAN_INLINE void Reset (const v8::Local<S> &other) {
76- v8::PersistentBase<T>::Reset (v8::Isolate::GetCurrent (), other);
182+ template <class S >
183+ NAN_INLINE Global (const PersistentBase<S>& that)
184+ : PersistentBase<T>(that) {
185+ TYPE_CHECK (T, S);
77186 }
78187
79- template <typename S>
80- NAN_INLINE void Reset (const v8::PersistentBase<S> &other) {
81- v8::PersistentBase<T>::Reset (v8::Isolate::GetCurrent (), other);
188+ NAN_INLINE Global (Global&& other) : PersistentBase<T>(other.persistent) {
189+ other.Reset ();
82190 }
83191
84- template <typename P>
85- NAN_INLINE void SetWeak (
86- P *parameter
87- , typename WeakCallbackInfo<P>::Callback callback
88- , WeakCallbackType type) {
89- reinterpret_cast <Persistent<T>*>(this )->SetWeak (
90- parameter, callback, type);
192+ NAN_INLINE ~Global () { this ->Reset (); }
193+
194+ template <class S >
195+ NAN_INLINE Global& operator =(Global<S>&& rhs) {
196+ TYPE_CHECK (T, S);
197+ if (this != &rhs) {
198+ this ->Reset (rhs.persistent );
199+ rhs.Reset ();
200+ }
201+ return *this ;
91202 }
203+
204+ Global Pass () { return static_cast <Global&&>(*this ); }
205+
206+ private:
207+ Global (Global&) = delete ;
208+ void operator =(Global&) = delete ;
92209};
93210#else
94211template <typename T>
95- class Global : public v8 ::UniquePersistent<T> {
96- public:
97- NAN_INLINE Global () : v8::UniquePersistent<T>() {}
212+ class Global : public PersistentBase <T> {
213+ struct RValue {
214+ NAN_INLINE explicit RValue (Global* obj) : object(obj) {}
215+ Global* object;
216+ };
98217
99- template <typename S> NAN_INLINE Global (v8::Local<S> that) :
100- v8::UniquePersistent<T>(v8::Isolate::GetCurrent(), that) {}
101-
102- template <typename S>
103- NAN_INLINE Global (const v8::PersistentBase<S> &that) :
104- v8::UniquePersistent<S>(v8::Isolate::GetCurrent(), that) {}
105-
106- NAN_INLINE void Reset () { v8::PersistentBase<T>::Reset (); }
218+ public:
219+ NAN_INLINE Global () : PersistentBase<T>() { }
107220
108221 template <typename S>
109- NAN_INLINE void Reset (const v8::Local<S> &other) {
110- v8::PersistentBase<T>::Reset (v8::Isolate::GetCurrent (), other);
222+ NAN_INLINE Global (v8::Local<S> that)
223+ : PersistentBase<T>(that) {
224+ TYPE_CHECK (T, S);
111225 }
112226
113227 template <typename S>
114- NAN_INLINE void Reset (const v8::PersistentBase<S> &other) {
115- v8::PersistentBase<T>::Reset (v8::Isolate::GetCurrent (), other);
228+ NAN_INLINE Global (const PersistentBase<S> &that)
229+ : PersistentBase<T>(that) {
230+ TYPE_CHECK (T, S);
116231 }
117232
118- template <typename P>
119- NAN_INLINE void SetWeak (
120- P *parameter
121- , typename WeakCallbackInfo<P>::Callback callback
122- , WeakCallbackType type) {
123- reinterpret_cast <Persistent<T>*>(this )->SetWeak (
124- parameter, callback, type);
233+ /* *
234+ * Move constructor.
235+ */
236+ NAN_INLINE Global (RValue rvalue)
237+ : PersistentBase<T>(rvalue.object.persistent) {
238+ rvalue.object ->Reset ();
239+ }
240+
241+ NAN_INLINE ~Global () { this ->Reset (); }
242+
243+ /* *
244+ * Move via assignment.
245+ */
246+ template <typename S>
247+ NAN_INLINE Global &operator =(Global<S> rhs) {
248+ TYPE_CHECK (T, S);
249+ this ->Reset (rhs.persistent );
250+ rhs.Reset ();
251+ return *this ;
125252 }
253+
254+ /* *
255+ * Cast operator for moves.
256+ */
257+ NAN_INLINE operator RValue () { return RValue (this ); }
258+
259+ /* *
260+ * Pass allows returning uniques from functions, etc.
261+ */
262+ Global Pass () { return Global (RValue (this )); }
126263};
127264#endif
128265
0 commit comments