1 /*********************************************************************
2 * NAN - Native Abstractions for Node.js
4 * Copyright (c) 2018 NAN contributors
6 * MIT License <https://github.com/nodejs/nan/blob/master/LICENSE.md>
7 ********************************************************************/
9 #ifndef NAN_CALLBACKS_PRE_12_INL_H_
10 #define NAN_CALLBACKS_PRE_12_INL_H_
13 template<typename T> class ReturnValueImp;
14 } // end of namespace imp
18 v8::Isolate *isolate_;
19 v8::Persistent<T> *value_;
20 friend class imp::ReturnValueImp<T>;
24 explicit inline ReturnValue(v8::Isolate *isolate, v8::Persistent<S> *p) :
25 isolate_(isolate), value_(p) {}
27 explicit inline ReturnValue(const ReturnValue<S>& that)
28 : isolate_(that.isolate_), value_(that.value_) {
33 template <typename S> inline void Set(const v8::Local<S> &handle) {
36 *value_ = v8::Persistent<T>::New(handle);
39 template <typename S> inline void Set(const Global<S> &handle) {
42 *value_ = v8::Persistent<T>::New(handle.persistent);
43 const_cast<Global<S> &>(handle).Reset();
46 // Fast primitive setters
47 inline void Set(bool value) {
48 v8::HandleScope scope;
50 TYPE_CHECK(T, v8::Boolean);
52 *value_ = v8::Persistent<T>::New(v8::Boolean::New(value));
55 inline void Set(double i) {
56 v8::HandleScope scope;
58 TYPE_CHECK(T, v8::Number);
60 *value_ = v8::Persistent<T>::New(v8::Number::New(i));
63 inline void Set(int32_t i) {
64 v8::HandleScope scope;
66 TYPE_CHECK(T, v8::Integer);
68 *value_ = v8::Persistent<T>::New(v8::Int32::New(i));
71 inline void Set(uint32_t i) {
72 v8::HandleScope scope;
74 TYPE_CHECK(T, v8::Integer);
76 *value_ = v8::Persistent<T>::New(v8::Uint32::NewFromUnsigned(i));
79 // Fast JS primitive setters
80 inline void SetNull() {
81 v8::HandleScope scope;
83 TYPE_CHECK(T, v8::Primitive);
85 *value_ = v8::Persistent<T>::New(v8::Null());
88 inline void SetUndefined() {
89 v8::HandleScope scope;
91 TYPE_CHECK(T, v8::Primitive);
93 *value_ = v8::Persistent<T>::New(v8::Undefined());
96 inline void SetEmptyString() {
97 v8::HandleScope scope;
99 TYPE_CHECK(T, v8::String);
101 *value_ = v8::Persistent<T>::New(v8::String::Empty());
104 // Convenience getter for isolate
105 inline v8::Isolate *GetIsolate() const {
109 // Pointer setter: Uncompilable to prevent inadvertent misuse.
111 inline void Set(S *whatever) { TYPE_CHECK(S*, v8::Primitive); }
115 class FunctionCallbackInfo {
116 const v8::Arguments &args_;
117 v8::Local<v8::Value> data_;
118 ReturnValue<T> return_value_;
119 v8::Persistent<T> retval_;
122 explicit inline FunctionCallbackInfo(
123 const v8::Arguments &args
124 , v8::Local<v8::Value> data) :
127 , return_value_(args.GetIsolate(), &retval_)
128 , retval_(v8::Persistent<T>::New(v8::Undefined())) {}
130 inline ~FunctionCallbackInfo() {
135 inline ReturnValue<T> GetReturnValue() const {
136 return ReturnValue<T>(return_value_);
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(); }
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;
160 NAN_DISALLOW_ASSIGN_COPY_MOVE(FunctionCallbackInfo)
164 class PropertyCallbackInfoBase {
165 const v8::AccessorInfo &info_;
166 const v8::Local<v8::Value> data_;
169 explicit inline PropertyCallbackInfoBase(
170 const v8::AccessorInfo &info
171 , const v8::Local<v8::Value> data) :
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(); }
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;
190 NAN_DISALLOW_ASSIGN_COPY_MOVE(PropertyCallbackInfoBase)
194 class PropertyCallbackInfo : public PropertyCallbackInfoBase<T> {
195 ReturnValue<T> return_value_;
196 v8::Persistent<T> retval_;
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())) {}
206 inline ~PropertyCallbackInfo() {
211 inline ReturnValue<T> GetReturnValue() const { return return_value_; }
215 class PropertyCallbackInfo<v8::Array> :
216 public PropertyCallbackInfoBase<v8::Array> {
217 ReturnValue<v8::Array> return_value_;
218 v8::Persistent<v8::Array> retval_;
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>())) {}
228 inline ~PropertyCallbackInfo() {
233 inline ReturnValue<v8::Array> GetReturnValue() const {
234 return return_value_;
239 class PropertyCallbackInfo<v8::Boolean> :
240 public PropertyCallbackInfoBase<v8::Boolean> {
241 ReturnValue<v8::Boolean> return_value_;
242 v8::Persistent<v8::Boolean> retval_;
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>())) {}
252 inline ~PropertyCallbackInfo() {
257 inline ReturnValue<v8::Boolean> GetReturnValue() const {
258 return return_value_;
263 class PropertyCallbackInfo<v8::Integer> :
264 public PropertyCallbackInfoBase<v8::Integer> {
265 ReturnValue<v8::Integer> return_value_;
266 v8::Persistent<v8::Integer> retval_;
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>())) {}
276 inline ~PropertyCallbackInfo() {
281 inline ReturnValue<v8::Integer> GetReturnValue() const {
282 return return_value_;
288 class ReturnValueImp : public ReturnValue<T> {
290 explicit ReturnValueImp(ReturnValue<T> that) :
291 ReturnValue<T>(that) {}
292 inline v8::Handle<T> Value() {
293 return *ReturnValue<T>::value_;
298 v8::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));
306 return ReturnValueImp<v8::Value>(cbinfo.GetReturnValue()).Value();
309 typedef v8::Handle<v8::Value> (*NativeFunction)(const v8::Arguments &);
312 v8::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();
324 typedef v8::Handle<v8::Value> (*NativeGetter)
325 (v8::Local<v8::String>, const v8::AccessorInfo &);
328 void 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);
341 typedef void (*NativeSetter)
342 (v8::Local<v8::String>, v8::Local<v8::Value>, const v8::AccessorInfo &);
345 v8::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();
358 typedef v8::Handle<v8::Value> (*NativePropertyGetter)
359 (v8::Local<v8::String>, const v8::AccessorInfo &);
362 v8::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();
377 typedef v8::Handle<v8::Value> (*NativePropertySetter)
378 (v8::Local<v8::String>, v8::Local<v8::Value>, const v8::AccessorInfo &);
381 v8::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()));
391 return ReturnValueImp<v8::Array>(cbinfo.GetReturnValue()).Value();
394 typedef v8::Handle<v8::Array> (*NativePropertyEnumerator)
395 (const v8::AccessorInfo &);
398 v8::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();
412 typedef v8::Handle<v8::Boolean> (NativePropertyDeleter)
413 (v8::Local<v8::String>, const v8::AccessorInfo &);
416 v8::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();
429 typedef v8::Handle<v8::Integer> (*NativePropertyQuery)
430 (v8::Local<v8::String>, const v8::AccessorInfo &);
433 v8::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();
446 typedef v8::Handle<v8::Value> (*NativeIndexGetter)
447 (uint32_t, const v8::AccessorInfo &);
450 v8::Handle<v8::Value> IndexSetterCallbackWrapper(
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();
465 typedef v8::Handle<v8::Value> (*NativeIndexSetter)
466 (uint32_t, v8::Local<v8::Value>, const v8::AccessorInfo &);
469 v8::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()));
479 return ReturnValueImp<v8::Array>(cbinfo.GetReturnValue()).Value();
482 typedef v8::Handle<v8::Array> (*NativeIndexEnumerator)
483 (const v8::AccessorInfo &);
486 v8::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();
499 typedef v8::Handle<v8::Boolean> (*NativeIndexDeleter)
500 (uint32_t, const v8::AccessorInfo &);
503 v8::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();
516 typedef v8::Handle<v8::Integer> (*NativeIndexQuery)
517 (uint32_t, const v8::AccessorInfo &);
518 } // end of namespace imp
520 #endif // NAN_CALLBACKS_PRE_12_INL_H_