Skip to content

Commit 9aceea7

Browse files
author
Gabriel Schulhof
committed
src: concentrate callbacks provided to core N-API
This change reduces the places where we declare private functions with the `napi_callback` signature for the purpose of using them with C++ callbacks passed as template arguments. We basically have 4 types: 1. static with `void` return 2. static with `napi_value` return 3. instance with `void` return 4. instance with `napi_value` return We can use one of these four calling patterns in the following places where we accept callbacks as template arguments: * `Napi::Function` (1. and 2.) * `Napi::PropertyDescriptor` (1. for the setter, 2. for the getter) * `Napi::InstanceWrap<T>` (3., 4. for instance methods, 4. for instance getters) * `Napi::ObjectWrap<T>` (1., 2. for static methods, 2. for static getters) In the case of `InstanceWrap<T>` and `ObjectWrap<T>` instance resp. static property descriptors we can also remove the infrastructure designed to allow for optional getters (`GetterTag` resp. `StaticGetterTag`) because the API for specifying instance resp. class property descriptors does not allow one to omit the getter. Signed-off-by: Gabriel Schulhof <[email protected]> PR-URL: #786 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Michael Dawson <[email protected]>
1 parent 2bc45bb commit 9aceea7

File tree

2 files changed

+72
-113
lines changed

2 files changed

+72
-113
lines changed

napi-inl.h

Lines changed: 72 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,48 @@ struct CallbackData<Callable, void> {
135135
void* data;
136136
};
137137

