You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
514 lines
17 KiB
514 lines
17 KiB
/********************************************************************* |
|
* 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_
|
|
|