| /********************************************************************* |
| * 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_12_INL_H_ |
| #define NAN_CALLBACKS_12_INL_H_ |
| |
| template<typename T> |
| class ReturnValue { |
| v8::ReturnValue<T> value_; |
| |
| public: |
| template <class S> |
| explicit inline ReturnValue(const v8::ReturnValue<S> &value) : |
| value_(value) {} |
| template <class S> |
| explicit inline ReturnValue(const ReturnValue<S>& that) |
| : 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_.Set(handle); |
| } |
| |
| template <typename S> inline void Set(const Global<S> &handle) { |
| TYPE_CHECK(T, S); |
| #if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \ |
| (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && \ |
| (V8_MINOR_VERSION > 5 || (V8_MINOR_VERSION == 5 && \ |
| defined(V8_BUILD_NUMBER) && V8_BUILD_NUMBER >= 8)))) |
| value_.Set(handle); |
| #else |
| value_.Set(*reinterpret_cast<const v8::Persistent<S>*>(&handle)); |
| const_cast<Global<S> &>(handle).Reset(); |
| #endif |
| } |
| |
| // Fast primitive setters |
| inline void Set(bool value) { |
| TYPE_CHECK(T, v8::Boolean); |
| value_.Set(value); |
| } |
| |
| inline void Set(double i) { |
| TYPE_CHECK(T, v8::Number); |
| value_.Set(i); |
| } |
| |
| inline void Set(int32_t i) { |
| TYPE_CHECK(T, v8::Integer); |
| value_.Set(i); |
| } |
| |
| inline void Set(uint32_t i) { |
| TYPE_CHECK(T, v8::Integer); |
| value_.Set(i); |
| } |
| |
| // Fast JS primitive setters |
| inline void SetNull() { |
| TYPE_CHECK(T, v8::Primitive); |
| value_.SetNull(); |
| } |
| |
| inline void SetUndefined() { |
| TYPE_CHECK(T, v8::Primitive); |
| value_.SetUndefined(); |
| } |
| |
| inline void SetEmptyString() { |
| TYPE_CHECK(T, v8::String); |
| value_.SetEmptyString(); |
| } |
| |
| // Convenience getter for isolate |
| inline v8::Isolate *GetIsolate() const { |
| return value_.GetIsolate(); |
| } |
| |
| // 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::FunctionCallbackInfo<T> &info_; |
| const v8::Local<v8::Value> data_; |
| |
| public: |
| explicit inline FunctionCallbackInfo( |
| const v8::FunctionCallbackInfo<T> &info |
| , v8::Local<v8::Value> data) : |
| info_(info) |
| , data_(data) {} |
| |
| inline ReturnValue<T> GetReturnValue() const { |
| return ReturnValue<T>(info_.GetReturnValue()); |
| } |
| |
| #if NODE_MAJOR_VERSION < 10 |
| inline v8::Local<v8::Function> Callee() const { return info_.Callee(); } |
| #endif |
| inline v8::Local<v8::Value> Data() const { return data_; } |
| inline v8::Local<v8::Object> Holder() const { return info_.Holder(); } |
| inline bool IsConstructCall() const { return info_.IsConstructCall(); } |
| inline int Length() const { return info_.Length(); } |
| inline v8::Local<v8::Value> operator[](int i) const { return info_[i]; } |
| inline v8::Local<v8::Object> This() const { return info_.This(); } |
| inline v8::Isolate *GetIsolate() const { return info_.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 PropertyCallbackInfo { |
| const v8::PropertyCallbackInfo<T> &info_; |
| const v8::Local<v8::Value> data_; |
| |
| public: |
| explicit inline PropertyCallbackInfo( |
| const v8::PropertyCallbackInfo<T> &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(); } |
| inline ReturnValue<T> GetReturnValue() const { |
| return ReturnValue<T>(info_.GetReturnValue()); |
| } |
| |
| 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(PropertyCallbackInfo) |
| }; |
| |
| namespace imp { |
| static |
| void FunctionCallbackWrapper(const v8::FunctionCallbackInfo<v8::Value> &info) { |
| v8::Local<v8::Object> obj = info.Data().As<v8::Object>(); |
| FunctionCallback callback = reinterpret_cast<FunctionCallback>( |
| reinterpret_cast<intptr_t>( |
| obj->GetInternalField(kFunctionIndex).As<v8::External>()->Value())); |
| FunctionCallbackInfo<v8::Value> |
| cbinfo(info, obj->GetInternalField(kDataIndex)); |
| callback(cbinfo); |
| } |
| |
| typedef void (*NativeFunction)(const v8::FunctionCallbackInfo<v8::Value> &); |
| |
| #if NODE_MODULE_VERSION > NODE_0_12_MODULE_VERSION |
| static |
| void GetterCallbackWrapper( |
| v8::Local<v8::Name> property |
| , const v8::PropertyCallbackInfo<v8::Value> &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.As<v8::String>(), cbinfo); |
| } |
| |
| typedef void (*NativeGetter) |
| (v8::Local<v8::Name>, const v8::PropertyCallbackInfo<v8::Value> &); |
| |
| static |
| void SetterCallbackWrapper( |
| v8::Local<v8::Name> property |
| , v8::Local<v8::Value> value |
| , const v8::PropertyCallbackInfo<void> &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.As<v8::String>(), value, cbinfo); |
| } |
| |
| typedef void (*NativeSetter)( |
| v8::Local<v8::Name> |
| , v8::Local<v8::Value> |
| , const v8::PropertyCallbackInfo<void> &); |
| #else |
| static |
| void GetterCallbackWrapper( |
| v8::Local<v8::String> property |
| , const v8::PropertyCallbackInfo<v8::Value> &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); |
| } |
| |
| typedef void (*NativeGetter) |
| (v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value> &); |
| |
| static |
| void SetterCallbackWrapper( |
| v8::Local<v8::String> property |
| , v8::Local<v8::Value> value |
| , const v8::PropertyCallbackInfo<void> &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::PropertyCallbackInfo<void> &); |
| #endif |
| |
| #if NODE_MODULE_VERSION > NODE_0_12_MODULE_VERSION |
| static |
| void PropertyGetterCallbackWrapper( |
| v8::Local<v8::Name> property |
| , const v8::PropertyCallbackInfo<v8::Value> &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.As<v8::String>(), cbinfo); |
| } |
| |
| typedef void (*NativePropertyGetter) |
| (v8::Local<v8::Name>, const v8::PropertyCallbackInfo<v8::Value> &); |
| |
| static |
| void PropertySetterCallbackWrapper( |
| v8::Local<v8::Name> property |
| , v8::Local<v8::Value> value |
| , const v8::PropertyCallbackInfo<v8::Value> &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.As<v8::String>(), value, cbinfo); |
| } |
| |
| typedef void (*NativePropertySetter)( |
| v8::Local<v8::Name> |
| , v8::Local<v8::Value> |
| , const v8::PropertyCallbackInfo<v8::Value> &); |
| |
| static |
| void PropertyEnumeratorCallbackWrapper( |
| const v8::PropertyCallbackInfo<v8::Array> &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); |
| } |
| |
| typedef void (*NativePropertyEnumerator) |
| (const v8::PropertyCallbackInfo<v8::Array> &); |
| |
| static |
| void PropertyDeleterCallbackWrapper( |
| v8::Local<v8::Name> property |
| , const v8::PropertyCallbackInfo<v8::Boolean> &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.As<v8::String>(), cbinfo); |
| } |
| |
| typedef void (NativePropertyDeleter) |
| (v8::Local<v8::Name>, const v8::PropertyCallbackInfo<v8::Boolean> &); |
| |
| static |
| void PropertyQueryCallbackWrapper( |
| v8::Local<v8::Name> property |
| , const v8::PropertyCallbackInfo<v8::Integer> &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.As<v8::String>(), cbinfo); |
| } |
| |
| typedef void (*NativePropertyQuery) |
| (v8::Local<v8::Name>, const v8::PropertyCallbackInfo<v8::Integer> &); |
| #else |
| static |
| void PropertyGetterCallbackWrapper( |
| v8::Local<v8::String> property |
| , const v8::PropertyCallbackInfo<v8::Value> &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); |
| } |
| |
| typedef void (*NativePropertyGetter) |
| (v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value> &); |
| |
| static |
| void PropertySetterCallbackWrapper( |
| v8::Local<v8::String> property |
| , v8::Local<v8::Value> value |
| , const v8::PropertyCallbackInfo<v8::Value> &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); |
| } |
| |
| typedef void (*NativePropertySetter)( |
| v8::Local<v8::String> |
| , v8::Local<v8::Value> |
| , const v8::PropertyCallbackInfo<v8::Value> &); |
| |
| static |
| void PropertyEnumeratorCallbackWrapper( |
| const v8::PropertyCallbackInfo<v8::Array> &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); |
| } |
| |
| typedef void (*NativePropertyEnumerator) |
| (const v8::PropertyCallbackInfo<v8::Array> &); |
| |
| static |
| void PropertyDeleterCallbackWrapper( |
| v8::Local<v8::String> property |
| , const v8::PropertyCallbackInfo<v8::Boolean> &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); |
| } |
| |
| typedef void (NativePropertyDeleter) |
| (v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Boolean> &); |
| |
| static |
| void PropertyQueryCallbackWrapper( |
| v8::Local<v8::String> property |
| , const v8::PropertyCallbackInfo<v8::Integer> &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); |
| } |
| |
| typedef void (*NativePropertyQuery) |
| (v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Integer> &); |
| #endif |
| |
| static |
| void IndexGetterCallbackWrapper( |
| uint32_t index, const v8::PropertyCallbackInfo<v8::Value> &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); |
| } |
| |
| typedef void (*NativeIndexGetter) |
| (uint32_t, const v8::PropertyCallbackInfo<v8::Value> &); |
| |
| static |
| void IndexSetterCallbackWrapper( |
| uint32_t index |
| , v8::Local<v8::Value> value |
| , const v8::PropertyCallbackInfo<v8::Value> &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); |
| } |
| |
| typedef void (*NativeIndexSetter)( |
| uint32_t |
| , v8::Local<v8::Value> |
| , const v8::PropertyCallbackInfo<v8::Value> &); |
| |
| static |
| void IndexEnumeratorCallbackWrapper( |
| const v8::PropertyCallbackInfo<v8::Array> &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); |
| } |
| |
| typedef void (*NativeIndexEnumerator) |
| (const v8::PropertyCallbackInfo<v8::Array> &); |
| |
| static |
| void IndexDeleterCallbackWrapper( |
| uint32_t index, const v8::PropertyCallbackInfo<v8::Boolean> &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); |
| } |
| |
| typedef void (*NativeIndexDeleter) |
| (uint32_t, const v8::PropertyCallbackInfo<v8::Boolean> &); |
| |
| static |
| void IndexQueryCallbackWrapper( |
| uint32_t index, const v8::PropertyCallbackInfo<v8::Integer> &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); |
| } |
| |
| typedef void (*NativeIndexQuery) |
| (uint32_t, const v8::PropertyCallbackInfo<v8::Integer> &); |
| } // end of namespace imp |
| |
| #endif // NAN_CALLBACKS_12_INL_H_ |