Skip to content

Commit c469041

Browse files
committed
Add convenience getter for Local from Persistent
1 parent 9f42b4c commit c469041

File tree

8 files changed

+226
-88
lines changed

8 files changed

+226
-88
lines changed

nan.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -169,15 +169,12 @@ typedef v8::String::ExternalOneByteStringResource
169169

170170
#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
171171
template<typename T>
172-
class NonCopyablePersistentTraits :
173-
public v8::NonCopyablePersistentTraits<T> {};
172+
class NonCopyablePersistentTraits;
174173
template<typename T>
175-
class CopyablePersistentTraits :
176-
public v8::CopyablePersistentTraits<T> {};
174+
class CopyablePersistentTraits;
177175

178176
template<typename T>
179-
class PersistentBase :
180-
public v8::PersistentBase<T> {};
177+
class PersistentBase;
181178

182179
template<typename T, typename M = v8::NonCopyablePersistentTraits<T> >
183180
class Persistent;

nan_callbacks_12_inl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class ReturnValue {
3535
(V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && \
3636
(V8_MINOR_VERSION > 5 || (V8_MINOR_VERSION == 5 && \
3737
defined(V8_BUILD_NUMBER) && V8_BUILD_NUMBER >= 8))))
38-
value_.Set(handle);
38+
value_.Set(handle.persistent);
3939
#else
4040
value_.Set(*reinterpret_cast<const v8::Persistent<S>*>(&handle));
4141
const_cast<Global<S> &>(handle).Reset();

nan_implementation_12_inl.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -393,12 +393,12 @@ inline v8::Local<T> New(v8::Persistent<T, M> const& p) {
393393

394394
template <typename T, typename M>
395395
inline v8::Local<T> New(Persistent<T, M> const& p) {
396-
return v8::Local<T>::New(v8::Isolate::GetCurrent(), p);
396+
return v8::Local<T>::New(v8::Isolate::GetCurrent(), p.persistent);
397397
}
398398

399399
template <typename T>
400400
inline v8::Local<T> New(Global<T> const& p) {
401-
return v8::Local<T>::New(v8::Isolate::GetCurrent(), p);
401+
return v8::Local<T>::New(v8::Isolate::GetCurrent(), p.persistent);
402402
}
403403

404404
#endif // NAN_IMPLEMENTATION_12_INL_H_

nan_object_wrap.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,15 @@ class ObjectWrap {
6262
(V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
6363

6464
inline void MakeWeak() {
65-
persistent().v8::PersistentBase<v8::Object>::SetWeak(
65+
persistent().persistent.v8::PersistentBase<v8::Object>::SetWeak(
6666
this, WeakCallback, v8::WeakCallbackType::kParameter);
6767
persistent().MarkIndependent();
6868
}
6969

7070
#elif NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
7171

7272
inline void MakeWeak() {
73-
persistent().v8::PersistentBase<v8::Object>::SetWeak(this, WeakCallback);
73+
persistent().persistent.v8::PersistentBase<v8::Object>::SetWeak(this, WeakCallback);
7474
persistent().MarkIndependent();
7575
}
7676

nan_persistent_12_inl.h

Lines changed: 197 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,56 @@
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))
60171
template<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
94211
template<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

nan_persistent_pre_12_inl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ class PersistentBase {
9999

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

102+
NAN_INLINE v8::Local<T> Get() const {
103+
return v8::Local<T>::New(persistent);
104+
}
105+
102106
private:
103107
NAN_INLINE explicit PersistentBase(v8::Persistent<T> that) :
104108
persistent(that) { }

0 commit comments

Comments
 (0)