| /********************************************************************* | 
|  * NAN - Native Abstractions for Node.js | 
|  * | 
|  * Copyright (c) 2018 NAN contributors | 
|  * | 
|  * MIT License <https://github.com/nodejs/nan/blob/master/LICENSE.md> | 
|  ********************************************************************/ | 
|   | 
| #ifndef NAN_CALLBACKS_PRE_12_INL_H_ | 
| #define NAN_CALLBACKS_PRE_12_INL_H_ | 
|   | 
| namespace imp { | 
| template<typename T> class ReturnValueImp; | 
| }  // end of namespace imp | 
|   | 
| template<typename T> | 
| class ReturnValue { | 
|   v8::Isolate *isolate_; | 
|   v8::Persistent<T> *value_; | 
|   friend class imp::ReturnValueImp<T>; | 
|   | 
|  public: | 
|   template <class S> | 
|   explicit inline ReturnValue(v8::Isolate *isolate, v8::Persistent<S> *p) : | 
|       isolate_(isolate), value_(p) {} | 
|   template <class S> | 
|   explicit inline ReturnValue(const ReturnValue<S>& that) | 
|       : isolate_(that.isolate_), value_(that.value_) { | 
|     TYPE_CHECK(T, S); | 
|   } | 
|   | 
|   // Handle setters | 
|   template <typename S> inline void Set(const v8::Local<S> &handle) { | 
|     TYPE_CHECK(T, S); | 
|     value_->Dispose(); | 
|     *value_ = v8::Persistent<T>::New(handle); | 
|   } | 
|   | 
|   template <typename S> inline void Set(const Global<S> &handle) { | 
|     TYPE_CHECK(T, S); | 
|     value_->Dispose(); | 
|     *value_ = v8::Persistent<T>::New(handle.persistent); | 
|     const_cast<Global<S> &>(handle).Reset(); | 
|   } | 
|   | 
|   // Fast primitive setters | 
|   inline void Set(bool value) { | 
|     v8::HandleScope scope; | 
|   | 
|     TYPE_CHECK(T, v8::Boolean); | 
|     value_->Dispose(); | 
|     *value_ = v8::Persistent<T>::New(v8::Boolean::New(value)); | 
|   } | 
|   | 
|   inline void Set(double i) { | 
|     v8::HandleScope scope; | 
|   | 
|     TYPE_CHECK(T, v8::Number); | 
|     value_->Dispose(); | 
|     *value_ = v8::Persistent<T>::New(v8::Number::New(i)); | 
|   } | 
|   | 
|   inline void Set(int32_t i) { | 
|     v8::HandleScope scope; | 
|   | 
|     TYPE_CHECK(T, v8::Integer); | 
|     value_->Dispose(); | 
|     *value_ = v8::Persistent<T>::New(v8::Int32::New(i)); | 
|   } | 
|   | 
|   inline void Set(uint32_t i) { | 
|     v8::HandleScope scope; | 
|   | 
|     TYPE_CHECK(T, v8::Integer); | 
|     value_->Dispose(); | 
|     *value_ = v8::Persistent<T>::New(v8::Uint32::NewFromUnsigned(i)); | 
|   } | 
|   | 
|   // Fast JS primitive setters | 
|   inline void SetNull() { | 
|     v8::HandleScope scope; | 
|   | 
|     TYPE_CHECK(T, v8::Primitive); | 
|     value_->Dispose(); | 
|     *value_ = v8::Persistent<T>::New(v8::Null()); | 
|   } | 
|   | 
|   inline void SetUndefined() { | 
|     v8::HandleScope scope; | 
|   | 
|     TYPE_CHECK(T, v8::Primitive); | 
|     value_->Dispose(); | 
|     *value_ = v8::Persistent<T>::New(v8::Undefined()); | 
|   } | 
|   | 
|   inline void SetEmptyString() { | 
|     v8::HandleScope scope; | 
|   | 
|     TYPE_CHECK(T, v8::String); | 
|     value_->Dispose(); | 
|     *value_ = v8::Persistent<T>::New(v8::String::Empty()); | 
|   } | 
|   | 
|   // Convenience getter for isolate | 
|   inline v8::Isolate *GetIsolate() const { | 
|     return isolate_; | 
|   } | 
|   | 
|   // Pointer setter: Uncompilable to prevent inadvertent misuse. | 
|   template<typename S> | 
|   inline void Set(S *whatever) { TYPE_CHECK(S*, v8::Primitive); } | 
| }; | 
|   | 
| template<typename T> | 
| class FunctionCallbackInfo { | 
|   const v8::Arguments &args_; | 
|   v8::Local<v8::Value> data_; | 
|   ReturnValue<T> return_value_; | 
|   v8::Persistent<T> retval_; | 
|   | 
|  public: | 
|   explicit inline FunctionCallbackInfo( | 
|       const v8::Arguments &args | 
|     , v8::Local<v8::Value> data) : | 
|           args_(args) | 
|         , data_(data) | 
|         , return_value_(args.GetIsolate(), &retval_) | 
|         , retval_(v8::Persistent<T>::New(v8::Undefined())) {} | 
|   | 
|   inline ~FunctionCallbackInfo() { | 
|     retval_.Dispose(); | 
|     retval_.Clear(); | 
|   } | 
|   | 
|   inline ReturnValue<T> GetReturnValue() const { | 
|     return ReturnValue<T>(return_value_); | 
|   } | 
|   | 
|   inline v8::Local<v8::Function> Callee() const { return args_.Callee(); } | 
|   inline v8::Local<v8::Value> Data() const { return data_; } | 
|   inline v8::Local<v8::Object> Holder() const { return args_.Holder(); } | 
|   inline bool IsConstructCall() const { return args_.IsConstructCall(); } | 
|   inline int Length() const { return args_.Length(); } | 
|   inline v8::Local<v8::Value> operator[](int i) const { return args_[i]; } | 
|   inline v8::Local<v8::Object> This() const { return args_.This(); } | 
|   inline v8::Isolate *GetIsolate() const { return args_.GetIsolate(); } | 
|   | 
|   | 
|  protected: | 
|   static const int kHolderIndex = 0; | 
|   static const int kIsolateIndex = 1; | 
|   static const int kReturnValueDefaultValueIndex = 2; | 
|   static const int kReturnValueIndex = 3; | 
|   static const int kDataIndex = 4; | 
|   static const int kCalleeIndex = 5; | 
|   static const int kContextSaveIndex = 6; | 
|   static const int kArgsLength = 7; | 
|   | 
|  private: | 
|   NAN_DISALLOW_ASSIGN_COPY_MOVE(FunctionCallbackInfo) | 
| }; | 
|   | 
| template<typename T> | 
| class PropertyCallbackInfoBase { | 
|   const v8::AccessorInfo &info_; | 
|   const v8::Local<v8::Value> data_; | 
|   | 
|  public: | 
|   explicit inline PropertyCallbackInfoBase( | 
|       const v8::AccessorInfo &info | 
|     , const v8::Local<v8::Value> data) : | 
|           info_(info) | 
|         , data_(data) {} | 
|   | 
|   inline v8::Isolate* GetIsolate() const { return info_.GetIsolate(); } | 
|   inline v8::Local<v8::Value> Data() const { return data_; } | 
|   inline v8::Local<v8::Object> This() const { return info_.This(); } | 
|   inline v8::Local<v8::Object> Holder() const { return info_.Holder(); } | 
|   | 
|  protected: | 
|   static const int kHolderIndex = 0; | 
|   static const int kIsolateIndex = 1; | 
|   static const int kReturnValueDefaultValueIndex = 2; | 
|   static const int kReturnValueIndex = 3; | 
|   static const int kDataIndex = 4; | 
|   static const int kThisIndex = 5; | 
|   static const int kArgsLength = 6; | 
|   | 
|  private: | 
|   NAN_DISALLOW_ASSIGN_COPY_MOVE(PropertyCallbackInfoBase) | 
| }; | 
|   | 
| template<typename T> | 
| class PropertyCallbackInfo : public PropertyCallbackInfoBase<T> { | 
|   ReturnValue<T> return_value_; | 
|   v8::Persistent<T> retval_; | 
|   | 
|  public: | 
|   explicit inline PropertyCallbackInfo( | 
|       const v8::AccessorInfo &info | 
|     , const v8::Local<v8::Value> data) : | 
|           PropertyCallbackInfoBase<T>(info, data) | 
|         , return_value_(info.GetIsolate(), &retval_) | 
|         , retval_(v8::Persistent<T>::New(v8::Undefined())) {} | 
|   | 
|   inline ~PropertyCallbackInfo() { | 
|     retval_.Dispose(); | 
|     retval_.Clear(); | 
|   } | 
|   | 
|   inline ReturnValue<T> GetReturnValue() const { return return_value_; } | 
| }; | 
|   | 
| template<> | 
| class PropertyCallbackInfo<v8::Array> : | 
|     public PropertyCallbackInfoBase<v8::Array> { | 
|   ReturnValue<v8::Array> return_value_; | 
|   v8::Persistent<v8::Array> retval_; | 
|   | 
|  public: | 
|   explicit inline PropertyCallbackInfo( | 
|       const v8::AccessorInfo &info | 
|     , const v8::Local<v8::Value> data) : | 
|           PropertyCallbackInfoBase<v8::Array>(info, data) | 
|         , return_value_(info.GetIsolate(), &retval_) | 
|         , retval_(v8::Persistent<v8::Array>::New(v8::Local<v8::Array>())) {} | 
|   | 
|   inline ~PropertyCallbackInfo() { | 
|     retval_.Dispose(); | 
|     retval_.Clear(); | 
|   } | 
|   | 
|   inline ReturnValue<v8::Array> GetReturnValue() const { | 
|     return return_value_; | 
|   } | 
| }; | 
|   | 
| template<> | 
| class PropertyCallbackInfo<v8::Boolean> : | 
|     public PropertyCallbackInfoBase<v8::Boolean> { | 
|   ReturnValue<v8::Boolean> return_value_; | 
|   v8::Persistent<v8::Boolean> retval_; | 
|   | 
|  public: | 
|   explicit inline PropertyCallbackInfo( | 
|       const v8::AccessorInfo &info | 
|     , const v8::Local<v8::Value> data) : | 
|           PropertyCallbackInfoBase<v8::Boolean>(info, data) | 
|         , return_value_(info.GetIsolate(), &retval_) | 
|         , retval_(v8::Persistent<v8::Boolean>::New(v8::Local<v8::Boolean>())) {} | 
|   | 
|   inline ~PropertyCallbackInfo() { | 
|     retval_.Dispose(); | 
|     retval_.Clear(); | 
|   } | 
|   | 
|   inline ReturnValue<v8::Boolean> GetReturnValue() const { | 
|     return return_value_; | 
|   } | 
| }; | 
|   | 
| template<> | 
| class PropertyCallbackInfo<v8::Integer> : | 
|     public PropertyCallbackInfoBase<v8::Integer> { | 
|   ReturnValue<v8::Integer> return_value_; | 
|   v8::Persistent<v8::Integer> retval_; | 
|   | 
|  public: | 
|   explicit inline PropertyCallbackInfo( | 
|       const v8::AccessorInfo &info | 
|     , const v8::Local<v8::Value> data) : | 
|           PropertyCallbackInfoBase<v8::Integer>(info, data) | 
|         , return_value_(info.GetIsolate(), &retval_) | 
|         , retval_(v8::Persistent<v8::Integer>::New(v8::Local<v8::Integer>())) {} | 
|   | 
|   inline ~PropertyCallbackInfo() { | 
|     retval_.Dispose(); | 
|     retval_.Clear(); | 
|   } | 
|   | 
|   inline ReturnValue<v8::Integer> GetReturnValue() const { | 
|     return return_value_; | 
|   } | 
| }; | 
|   | 
| namespace imp { | 
| template<typename T> | 
| class ReturnValueImp : public ReturnValue<T> { | 
|  public: | 
|   explicit ReturnValueImp(ReturnValue<T> that) : | 
|       ReturnValue<T>(that) {} | 
|   inline v8::Handle<T> Value() { | 
|       return *ReturnValue<T>::value_; | 
|   } | 
| }; | 
|   | 
| static | 
| v8::Handle<v8::Value> FunctionCallbackWrapper(const v8::Arguments &args) { | 
|   v8::Local<v8::Object> obj = args.Data().As<v8::Object>(); | 
|   FunctionCallback callback = reinterpret_cast<FunctionCallback>( | 
|       reinterpret_cast<intptr_t>( | 
|           obj->GetInternalField(kFunctionIndex).As<v8::External>()->Value())); | 
|   FunctionCallbackInfo<v8::Value> | 
|       cbinfo(args, obj->GetInternalField(kDataIndex)); | 
|   callback(cbinfo); | 
|   return ReturnValueImp<v8::Value>(cbinfo.GetReturnValue()).Value(); | 
| } | 
|   | 
| typedef v8::Handle<v8::Value> (*NativeFunction)(const v8::Arguments &); | 
|   | 
| static | 
| v8::Handle<v8::Value> GetterCallbackWrapper( | 
|     v8::Local<v8::String> property, const v8::AccessorInfo &info) { | 
|   v8::Local<v8::Object> obj = info.Data().As<v8::Object>(); | 
|   PropertyCallbackInfo<v8::Value> | 
|       cbinfo(info, obj->GetInternalField(kDataIndex)); | 
|   GetterCallback callback = reinterpret_cast<GetterCallback>( | 
|       reinterpret_cast<intptr_t>( | 
|           obj->GetInternalField(kGetterIndex).As<v8::External>()->Value())); | 
|   callback(property, cbinfo); | 
|   return ReturnValueImp<v8::Value>(cbinfo.GetReturnValue()).Value(); | 
| } | 
|   | 
| typedef v8::Handle<v8::Value> (*NativeGetter) | 
|     (v8::Local<v8::String>, const v8::AccessorInfo &); | 
|   | 
| static | 
| void SetterCallbackWrapper( | 
|     v8::Local<v8::String> property | 
|   , v8::Local<v8::Value> value | 
|   , const v8::AccessorInfo &info) { | 
|   v8::Local<v8::Object> obj = info.Data().As<v8::Object>(); | 
|   PropertyCallbackInfo<void> | 
|       cbinfo(info, obj->GetInternalField(kDataIndex)); | 
|   SetterCallback callback = reinterpret_cast<SetterCallback>( | 
|       reinterpret_cast<intptr_t>( | 
|           obj->GetInternalField(kSetterIndex).As<v8::External>()->Value())); | 
|   callback(property, value, cbinfo); | 
| } | 
|   | 
| typedef void (*NativeSetter) | 
|     (v8::Local<v8::String>, v8::Local<v8::Value>, const v8::AccessorInfo &); | 
|   | 
| static | 
| v8::Handle<v8::Value> PropertyGetterCallbackWrapper( | 
|     v8::Local<v8::String> property, const v8::AccessorInfo &info) { | 
|   v8::Local<v8::Object> obj = info.Data().As<v8::Object>(); | 
|   PropertyCallbackInfo<v8::Value> | 
|       cbinfo(info, obj->GetInternalField(kDataIndex)); | 
|   PropertyGetterCallback callback = reinterpret_cast<PropertyGetterCallback>( | 
|       reinterpret_cast<intptr_t>( | 
|           obj->GetInternalField(kPropertyGetterIndex) | 
|               .As<v8::External>()->Value())); | 
|   callback(property, cbinfo); | 
|   return ReturnValueImp<v8::Value>(cbinfo.GetReturnValue()).Value(); | 
| } | 
|   | 
| typedef v8::Handle<v8::Value> (*NativePropertyGetter) | 
|     (v8::Local<v8::String>, const v8::AccessorInfo &); | 
|   | 
| static | 
| v8::Handle<v8::Value> PropertySetterCallbackWrapper( | 
|     v8::Local<v8::String> property | 
|   , v8::Local<v8::Value> value | 
|   , const v8::AccessorInfo &info) { | 
|   v8::Local<v8::Object> obj = info.Data().As<v8::Object>(); | 
|   PropertyCallbackInfo<v8::Value> | 
|       cbinfo(info, obj->GetInternalField(kDataIndex)); | 
|   PropertySetterCallback callback = reinterpret_cast<PropertySetterCallback>( | 
|       reinterpret_cast<intptr_t>( | 
|           obj->GetInternalField(kPropertySetterIndex) | 
|               .As<v8::External>()->Value())); | 
|   callback(property, value, cbinfo); | 
|   return ReturnValueImp<v8::Value>(cbinfo.GetReturnValue()).Value(); | 
| } | 
|   | 
| typedef v8::Handle<v8::Value> (*NativePropertySetter) | 
|     (v8::Local<v8::String>, v8::Local<v8::Value>, const v8::AccessorInfo &); | 
|   | 
| static | 
| v8::Handle<v8::Array> PropertyEnumeratorCallbackWrapper( | 
|     const v8::AccessorInfo &info) { | 
|   v8::Local<v8::Object> obj = info.Data().As<v8::Object>(); | 
|   PropertyCallbackInfo<v8::Array> | 
|       cbinfo(info, obj->GetInternalField(kDataIndex)); | 
|   PropertyEnumeratorCallback callback = | 
|       reinterpret_cast<PropertyEnumeratorCallback>(reinterpret_cast<intptr_t>( | 
|           obj->GetInternalField(kPropertyEnumeratorIndex) | 
|               .As<v8::External>()->Value())); | 
|   callback(cbinfo); | 
|   return ReturnValueImp<v8::Array>(cbinfo.GetReturnValue()).Value(); | 
| } | 
|   | 
| typedef v8::Handle<v8::Array> (*NativePropertyEnumerator) | 
|     (const v8::AccessorInfo &); | 
|   | 
| static | 
| v8::Handle<v8::Boolean> PropertyDeleterCallbackWrapper( | 
|     v8::Local<v8::String> property | 
|   , const v8::AccessorInfo &info) { | 
|   v8::Local<v8::Object> obj = info.Data().As<v8::Object>(); | 
|   PropertyCallbackInfo<v8::Boolean> | 
|       cbinfo(info, obj->GetInternalField(kDataIndex)); | 
|   PropertyDeleterCallback callback = reinterpret_cast<PropertyDeleterCallback>( | 
|       reinterpret_cast<intptr_t>( | 
|           obj->GetInternalField(kPropertyDeleterIndex) | 
|               .As<v8::External>()->Value())); | 
|   callback(property, cbinfo); | 
|   return ReturnValueImp<v8::Boolean>(cbinfo.GetReturnValue()).Value(); | 
| } | 
|   | 
| typedef v8::Handle<v8::Boolean> (NativePropertyDeleter) | 
|     (v8::Local<v8::String>, const v8::AccessorInfo &); | 
|   | 
| static | 
| v8::Handle<v8::Integer> PropertyQueryCallbackWrapper( | 
|     v8::Local<v8::String> property, const v8::AccessorInfo &info) { | 
|   v8::Local<v8::Object> obj = info.Data().As<v8::Object>(); | 
|   PropertyCallbackInfo<v8::Integer> | 
|       cbinfo(info, obj->GetInternalField(kDataIndex)); | 
|   PropertyQueryCallback callback = reinterpret_cast<PropertyQueryCallback>( | 
|       reinterpret_cast<intptr_t>( | 
|           obj->GetInternalField(kPropertyQueryIndex) | 
|               .As<v8::External>()->Value())); | 
|   callback(property, cbinfo); | 
|   return ReturnValueImp<v8::Integer>(cbinfo.GetReturnValue()).Value(); | 
| } | 
|   | 
| typedef v8::Handle<v8::Integer> (*NativePropertyQuery) | 
|     (v8::Local<v8::String>, const v8::AccessorInfo &); | 
|   | 
| static | 
| v8::Handle<v8::Value> IndexGetterCallbackWrapper( | 
|     uint32_t index, const v8::AccessorInfo &info) { | 
|   v8::Local<v8::Object> obj = info.Data().As<v8::Object>(); | 
|   PropertyCallbackInfo<v8::Value> | 
|       cbinfo(info, obj->GetInternalField(kDataIndex)); | 
|   IndexGetterCallback callback = reinterpret_cast<IndexGetterCallback>( | 
|       reinterpret_cast<intptr_t>( | 
|           obj->GetInternalField(kIndexPropertyGetterIndex) | 
|               .As<v8::External>()->Value())); | 
|   callback(index, cbinfo); | 
|   return ReturnValueImp<v8::Value>(cbinfo.GetReturnValue()).Value(); | 
| } | 
|   | 
| typedef v8::Handle<v8::Value> (*NativeIndexGetter) | 
|     (uint32_t, const v8::AccessorInfo &); | 
|   | 
| static | 
| v8::Handle<v8::Value> IndexSetterCallbackWrapper( | 
|     uint32_t index | 
|   , v8::Local<v8::Value> value | 
|   , const v8::AccessorInfo &info) { | 
|   v8::Local<v8::Object> obj = info.Data().As<v8::Object>(); | 
|   PropertyCallbackInfo<v8::Value> | 
|       cbinfo(info, obj->GetInternalField(kDataIndex)); | 
|   IndexSetterCallback callback = reinterpret_cast<IndexSetterCallback>( | 
|       reinterpret_cast<intptr_t>( | 
|           obj->GetInternalField(kIndexPropertySetterIndex) | 
|               .As<v8::External>()->Value())); | 
|   callback(index, value, cbinfo); | 
|   return ReturnValueImp<v8::Value>(cbinfo.GetReturnValue()).Value(); | 
| } | 
|   | 
| typedef v8::Handle<v8::Value> (*NativeIndexSetter) | 
|     (uint32_t, v8::Local<v8::Value>, const v8::AccessorInfo &); | 
|   | 
| static | 
| v8::Handle<v8::Array> IndexEnumeratorCallbackWrapper( | 
|     const v8::AccessorInfo &info) { | 
|   v8::Local<v8::Object> obj = info.Data().As<v8::Object>(); | 
|   PropertyCallbackInfo<v8::Array> | 
|       cbinfo(info, obj->GetInternalField(kDataIndex)); | 
|   IndexEnumeratorCallback callback = reinterpret_cast<IndexEnumeratorCallback>( | 
|       reinterpret_cast<intptr_t>( | 
|           obj->GetInternalField(kIndexPropertyEnumeratorIndex) | 
|               .As<v8::External>()->Value())); | 
|   callback(cbinfo); | 
|   return ReturnValueImp<v8::Array>(cbinfo.GetReturnValue()).Value(); | 
| } | 
|   | 
| typedef v8::Handle<v8::Array> (*NativeIndexEnumerator) | 
|     (const v8::AccessorInfo &); | 
|   | 
| static | 
| v8::Handle<v8::Boolean> IndexDeleterCallbackWrapper( | 
|     uint32_t index, const v8::AccessorInfo &info) { | 
|   v8::Local<v8::Object> obj = info.Data().As<v8::Object>(); | 
|   PropertyCallbackInfo<v8::Boolean> | 
|       cbinfo(info, obj->GetInternalField(kDataIndex)); | 
|   IndexDeleterCallback callback = reinterpret_cast<IndexDeleterCallback>( | 
|       reinterpret_cast<intptr_t>( | 
|           obj->GetInternalField(kIndexPropertyDeleterIndex) | 
|               .As<v8::External>()->Value())); | 
|   callback(index, cbinfo); | 
|   return ReturnValueImp<v8::Boolean>(cbinfo.GetReturnValue()).Value(); | 
| } | 
|   | 
| typedef v8::Handle<v8::Boolean> (*NativeIndexDeleter) | 
|     (uint32_t, const v8::AccessorInfo &); | 
|   | 
| static | 
| v8::Handle<v8::Integer> IndexQueryCallbackWrapper( | 
|     uint32_t index, const v8::AccessorInfo &info) { | 
|   v8::Local<v8::Object> obj = info.Data().As<v8::Object>(); | 
|   PropertyCallbackInfo<v8::Integer> | 
|       cbinfo(info, obj->GetInternalField(kDataIndex)); | 
|   IndexQueryCallback callback = reinterpret_cast<IndexQueryCallback>( | 
|       reinterpret_cast<intptr_t>( | 
|           obj->GetInternalField(kIndexPropertyQueryIndex) | 
|               .As<v8::External>()->Value())); | 
|   callback(index, cbinfo); | 
|   return ReturnValueImp<v8::Integer>(cbinfo.GetReturnValue()).Value(); | 
| } | 
|   | 
| typedef v8::Handle<v8::Integer> (*NativeIndexQuery) | 
|     (uint32_t, const v8::AccessorInfo &); | 
| }  // end of namespace imp | 
|   | 
| #endif  // NAN_CALLBACKS_PRE_12_INL_H_ |