UNPKG

17.1 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_CALLBACKS_PRE_12_INL_H_
10#define NAN_CALLBACKS_PRE_12_INL_H_
11
12namespace imp {
13template<typename T> class ReturnValueImp;
14} // end of namespace imp
15
16template<typename T>
17class ReturnValue {
18 v8::Isolate *isolate_;
19 v8::Persistent<T> *value_;
20 friend class imp::ReturnValueImp<T>;
21
22 public:
23 template <class S>
24 explicit inline ReturnValue(v8::Isolate *isolate, v8::Persistent<S> *p) :
25 isolate_(isolate), value_(p) {}
26 template <class S>
27 explicit inline ReturnValue(const ReturnValue<S>& that)
28 : isolate_(that.isolate_), value_(that.value_) {
29 TYPE_CHECK(T, S);
30 }
31
32 // Handle setters
33 template <typename S> inline void Set(const v8::Local<S> &handle) {
34 TYPE_CHECK(T, S);
35 value_->Dispose();
36 *value_ = v8::Persistent<T>::New(handle);
37 }
38
39 template <typename S> inline void Set(const Global<S> &handle) {
40 TYPE_CHECK(T, S);
41 value_->Dispose();
42 *value_ = v8::Persistent<T>::New(handle.persistent);
43 const_cast<Global<S> &>(handle).Reset();
44 }
45
46 // Fast primitive setters
47 inline void Set(bool value) {
48 v8::HandleScope scope;
49
50 TYPE_CHECK(T, v8::Boolean);
51 value_->Dispose();
52 *value_ = v8::Persistent<T>::New(v8::Boolean::New(value));
53 }
54
55 inline void Set(double i) {
56 v8::HandleScope scope;
57
58 TYPE_CHECK(T, v8::Number);
59 value_->Dispose();
60 *value_ = v8::Persistent<T>::New(v8::Number::New(i));
61 }
62
63 inline void Set(int32_t i) {
64 v8::HandleScope scope;
65
66 TYPE_CHECK(T, v8::Integer);
67 value_->Dispose();
68 *value_ = v8::Persistent<T>::New(v8::Int32::New(i));
69 }
70
71 inline void Set(uint32_t i) {
72 v8::HandleScope scope;
73
74 TYPE_CHECK(T, v8::Integer);
75 value_->Dispose();
76 *value_ = v8::Persistent<T>::New(v8::Uint32::NewFromUnsigned(i));
77 }
78
79 // Fast JS primitive setters
80 inline void SetNull() {
81 v8::HandleScope scope;
82
83 TYPE_CHECK(T, v8::Primitive);
84 value_->Dispose();
85 *value_ = v8::Persistent<T>::New(v8::Null());
86 }
87
88 inline void SetUndefined() {
89 v8::HandleScope scope;
90
91 TYPE_CHECK(T, v8::Primitive);
92 value_->Dispose();
93 *value_ = v8::Persistent<T>::New(v8::Undefined());
94 }
95
96 inline void SetEmptyString() {
97 v8::HandleScope scope;
98
99 TYPE_CHECK(T, v8::String);
100 value_->Dispose();
101 *value_ = v8::Persistent<T>::New(v8::String::Empty());
102 }
103
104 // Convenience getter for isolate
105 inline v8::Isolate *GetIsolate() const {
106 return isolate_;
107 }
108
109 // Pointer setter: Uncompilable to prevent inadvertent misuse.
110 template<typename S>
111 inline void Set(S *whatever) { TYPE_CHECK(S*, v8::Primitive); }
112};
113
114template<typename T>
115class FunctionCallbackInfo {
116 const v8::Arguments &args_;
117 v8::Local<v8::Value> data_;
118 ReturnValue<T> return_value_;
119 v8::Persistent<T> retval_;
120
121 public:
122 explicit inline FunctionCallbackInfo(
123 const v8::Arguments &args
124 , v8::Local<v8::Value> data) :
125 args_(args)
126 , data_(data)
127 , return_value_(args.GetIsolate(), &retval_)
128 , retval_(v8::Persistent<T>::New(v8::Undefined())) {}
129
130 inline ~FunctionCallbackInfo() {
131 retval_.Dispose();
132 retval_.Clear();
133 }
134
135 inline ReturnValue<T> GetReturnValue() const {
136 return ReturnValue<T>(return_value_);
137 }
138
139 inline v8::Local<v8::Function> Callee() const { return args_.Callee(); }
140 inline v8::Local<v8::Value> Data() const { return data_; }
141 inline v8::Local<v8::Object> Holder() const { return args_.Holder(); }
142 inline bool IsConstructCall() const { return args_.IsConstructCall(); }
143 inline int Length() const { return args_.Length(); }
144 inline v8::Local<v8::Value> operator[](int i) const { return args_[i]; }
145 inline v8::Local<v8::Object> This() const { return args_.This(); }
146 inline v8::Isolate *GetIsolate() const { return args_.GetIsolate(); }
147
148
149 protected:
150 static const int kHolderIndex = 0;
151 static const int kIsolateIndex = 1;
152 static const int kReturnValueDefaultValueIndex = 2;
153 static const int kReturnValueIndex = 3;
154 static const int kDataIndex = 4;
155 static const int kCalleeIndex = 5;
156 static const int kContextSaveIndex = 6;
157 static const int kArgsLength = 7;
158
159 private:
160 NAN_DISALLOW_ASSIGN_COPY_MOVE(FunctionCallbackInfo)
161};
162
163template<typename T>
164class PropertyCallbackInfoBase {
165 const v8::AccessorInfo &info_;
166 const v8::Local<v8::Value> data_;
167
168 public:
169 explicit inline PropertyCallbackInfoBase(
170 const v8::AccessorInfo &info
171 , const v8::Local<v8::Value> data) :
172 info_(info)
173 , data_(data) {}
174
175 inline v8::Isolate* GetIsolate() const { return info_.GetIsolate(); }
176 inline v8::Local<v8::Value> Data() const { return data_; }
177 inline v8::Local<v8::Object> This() const { return info_.This(); }
178 inline v8::Local<v8::Object> Holder() const { return info_.Holder(); }
179
180 protected:
181 static const int kHolderIndex = 0;
182 static const int kIsolateIndex = 1;
183 static const int kReturnValueDefaultValueIndex = 2;
184 static const int kReturnValueIndex = 3;
185 static const int kDataIndex = 4;
186 static const int kThisIndex = 5;
187 static const int kArgsLength = 6;
188
189 private:
190 NAN_DISALLOW_ASSIGN_COPY_MOVE(PropertyCallbackInfoBase)
191};
192
193template<typename T>
194class PropertyCallbackInfo : public PropertyCallbackInfoBase<T> {
195 ReturnValue<T> return_value_;
196 v8::Persistent<T> retval_;
197
198 public:
199 explicit inline PropertyCallbackInfo(
200 const v8::AccessorInfo &info
201 , const v8::Local<v8::Value> data) :
202 PropertyCallbackInfoBase<T>(info, data)
203 , return_value_(info.GetIsolate(), &retval_)
204 , retval_(v8::Persistent<T>::New(v8::Undefined())) {}
205
206 inline ~PropertyCallbackInfo() {
207 retval_.Dispose();
208 retval_.Clear();
209 }
210
211 inline ReturnValue<T> GetReturnValue() const { return return_value_; }
212};
213
214template<>
215class PropertyCallbackInfo<v8::Array> :
216 public PropertyCallbackInfoBase<v8::Array> {
217 ReturnValue<v8::Array> return_value_;
218 v8::Persistent<v8::Array> retval_;
219
220 public:
221 explicit inline PropertyCallbackInfo(
222 const v8::AccessorInfo &info
223 , const v8::Local<v8::Value> data) :
224 PropertyCallbackInfoBase<v8::Array>(info, data)
225 , return_value_(info.GetIsolate(), &retval_)
226 , retval_(v8::Persistent<v8::Array>::New(v8::Local<v8::Array>())) {}
227
228 inline ~PropertyCallbackInfo() {
229 retval_.Dispose();
230 retval_.Clear();
231 }
232
233 inline ReturnValue<v8::Array> GetReturnValue() const {
234 return return_value_;
235 }
236};
237
238template<>
239class PropertyCallbackInfo<v8::Boolean> :
240 public PropertyCallbackInfoBase<v8::Boolean> {
241 ReturnValue<v8::Boolean> return_value_;
242 v8::Persistent<v8::Boolean> retval_;
243
244 public:
245 explicit inline PropertyCallbackInfo(
246 const v8::AccessorInfo &info
247 , const v8::Local<v8::Value> data) :
248 PropertyCallbackInfoBase<v8::Boolean>(info, data)
249 , return_value_(info.GetIsolate(), &retval_)
250 , retval_(v8::Persistent<v8::Boolean>::New(v8::Local<v8::Boolean>())) {}
251
252 inline ~PropertyCallbackInfo() {
253 retval_.Dispose();
254 retval_.Clear();
255 }
256
257 inline ReturnValue<v8::Boolean> GetReturnValue() const {
258 return return_value_;
259 }
260};
261
262template<>
263class PropertyCallbackInfo<v8::Integer> :
264 public PropertyCallbackInfoBase<v8::Integer> {
265 ReturnValue<v8::Integer> return_value_;
266 v8::Persistent<v8::Integer> retval_;
267
268 public:
269 explicit inline PropertyCallbackInfo(
270 const v8::AccessorInfo &info
271 , const v8::Local<v8::Value> data) :
272 PropertyCallbackInfoBase<v8::Integer>(info, data)
273 , return_value_(info.GetIsolate(), &retval_)
274 , retval_(v8::Persistent<v8::Integer>::New(v8::Local<v8::Integer>())) {}
275
276 inline ~PropertyCallbackInfo() {
277 retval_.Dispose();
278 retval_.Clear();
279 }
280
281 inline ReturnValue<v8::Integer> GetReturnValue() const {
282 return return_value_;
283 }
284};
285
286namespace imp {
287template<typename T>
288class ReturnValueImp : public ReturnValue<T> {
289 public:
290 explicit ReturnValueImp(ReturnValue<T> that) :
291 ReturnValue<T>(that) {}
292 inline v8::Handle<T> Value() {
293 return *ReturnValue<T>::value_;
294 }
295};
296
297static
298v8::Handle<v8::Value> FunctionCallbackWrapper(const v8::Arguments &args) {
299 v8::Local<v8::Object> obj = args.Data().As<v8::Object>();
300 FunctionCallback callback = reinterpret_cast<FunctionCallback>(
301 reinterpret_cast<intptr_t>(
302 obj->GetInternalField(kFunctionIndex).As<v8::External>()->Value()));
303 FunctionCallbackInfo<v8::Value>
304 cbinfo(args, obj->GetInternalField(kDataIndex));
305 callback(cbinfo);
306 return ReturnValueImp<v8::Value>(cbinfo.GetReturnValue()).Value();
307}
308
309typedef v8::Handle<v8::Value> (*NativeFunction)(const v8::Arguments &);
310
311static
312v8::Handle<v8::Value> GetterCallbackWrapper(
313 v8::Local<v8::String> property, const v8::AccessorInfo &info) {
314 v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
315 PropertyCallbackInfo<v8::Value>
316 cbinfo(info, obj->GetInternalField(kDataIndex));
317 GetterCallback callback = reinterpret_cast<GetterCallback>(
318 reinterpret_cast<intptr_t>(
319 obj->GetInternalField(kGetterIndex).As<v8::External>()->Value()));
320 callback(property, cbinfo);
321 return ReturnValueImp<v8::Value>(cbinfo.GetReturnValue()).Value();
322}
323
324typedef v8::Handle<v8::Value> (*NativeGetter)
325 (v8::Local<v8::String>, const v8::AccessorInfo &);
326
327static
328void SetterCallbackWrapper(
329 v8::Local<v8::String> property
330 , v8::Local<v8::Value> value
331 , const v8::AccessorInfo &info) {
332 v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
333 PropertyCallbackInfo<void>
334 cbinfo(info, obj->GetInternalField(kDataIndex));
335 SetterCallback callback = reinterpret_cast<SetterCallback>(
336 reinterpret_cast<intptr_t>(
337 obj->GetInternalField(kSetterIndex).As<v8::External>()->Value()));
338 callback(property, value, cbinfo);
339}
340
341typedef void (*NativeSetter)
342 (v8::Local<v8::String>, v8::Local<v8::Value>, const v8::AccessorInfo &);
343
344static
345v8::Handle<v8::Value> PropertyGetterCallbackWrapper(
346 v8::Local<v8::String> property, const v8::AccessorInfo &info) {
347 v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
348 PropertyCallbackInfo<v8::Value>
349 cbinfo(info, obj->GetInternalField(kDataIndex));
350 PropertyGetterCallback callback = reinterpret_cast<PropertyGetterCallback>(
351 reinterpret_cast<intptr_t>(
352 obj->GetInternalField(kPropertyGetterIndex)
353 .As<v8::External>()->Value()));
354 callback(property, cbinfo);
355 return ReturnValueImp<v8::Value>(cbinfo.GetReturnValue()).Value();
356}
357
358typedef v8::Handle<v8::Value> (*NativePropertyGetter)
359 (v8::Local<v8::String>, const v8::AccessorInfo &);
360
361static
362v8::Handle<v8::Value> PropertySetterCallbackWrapper(
363 v8::Local<v8::String> property
364 , v8::Local<v8::Value> value
365 , const v8::AccessorInfo &info) {
366 v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
367 PropertyCallbackInfo<v8::Value>
368 cbinfo(info, obj->GetInternalField(kDataIndex));
369 PropertySetterCallback callback = reinterpret_cast<PropertySetterCallback>(
370 reinterpret_cast<intptr_t>(
371 obj->GetInternalField(kPropertySetterIndex)
372 .As<v8::External>()->Value()));
373 callback(property, value, cbinfo);
374 return ReturnValueImp<v8::Value>(cbinfo.GetReturnValue()).Value();
375}
376
377typedef v8::Handle<v8::Value> (*NativePropertySetter)
378 (v8::Local<v8::String>, v8::Local<v8::Value>, const v8::AccessorInfo &);
379
380static
381v8::Handle<v8::Array> PropertyEnumeratorCallbackWrapper(
382 const v8::AccessorInfo &info) {
383 v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
384 PropertyCallbackInfo<v8::Array>
385 cbinfo(info, obj->GetInternalField(kDataIndex));
386 PropertyEnumeratorCallback callback =
387 reinterpret_cast<PropertyEnumeratorCallback>(reinterpret_cast<intptr_t>(
388 obj->GetInternalField(kPropertyEnumeratorIndex)
389 .As<v8::External>()->Value()));
390 callback(cbinfo);
391 return ReturnValueImp<v8::Array>(cbinfo.GetReturnValue()).Value();
392}
393
394typedef v8::Handle<v8::Array> (*NativePropertyEnumerator)
395 (const v8::AccessorInfo &);
396
397static
398v8::Handle<v8::Boolean> PropertyDeleterCallbackWrapper(
399 v8::Local<v8::String> property
400 , const v8::AccessorInfo &info) {
401 v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
402 PropertyCallbackInfo<v8::Boolean>
403 cbinfo(info, obj->GetInternalField(kDataIndex));
404 PropertyDeleterCallback callback = reinterpret_cast<PropertyDeleterCallback>(
405 reinterpret_cast<intptr_t>(
406 obj->GetInternalField(kPropertyDeleterIndex)
407 .As<v8::External>()->Value()));
408 callback(property, cbinfo);
409 return ReturnValueImp<v8::Boolean>(cbinfo.GetReturnValue()).Value();
410}
411
412typedef v8::Handle<v8::Boolean> (NativePropertyDeleter)
413 (v8::Local<v8::String>, const v8::AccessorInfo &);
414
415static
416v8::Handle<v8::Integer> PropertyQueryCallbackWrapper(
417 v8::Local<v8::String> property, const v8::AccessorInfo &info) {
418 v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
419 PropertyCallbackInfo<v8::Integer>
420 cbinfo(info, obj->GetInternalField(kDataIndex));
421 PropertyQueryCallback callback = reinterpret_cast<PropertyQueryCallback>(
422 reinterpret_cast<intptr_t>(
423 obj->GetInternalField(kPropertyQueryIndex)
424 .As<v8::External>()->Value()));
425 callback(property, cbinfo);
426 return ReturnValueImp<v8::Integer>(cbinfo.GetReturnValue()).Value();
427}
428
429typedef v8::Handle<v8::Integer> (*NativePropertyQuery)
430 (v8::Local<v8::String>, const v8::AccessorInfo &);
431
432static
433v8::Handle<v8::Value> IndexGetterCallbackWrapper(
434 uint32_t index, const v8::AccessorInfo &info) {
435 v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
436 PropertyCallbackInfo<v8::Value>
437 cbinfo(info, obj->GetInternalField(kDataIndex));
438 IndexGetterCallback callback = reinterpret_cast<IndexGetterCallback>(
439 reinterpret_cast<intptr_t>(
440 obj->GetInternalField(kIndexPropertyGetterIndex)
441 .As<v8::External>()->Value()));
442 callback(index, cbinfo);
443 return ReturnValueImp<v8::Value>(cbinfo.GetReturnValue()).Value();
444}
445
446typedef v8::Handle<v8::Value> (*NativeIndexGetter)
447 (uint32_t, const v8::AccessorInfo &);
448
449static
450v8::Handle<v8::Value> IndexSetterCallbackWrapper(
451 uint32_t index
452 , v8::Local<v8::Value> value
453 , const v8::AccessorInfo &info) {
454 v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
455 PropertyCallbackInfo<v8::Value>
456 cbinfo(info, obj->GetInternalField(kDataIndex));
457 IndexSetterCallback callback = reinterpret_cast<IndexSetterCallback>(
458 reinterpret_cast<intptr_t>(
459 obj->GetInternalField(kIndexPropertySetterIndex)
460 .As<v8::External>()->Value()));
461 callback(index, value, cbinfo);
462 return ReturnValueImp<v8::Value>(cbinfo.GetReturnValue()).Value();
463}
464
465typedef v8::Handle<v8::Value> (*NativeIndexSetter)
466 (uint32_t, v8::Local<v8::Value>, const v8::AccessorInfo &);
467
468static
469v8::Handle<v8::Array> IndexEnumeratorCallbackWrapper(
470 const v8::AccessorInfo &info) {
471 v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
472 PropertyCallbackInfo<v8::Array>
473 cbinfo(info, obj->GetInternalField(kDataIndex));
474 IndexEnumeratorCallback callback = reinterpret_cast<IndexEnumeratorCallback>(
475 reinterpret_cast<intptr_t>(
476 obj->GetInternalField(kIndexPropertyEnumeratorIndex)
477 .As<v8::External>()->Value()));
478 callback(cbinfo);
479 return ReturnValueImp<v8::Array>(cbinfo.GetReturnValue()).Value();
480}
481
482typedef v8::Handle<v8::Array> (*NativeIndexEnumerator)
483 (const v8::AccessorInfo &);
484
485static
486v8::Handle<v8::Boolean> IndexDeleterCallbackWrapper(
487 uint32_t index, const v8::AccessorInfo &info) {
488 v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
489 PropertyCallbackInfo<v8::Boolean>
490 cbinfo(info, obj->GetInternalField(kDataIndex));
491 IndexDeleterCallback callback = reinterpret_cast<IndexDeleterCallback>(
492 reinterpret_cast<intptr_t>(
493 obj->GetInternalField(kIndexPropertyDeleterIndex)
494 .As<v8::External>()->Value()));
495 callback(index, cbinfo);
496 return ReturnValueImp<v8::Boolean>(cbinfo.GetReturnValue()).Value();
497}
498
499typedef v8::Handle<v8::Boolean> (*NativeIndexDeleter)
500 (uint32_t, const v8::AccessorInfo &);
501
502static
503v8::Handle<v8::Integer> IndexQueryCallbackWrapper(
504 uint32_t index, const v8::AccessorInfo &info) {
505 v8::Local<v8::Object> obj = info.Data().As<v8::Object>();
506 PropertyCallbackInfo<v8::Integer>
507 cbinfo(info, obj->GetInternalField(kDataIndex));
508 IndexQueryCallback callback = reinterpret_cast<IndexQueryCallback>(
509 reinterpret_cast<intptr_t>(
510 obj->GetInternalField(kIndexPropertyQueryIndex)
511 .As<v8::External>()->Value()));
512 callback(index, cbinfo);
513 return ReturnValueImp<v8::Integer>(cbinfo.GetReturnValue()).Value();
514}
515
516typedef v8::Handle<v8::Integer> (*NativeIndexQuery)
517 (uint32_t, const v8::AccessorInfo &);
518} // end of namespace imp
519
520#endif // NAN_CALLBACKS_PRE_12_INL_H_