UNPKG

6.16 kBtext/x-cView Raw
1/*********************************************************************
2 * NAN - Native Abstractions for Node.js
3 *
4 * Copyright (c) 2018 NAN contributors
5 *
6 * MIT License <https://github.com/nodejs/nan/blob/master/LICENSE.md>
7 ********************************************************************/
8
9#ifndef NAN_PERSISTENT_PRE_12_INL_H_
10#define NAN_PERSISTENT_PRE_12_INL_H_
11
12template<typename T>
13class PersistentBase {
14 v8::Persistent<T> persistent;
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
23 public:
24 inline PersistentBase() :
25 persistent() {}
26
27 inline void Reset() {
28 persistent.Dispose();
29 persistent.Clear();
30 }
31
32 template<typename S>
33 inline void Reset(const v8::Local<S> &other) {
34 TYPE_CHECK(T, S);
35
36 if (!persistent.IsEmpty()) {
37 persistent.Dispose();
38 }
39
40 if (other.IsEmpty()) {
41 persistent.Clear();
42 } else {
43 persistent = v8::Persistent<T>::New(other);
44 }
45 }
46
47 template<typename S>
48 inline void Reset(const PersistentBase<S> &other) {
49 TYPE_CHECK(T, S);
50
51 if (!persistent.IsEmpty()) {
52 persistent.Dispose();
53 }
54
55 if (other.IsEmpty()) {
56 persistent.Clear();
57 } else {
58 persistent = v8::Persistent<T>::New(other.persistent);
59 }
60 }
61
62 inline bool IsEmpty() const { return persistent.IsEmpty(); }
63
64 inline void Empty() { persistent.Clear(); }
65
66 template<typename S>
67 inline bool operator==(const PersistentBase<S> &that) const {
68 return this->persistent == that.persistent;
69 }
70
71 template<typename S>
72 inline bool operator==(const v8::Local<S> &that) const {
73 return this->persistent == that;
74 }
75
76 template<typename S>
77 inline bool operator!=(const PersistentBase<S> &that) const {
78 return !operator==(that);
79 }
80
81 template<typename S>
82 inline bool operator!=(const v8::Local<S> &that) const {
83 return !operator==(that);
84 }
85
86 template<typename P>
87 inline void SetWeak(
88 P *parameter
89 , typename WeakCallbackInfo<P>::Callback callback
90 , WeakCallbackType type);
91
92 inline void ClearWeak() { persistent.ClearWeak(); }
93
94 inline void MarkIndependent() { persistent.MarkIndependent(); }
95
96 inline bool IsIndependent() const { return persistent.IsIndependent(); }
97
98 inline bool IsNearDeath() const { return persistent.IsNearDeath(); }
99
100 inline bool IsWeak() const { return persistent.IsWeak(); }
101
102 private:
103 inline explicit PersistentBase(v8::Persistent<T> that) :
104 persistent(that) { }
105 inline explicit PersistentBase(T *val) : persistent(val) {}
106 template<typename S, typename M> friend class Persistent;
107 template<typename S> friend class Global;
108 friend class ObjectWrap;
109};
110
111template<typename T>
112class NonCopyablePersistentTraits {
113 public:
114 typedef Persistent<T, NonCopyablePersistentTraits<T> >
115 NonCopyablePersistent;
116 static const bool kResetInDestructor = false;
117 template<typename S, typename M>
118 inline static void Copy(const Persistent<S, M> &source,
119 NonCopyablePersistent *dest) {
120 Uncompilable<v8::Object>();
121 }
122
123 template<typename O> inline static void Uncompilable() {
124 TYPE_CHECK(O, v8::Primitive);
125 }
126};
127
128template<typename T>
129struct CopyablePersistentTraits {
130 typedef Persistent<T, CopyablePersistentTraits<T> > CopyablePersistent;
131 static const bool kResetInDestructor = true;
132 template<typename S, typename M>
133 static inline void Copy(const Persistent<S, M> &source,
134 CopyablePersistent *dest) {}
135};
136
137template<typename T, typename M> class Persistent :
138 public PersistentBase<T> {
139 public:
140 inline Persistent() {}
141
142 template<typename S> inline Persistent(v8::Handle<S> that)
143 : PersistentBase<T>(v8::Persistent<T>::New(that)) {
144 TYPE_CHECK(T, S);
145 }
146
147 inline Persistent(const Persistent &that) : PersistentBase<T>() {
148 Copy(that);
149 }
150
151 template<typename S, typename M2>
152 inline Persistent(const Persistent<S, M2> &that) :
153 PersistentBase<T>() {
154 Copy(that);
155 }
156
157 inline Persistent &operator=(const Persistent &that) {
158 Copy(that);
159 return *this;
160 }
161
162 template <class S, class M2>
163 inline Persistent &operator=(const Persistent<S, M2> &that) {
164 Copy(that);
165 return *this;
166 }
167
168 inline ~Persistent() {
169 if (M::kResetInDestructor) this->Reset();
170 }
171
172 private:
173 inline T *operator*() const { return *PersistentBase<T>::persistent; }
174
175 template<typename S, typename M2>
176 inline void Copy(const Persistent<S, M2> &that) {
177 TYPE_CHECK(T, S);
178
179 this->Reset();
180
181 if (!that.IsEmpty()) {
182 this->persistent = v8::Persistent<T>::New(that.persistent);
183 M::Copy(that, this);
184 }
185 }
186};
187
188template<typename T>
189class Global : public PersistentBase<T> {
190 struct RValue {
191 inline explicit RValue(Global* obj) : object(obj) {}
192 Global* object;
193 };
194
195 public:
196 inline Global() : PersistentBase<T>(0) { }
197
198 template <typename S>
199 inline Global(v8::Local<S> that) // NOLINT(runtime/explicit)
200 : PersistentBase<T>(v8::Persistent<T>::New(that)) {
201 TYPE_CHECK(T, S);
202 }
203
204 template <typename S>
205 inline Global(const PersistentBase<S> &that) // NOLINT(runtime/explicit)
206 : PersistentBase<T>(that) {
207 TYPE_CHECK(T, S);
208 }
209 /**
210 * Move constructor.
211 */
212 inline Global(RValue rvalue) // NOLINT(runtime/explicit)
213 : PersistentBase<T>(rvalue.object->persistent) {
214 rvalue.object->Reset();
215 }
216 inline ~Global() { this->Reset(); }
217 /**
218 * Move via assignment.
219 */
220 template<typename S>
221 inline Global &operator=(Global<S> rhs) {
222 TYPE_CHECK(T, S);
223 this->Reset(rhs.persistent);
224 rhs.Reset();
225 return *this;
226 }
227 /**
228 * Cast operator for moves.
229 */
230 inline operator RValue() { return RValue(this); }
231 /**
232 * Pass allows returning uniques from functions, etc.
233 */
234 Global Pass() { return Global(RValue(this)); }
235
236 private:
237 Global(Global &);
238 void operator=(Global &);
239 template<typename S> friend class ReturnValue;
240};
241
242#endif // NAN_PERSISTENT_PRE_12_INL_H_