138+
template <void (*Callback)(const CallbackInfo& info)>
139+
static napi_value
140+
TemplatedVoidCallback(napi_env env, napi_callback_info info) NAPI_NOEXCEPT {
141+
return details::WrapCallback([&] {
142+
CallbackInfo cbInfo(env, info);
143+
Callback(cbInfo);
144+
return nullptr;
145+
});
146+
}
147+
148+
template <Napi::Value (*Callback)(const CallbackInfo& info)>
149+
static napi_value
150+
TemplatedCallback(napi_env env, napi_callback_info info) NAPI_NOEXCEPT {
151+
return details::WrapCallback([&] {
152+
CallbackInfo cbInfo(env, info);
153+
return Callback(cbInfo);
154+
});
155+
}
156+
157+
template <typename T,
158+
Napi::Value (T::*UnwrapCallback)(const CallbackInfo& info)>
159+
static napi_value
160+
TemplatedInstanceCallback(napi_env env, napi_callback_info info) NAPI_NOEXCEPT {
161+
return details::WrapCallback([&] {
162+
CallbackInfo cbInfo(env, info);
163+
T* instance = T::Unwrap(cbInfo.This().As<Object>());
164+
return (instance->*UnwrapCallback)(cbInfo);
165+
});
166+
}
167+
168+
template <typename T, void (T::*UnwrapCallback)(const CallbackInfo& info)>
169+
static napi_value
170+
TemplatedInstanceVoidCallback(napi_env env,
171+
napi_callback_info info) NAPI_NOEXCEPT {
172+
return details::WrapCallback([&] {
173+
CallbackInfo cbInfo(env, info);
174+
T* instance = T::Unwrap(cbInfo.This().As<Object>());
175+
(instance->*UnwrapCallback)(cbInfo);
176+
return nullptr;
177+
});
178+
}
179+
138180
template <typename T, typename Finalizer, typename Hint = void>
139181
struct FinalizeData {
140182
static inline
@@ -1845,30 +1887,25 @@ CreateFunction(napi_env env,
18451887
template <Function::VoidCallback cb>
18461888
inline Function Function::New(napi_env env, const char* utf8name, void* data) {
18471889
napi_value result = nullptr;
1848-
napi_status status = napi_create_function(
1849-
env, utf8name, NAPI_AUTO_LENGTH,
1850-
[](napi_env env, napi_callback_info info) {
1851-
CallbackInfo callbackInfo(env, info);
1852-
return details::WrapCallback([&] {
1853-
cb(callbackInfo);
1854-
return nullptr;
1855-
});
1856-
}, data, &result);
1890+
napi_status status = napi_create_function(env,
1891+
utf8name,
1892+
NAPI_AUTO_LENGTH,
1893+
details::TemplatedVoidCallback<cb>,
1894+
data,
1895+
&result);
18571896
NAPI_THROW_IF_FAILED(env, status, Function());
18581897
return Function(env, result);
18591898
}
18601899

18611900
template <Function::Callback cb>
18621901
inline Function Function::New(napi_env env, const char* utf8name, void* data) {
18631902
napi_value result = nullptr;
1864-
napi_status status = napi_create_function(
1865-
env, utf8name, NAPI_AUTO_LENGTH,
1866-
[](napi_env env, napi_callback_info info) {
1867-
CallbackInfo callbackInfo(env, info);
1868-
return details::WrapCallback([&] {
1869-
return cb(callbackInfo);
1870-
});
1871-
}, data, &result);
1903+
napi_status status = napi_create_function(env,
1904+
utf8name,
1905+
NAPI_AUTO_LENGTH,
1906+
details::TemplatedCallback<cb>,
1907+
data,
1908+
&result);
18721909
NAPI_THROW_IF_FAILED(env, status, Function());
18731910
return Function(env, result);
18741911
}
@@ -2859,7 +2896,7 @@ PropertyDescriptor::Accessor(const char* utf8name,
28592896
napi_property_descriptor desc = napi_property_descriptor();
28602897

28612898
desc.utf8name = utf8name;
2862-
desc.getter = &GetterCallbackWrapper<Getter>;
2899+
desc.getter = details::TemplatedCallback<Getter>;
28632900
desc.attributes = attributes;
28642901
desc.data = data;
28652902

@@ -2882,7 +2919,7 @@ PropertyDescriptor::Accessor(Name name,
28822919
napi_property_descriptor desc = napi_property_descriptor();
28832920

28842921
desc.name = name;
2885-
desc.getter = &GetterCallbackWrapper<Getter>;
2922+
desc.getter = details::TemplatedCallback<Getter>;
28862923
desc.attributes = attributes;
28872924
desc.data = data;
28882925

@@ -2900,8 +2937,8 @@ PropertyDescriptor::Accessor(const char* utf8name,
29002937
napi_property_descriptor desc = napi_property_descriptor();
29012938

29022939
desc.utf8name = utf8name;
2903-
desc.getter = &GetterCallbackWrapper<Getter>;
2904-
desc.setter = &SetterCallbackWrapper<Setter>;
2940+
desc.getter = details::TemplatedCallback<Getter>;
2941+
desc.setter = details::TemplatedVoidCallback<Setter>;
29052942
desc.attributes = attributes;
29062943
desc.data = data;
29072944

@@ -2928,31 +2965,14 @@ PropertyDescriptor::Accessor(Name name,
29282965
napi_property_descriptor desc = napi_property_descriptor();
29292966

29302967
desc.name = name;
2931-
desc.getter = &GetterCallbackWrapper<Getter>;
2932-
desc.setter = &SetterCallbackWrapper<Setter>;
2968+
desc.getter = details::TemplatedCallback<Getter>;
2969+
desc.setter = details::TemplatedVoidCallback<Setter>;
29332970
desc.attributes = attributes;
29342971
desc.data = data;
29352972

29362973
return desc;
29372974
}
29382975

2939-
template <typename PropertyDescriptor::GetterCallback Getter>
2940-
napi_value
2941-
PropertyDescriptor::GetterCallbackWrapper(napi_env env,
2942-
napi_callback_info info) {
2943-
CallbackInfo cbInfo(env, info);
2944-
return Getter(cbInfo);
2945-
}
2946-
2947-
template <typename PropertyDescriptor::SetterCallback Setter>
2948-
napi_value
2949-
PropertyDescriptor::SetterCallbackWrapper(napi_env env,
2950-
napi_callback_info info) {
2951-
CallbackInfo cbInfo(env, info);
2952-
Setter(cbInfo);
2953-
return nullptr;
2954-
}
2955-
29562976
template <typename Getter>
29572977
inline PropertyDescriptor
29582978
PropertyDescriptor::Accessor(Napi::Env env,
@@ -3283,7 +3303,7 @@ inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceMethod(
32833303
void* data) {
32843304
napi_property_descriptor desc = napi_property_descriptor();
32853305
desc.utf8name = utf8name;
3286-
desc.method = &InstanceWrap<T>::WrappedMethod<method>;
3306+
desc.method = details::TemplatedInstanceVoidCallback<T, method>;
32873307
desc.data = data;
32883308
desc.attributes = attributes;
32893309
return desc;
@@ -3297,7 +3317,7 @@ inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceMethod(
32973317
void* data) {
32983318
napi_property_descriptor desc = napi_property_descriptor();
32993319
desc.utf8name = utf8name;
3300-
desc.method = &InstanceWrap<T>::WrappedMethod<method>;
3320+
desc.method = details::TemplatedInstanceCallback<T, method>;
33013321
desc.data = data;
33023322
desc.attributes = attributes;
33033323
return desc;
@@ -3311,7 +3331,7 @@ inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceMethod(
33113331
void* data) {
33123332
napi_property_descriptor desc = napi_property_descriptor();
33133333
desc.name = name;
3314-
desc.method = &InstanceWrap<T>::WrappedMethod<method>;
3334+
desc.method = details::TemplatedInstanceVoidCallback<T, method>;
33153335
desc.data = data;
33163336
desc.attributes = attributes;
33173337
return desc;
@@ -3325,7 +3345,7 @@ inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceMethod(
33253345
void* data) {
33263346
napi_property_descriptor desc = napi_property_descriptor();
33273347
desc.name = name;
3328-
desc.method = &InstanceWrap<T>::WrappedMethod<method>;
3348+
desc.method = details::TemplatedInstanceCallback<T, method>;
33293349
desc.data = data;
33303350
desc.attributes = attributes;
33313351
return desc;
@@ -3378,7 +3398,7 @@ inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceAccessor(
33783398
void* data) {
33793399
napi_property_descriptor desc = napi_property_descriptor();
33803400
desc.utf8name = utf8name;
3381-
desc.getter = This::WrapGetter(This::GetterTag<getter>());
3401+
desc.getter = details::TemplatedInstanceCallback<T, getter>;
33823402
desc.setter = This::WrapSetter(This::SetterTag<setter>());
33833403
desc.data = data;
33843404
desc.attributes = attributes;
@@ -3394,7 +3414,7 @@ inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceAccessor(
33943414
void* data) {
33953415
napi_property_descriptor desc = napi_property_descriptor();
33963416
desc.name = name;
3397-
desc.getter = This::WrapGetter(This::GetterTag<getter>());
3417+
desc.getter = details::TemplatedInstanceCallback<T, getter>;
33983418
desc.setter = This::WrapSetter(This::SetterTag<setter>());
33993419
desc.data = data;
34003420
desc.attributes = attributes;
@@ -3487,27 +3507,6 @@ inline napi_value InstanceWrap<T>::InstanceSetterCallbackWrapper(
34873507
});
34883508
}
34893509

3490-
template <typename T>
3491-
template <typename InstanceWrap<T>::InstanceVoidMethodCallback method>
3492-
inline napi_value InstanceWrap<T>::WrappedMethod(napi_env env, napi_callback_info info) noexcept {
3493-
return details::WrapCallback([&] {
3494-
const CallbackInfo cbInfo(env, info);
3495-
T* instance = T::Unwrap(cbInfo.This().As<Object>());
3496-
(instance->*method)(cbInfo);
3497-
return nullptr;
3498-
});
3499-
}
3500-
3501-
template <typename T>
3502-
template <typename InstanceWrap<T>::InstanceMethodCallback method>
3503-
inline napi_value InstanceWrap<T>::WrappedMethod(napi_env env, napi_callback_info info) noexcept {
3504-
return details::WrapCallback([&] {
3505-
const CallbackInfo cbInfo(env, info);
3506-
T* instance = T::Unwrap(cbInfo.This().As<Object>());
3507-
return (instance->*method)(cbInfo);
3508-
});
3509-
}
3510-
35113510
template <typename T>
35123511
template <typename InstanceWrap<T>::InstanceSetterCallback method>
35133512
inline napi_value InstanceWrap<T>::WrappedMethod(napi_env env, napi_callback_info info) noexcept {
@@ -3732,7 +3731,7 @@ inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticMethod(
37323731
void* data) {
37333732
napi_property_descriptor desc = napi_property_descriptor();
37343733
desc.utf8name = utf8name;
3735-
desc.method = &ObjectWrap<T>::WrappedMethod<method>;
3734+
desc.method = details::TemplatedVoidCallback<method>;
37363735
desc.data = data;
37373736
desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
37383737
return desc;
@@ -3746,7 +3745,7 @@ inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticMethod(
37463745
void* data) {
37473746
napi_property_descriptor desc = napi_property_descriptor();
37483747
desc.name = name;
3749-
desc.method = &ObjectWrap<T>::WrappedMethod<method>;
3748+
desc.method = details::TemplatedVoidCallback<method>;
37503749
desc.data = data;
37513750
desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
37523751
return desc;
@@ -3760,7 +3759,7 @@ inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticMethod(
37603759
void* data) {
37613760
napi_property_descriptor desc = napi_property_descriptor();
37623761
desc.utf8name = utf8name;
3763-
desc.method = &ObjectWrap<T>::WrappedMethod<method>;
3762+
desc.method = details::TemplatedCallback<method>;
37643763
desc.data = data;
37653764
desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
37663765
return desc;
@@ -3774,7 +3773,7 @@ inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticMethod(
37743773
void* data) {
37753774
napi_property_descriptor desc = napi_property_descriptor();
37763775
desc.name = name;
3777-
desc.method = &ObjectWrap<T>::WrappedMethod<method>;
3776+
desc.method = details::TemplatedCallback<method>;
37783777
desc.data = data;
37793778
desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
37803779
return desc;
@@ -3827,7 +3826,7 @@ inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticAccessor(
38273826
void* data) {
38283827
napi_property_descriptor desc = napi_property_descriptor();
38293828
desc.utf8name = utf8name;
3830-
desc.getter = This::WrapStaticGetter(This::StaticGetterTag<getter>());
3829+
desc.getter = details::TemplatedCallback<getter>;
38313830
desc.setter = This::WrapStaticSetter(This::StaticSetterTag<setter>());
38323831
desc.data = data;
38333832
desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
@@ -3843,7 +3842,7 @@ inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticAccessor(
38433842
void* data) {
38443843
napi_property_descriptor desc = napi_property_descriptor();
38453844
desc.name = name;
3846-
desc.getter = This::WrapStaticGetter(This::StaticGetterTag<getter>());
3845+
desc.getter = details::TemplatedCallback<getter>;
38473846
desc.setter = This::WrapStaticSetter(This::StaticSetterTag<setter>());
38483847
desc.data = data;
38493848
desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
@@ -3969,23 +3968,6 @@ inline void ObjectWrap<T>::FinalizeCallback(napi_env env, void* data, void* /*hi
39693968
delete instance;
39703969
}
39713970

3972-
template <typename T>
3973-
template <typename ObjectWrap<T>::StaticVoidMethodCallback method>
3974-
inline napi_value ObjectWrap<T>::WrappedMethod(napi_env env, napi_callback_info info) noexcept {
3975-
return details::WrapCallback([&] {
3976-
method(CallbackInfo(env, info));
3977-
return nullptr;
3978-
});
3979-
}
3980-
3981-
template <typename T>
3982-
template <typename ObjectWrap<T>::StaticMethodCallback method>
3983-
inline napi_value ObjectWrap<T>::WrappedMethod(napi_env env, napi_callback_info info) noexcept {
3984-
return details::WrapCallback([&] {
3985-
return method(CallbackInfo(env, info));
3986-
});
3987-
}
3988-
39893971
template <typename T>
39903972
template <typename ObjectWrap<T>::StaticSetterCallback method>
39913973
inline napi_value ObjectWrap<T>::WrappedMethod(napi_env env, napi_callback_info info) noexcept {

napi.h

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1623,10 +1623,6 @@ namespace Napi {
16231623
operator const napi_property_descriptor&() const;
16241624

16251625
private:
1626-
template <GetterCallback Getter>
1627-
static napi_value GetterCallbackWrapper(napi_env env, napi_callback_info info);
1628-
template <SetterCallback Setter>
1629-
static napi_value SetterCallbackWrapper(napi_env env, napi_callback_info info);
16301626
napi_property_descriptor _desc;
16311627
};
16321628

@@ -1748,16 +1744,8 @@ namespace Napi {
17481744
template <InstanceSetterCallback method>
17491745
static napi_value WrappedMethod(napi_env env, napi_callback_info info) noexcept;
17501746

1751-
template <InstanceGetterCallback getter> struct GetterTag {};
17521747
template <InstanceSetterCallback setter> struct SetterTag {};
17531748

1754-
template <InstanceVoidMethodCallback method>
1755-
static napi_value WrappedMethod(napi_env env, napi_callback_info info) noexcept;
1756-
template <InstanceMethodCallback method>
1757-
static napi_value WrappedMethod(napi_env env, napi_callback_info info) noexcept;
1758-
template <InstanceGetterCallback getter>
1759-
static napi_callback WrapGetter(GetterTag<getter>) noexcept { return &This::WrappedMethod<getter>; }
1760-
static napi_callback WrapGetter(GetterTag<nullptr>) noexcept { return nullptr; }
17611749
template <InstanceSetterCallback setter>
17621750
static napi_callback WrapSetter(SetterTag<setter>) noexcept { return &This::WrappedMethod<setter>; }
17631751
static napi_callback WrapSetter(SetterTag<nullptr>) noexcept { return nullptr; }
@@ -1892,22 +1880,11 @@ namespace Napi {
18921880
StaticGetterCallback,
18931881
StaticSetterCallback> StaticAccessorCallbackData;
18941882

1895-
template <StaticVoidMethodCallback method>
1896-
static napi_value WrappedMethod(napi_env env, napi_callback_info info) noexcept;
1897-
1898-
template <StaticMethodCallback method>
1899-
static napi_value WrappedMethod(napi_env env, napi_callback_info info) noexcept;
1900-
19011883
template <StaticSetterCallback method>
19021884
static napi_value WrappedMethod(napi_env env, napi_callback_info info) noexcept;
19031885

1904-
template <StaticGetterCallback getter> struct StaticGetterTag {};
19051886
template <StaticSetterCallback setter> struct StaticSetterTag {};
19061887

1907-
template <StaticGetterCallback getter>
1908-
static napi_callback WrapStaticGetter(StaticGetterTag<getter>) noexcept { return &This::WrappedMethod<getter>; }
1909-
static napi_callback WrapStaticGetter(StaticGetterTag<nullptr>) noexcept { return nullptr; }
1910-
19111888
template <StaticSetterCallback setter>
19121889
static napi_callback WrapStaticSetter(StaticSetterTag<setter>) noexcept { return &This::WrappedMethod<setter>; }
19131890
static napi_callback WrapStaticSetter(StaticSetterTag<nullptr>) noexcept { return nullptr; }

0 commit comments

Comments
 (0)