node-addon-api 1.6.1 → 1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +112 -4
- package/CONTRIBUTING.md +66 -0
- package/README.md +33 -6
- package/doc/async_worker.md +91 -11
- package/doc/basic_types.md +11 -0
- package/doc/class_property_descriptor.md +85 -3
- package/doc/creating_a_release.md +37 -16
- package/doc/error_handling.md +31 -0
- package/doc/function_reference.md +2 -2
- package/doc/number.md +5 -5
- package/doc/object.md +5 -5
- package/doc/object_reference.md +2 -2
- package/doc/object_wrap.md +2 -2
- package/doc/prebuild_tools.md +1 -1
- package/doc/property_descriptor.md +1 -1
- package/doc/setup.md +13 -2
- package/doc/string.md +3 -0
- package/doc/threadsafe_function.md +303 -0
- package/index.js +1 -0
- package/napi-inl.deprecated.h +2 -2
- package/napi-inl.h +510 -83
- package/napi.h +280 -10
- package/package.json +19 -2
- package/tools/README.md +2 -2
package/napi-inl.h
CHANGED
|
@@ -17,49 +17,6 @@ namespace Napi {
|
|
|
17
17
|
// Helpers to handle functions exposed from C++.
|
|
18
18
|
namespace details {
|
|
19
19
|
|
|
20
|
-
#ifdef NAPI_CPP_EXCEPTIONS
|
|
21
|
-
|
|
22
|
-
#define NAPI_THROW(e) throw e
|
|
23
|
-
|
|
24
|
-
// When C++ exceptions are enabled, Errors are thrown directly. There is no need
|
|
25
|
-
// to return anything after the throw statement. The variadic parameter is an
|
|
26
|
-
// optional return value that is ignored.
|
|
27
|
-
#define NAPI_THROW_IF_FAILED(env, status, ...) \
|
|
28
|
-
if ((status) != napi_ok) throw Error::New(env);
|
|
29
|
-
|
|
30
|
-
#define NAPI_THROW_IF_FAILED_VOID(env, status) \
|
|
31
|
-
if ((status) != napi_ok) throw Error::New(env);
|
|
32
|
-
|
|
33
|
-
#else // NAPI_CPP_EXCEPTIONS
|
|
34
|
-
|
|
35
|
-
#define NAPI_THROW(e) (e).ThrowAsJavaScriptException();
|
|
36
|
-
|
|
37
|
-
// When C++ exceptions are disabled, Errors are thrown as JavaScript exceptions,
|
|
38
|
-
// which are pending until the callback returns to JS. The variadic parameter
|
|
39
|
-
// is an optional return value; usually it is an empty result.
|
|
40
|
-
#define NAPI_THROW_IF_FAILED(env, status, ...) \
|
|
41
|
-
if ((status) != napi_ok) { \
|
|
42
|
-
Error::New(env).ThrowAsJavaScriptException(); \
|
|
43
|
-
return __VA_ARGS__; \
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// We need a _VOID version of this macro to avoid warnings resulting from
|
|
47
|
-
// leaving the NAPI_THROW_IF_FAILED `...` argument empty.
|
|
48
|
-
#define NAPI_THROW_IF_FAILED_VOID(env, status) \
|
|
49
|
-
if ((status) != napi_ok) { \
|
|
50
|
-
Error::New(env).ThrowAsJavaScriptException(); \
|
|
51
|
-
return; \
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
#endif // NAPI_CPP_EXCEPTIONS
|
|
55
|
-
|
|
56
|
-
#define NAPI_FATAL_IF_FAILED(status, location, message) \
|
|
57
|
-
do { \
|
|
58
|
-
if ((status) != napi_ok) { \
|
|
59
|
-
Error::Fatal((location), (message)); \
|
|
60
|
-
} \
|
|
61
|
-
} while (0)
|
|
62
|
-
|
|
63
20
|
// Attach a data item to an object and delete it when the object gets
|
|
64
21
|
// garbage-collected.
|
|
65
22
|
// TODO: Replace this code with `napi_add_finalizer()` whenever it becomes
|
|
@@ -168,6 +125,80 @@ struct FinalizeData {
|
|
|
168
125
|
Hint* hint;
|
|
169
126
|
};
|
|
170
127
|
|
|
128
|
+
#if (NAPI_VERSION > 3)
|
|
129
|
+
template <typename ContextType=void,
|
|
130
|
+
typename Finalizer=std::function<void(Env, void*, ContextType*)>,
|
|
131
|
+
typename FinalizerDataType=void>
|
|
132
|
+
struct ThreadSafeFinalize {
|
|
133
|
+
static inline
|
|
134
|
+
void Wrapper(napi_env env, void* rawFinalizeData, void* /* rawContext */) {
|
|
135
|
+
if (rawFinalizeData == nullptr)
|
|
136
|
+
return;
|
|
137
|
+
|
|
138
|
+
ThreadSafeFinalize* finalizeData =
|
|
139
|
+
static_cast<ThreadSafeFinalize*>(rawFinalizeData);
|
|
140
|
+
finalizeData->callback(Env(env));
|
|
141
|
+
if (finalizeData->tsfn) {
|
|
142
|
+
*finalizeData->tsfn = nullptr;
|
|
143
|
+
}
|
|
144
|
+
delete finalizeData;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
static inline
|
|
148
|
+
void FinalizeWrapperWithData(napi_env env,
|
|
149
|
+
void* rawFinalizeData,
|
|
150
|
+
void* /* rawContext */) {
|
|
151
|
+
if (rawFinalizeData == nullptr)
|
|
152
|
+
return;
|
|
153
|
+
|
|
154
|
+
ThreadSafeFinalize* finalizeData =
|
|
155
|
+
static_cast<ThreadSafeFinalize*>(rawFinalizeData);
|
|
156
|
+
finalizeData->callback(Env(env), finalizeData->data);
|
|
157
|
+
if (finalizeData->tsfn) {
|
|
158
|
+
*finalizeData->tsfn = nullptr;
|
|
159
|
+
}
|
|
160
|
+
delete finalizeData;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
static inline
|
|
164
|
+
void FinalizeWrapperWithContext(napi_env env,
|
|
165
|
+
void* rawFinalizeData,
|
|
166
|
+
void* rawContext) {
|
|
167
|
+
if (rawFinalizeData == nullptr)
|
|
168
|
+
return;
|
|
169
|
+
|
|
170
|
+
ThreadSafeFinalize* finalizeData =
|
|
171
|
+
static_cast<ThreadSafeFinalize*>(rawFinalizeData);
|
|
172
|
+
finalizeData->callback(Env(env), static_cast<ContextType*>(rawContext));
|
|
173
|
+
if (finalizeData->tsfn) {
|
|
174
|
+
*finalizeData->tsfn = nullptr;
|
|
175
|
+
}
|
|
176
|
+
delete finalizeData;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
static inline
|
|
180
|
+
void FinalizeFinalizeWrapperWithDataAndContext(napi_env env,
|
|
181
|
+
void* rawFinalizeData,
|
|
182
|
+
void* rawContext) {
|
|
183
|
+
if (rawFinalizeData == nullptr)
|
|
184
|
+
return;
|
|
185
|
+
|
|
186
|
+
ThreadSafeFinalize* finalizeData =
|
|
187
|
+
static_cast<ThreadSafeFinalize*>(rawFinalizeData);
|
|
188
|
+
finalizeData->callback(Env(env), finalizeData->data,
|
|
189
|
+
static_cast<ContextType*>(rawContext));
|
|
190
|
+
if (finalizeData->tsfn) {
|
|
191
|
+
*finalizeData->tsfn = nullptr;
|
|
192
|
+
}
|
|
193
|
+
delete finalizeData;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
FinalizerDataType* data;
|
|
197
|
+
Finalizer callback;
|
|
198
|
+
napi_threadsafe_function* tsfn;
|
|
199
|
+
};
|
|
200
|
+
#endif
|
|
201
|
+
|
|
171
202
|
template <typename Getter, typename Setter>
|
|
172
203
|
struct AccessorCallbackData {
|
|
173
204
|
static inline
|
|
@@ -176,6 +207,7 @@ struct AccessorCallbackData {
|
|
|
176
207
|
CallbackInfo callbackInfo(env, info);
|
|
177
208
|
AccessorCallbackData* callbackData =
|
|
178
209
|
static_cast<AccessorCallbackData*>(callbackInfo.Data());
|
|
210
|
+
callbackInfo.SetData(callbackData->data);
|
|
179
211
|
return callbackData->getterCallback(callbackInfo);
|
|
180
212
|
});
|
|
181
213
|
}
|
|
@@ -186,6 +218,7 @@ struct AccessorCallbackData {
|
|
|
186
218
|
CallbackInfo callbackInfo(env, info);
|
|
187
219
|
AccessorCallbackData* callbackData =
|
|
188
220
|
static_cast<AccessorCallbackData*>(callbackInfo.Data());
|
|
221
|
+
callbackInfo.SetData(callbackData->data);
|
|
189
222
|
callbackData->setterCallback(callbackInfo);
|
|
190
223
|
return nullptr;
|
|
191
224
|
});
|
|
@@ -193,6 +226,7 @@ struct AccessorCallbackData {
|
|
|
193
226
|
|
|
194
227
|
Getter getterCallback;
|
|
195
228
|
Setter setterCallback;
|
|
229
|
+
void* data;
|
|
196
230
|
};
|
|
197
231
|
|
|
198
232
|
} // namespace details
|
|
@@ -311,7 +345,7 @@ inline bool Value::IsEmpty() const {
|
|
|
311
345
|
}
|
|
312
346
|
|
|
313
347
|
inline napi_valuetype Value::Type() const {
|
|
314
|
-
if (
|
|
348
|
+
if (IsEmpty()) {
|
|
315
349
|
return napi_undefined;
|
|
316
350
|
}
|
|
317
351
|
|
|
@@ -354,7 +388,7 @@ inline bool Value::IsSymbol() const {
|
|
|
354
388
|
}
|
|
355
389
|
|
|
356
390
|
inline bool Value::IsArray() const {
|
|
357
|
-
if (
|
|
391
|
+
if (IsEmpty()) {
|
|
358
392
|
return false;
|
|
359
393
|
}
|
|
360
394
|
|
|
@@ -365,7 +399,7 @@ inline bool Value::IsArray() const {
|
|
|
365
399
|
}
|
|
366
400
|
|
|
367
401
|
inline bool Value::IsArrayBuffer() const {
|
|
368
|
-
if (
|
|
402
|
+
if (IsEmpty()) {
|
|
369
403
|
return false;
|
|
370
404
|
}
|
|
371
405
|
|
|
@@ -376,7 +410,7 @@ inline bool Value::IsArrayBuffer() const {
|
|
|
376
410
|
}
|
|
377
411
|
|
|
378
412
|
inline bool Value::IsTypedArray() const {
|
|
379
|
-
if (
|
|
413
|
+
if (IsEmpty()) {
|
|
380
414
|
return false;
|
|
381
415
|
}
|
|
382
416
|
|
|
@@ -395,7 +429,7 @@ inline bool Value::IsFunction() const {
|
|
|
395
429
|
}
|
|
396
430
|
|
|
397
431
|
inline bool Value::IsPromise() const {
|
|
398
|
-
if (
|
|
432
|
+
if (IsEmpty()) {
|
|
399
433
|
return false;
|
|
400
434
|
}
|
|
401
435
|
|
|
@@ -406,7 +440,7 @@ inline bool Value::IsPromise() const {
|
|
|
406
440
|
}
|
|
407
441
|
|
|
408
442
|
inline bool Value::IsDataView() const {
|
|
409
|
-
if (
|
|
443
|
+
if (IsEmpty()) {
|
|
410
444
|
return false;
|
|
411
445
|
}
|
|
412
446
|
|
|
@@ -417,7 +451,7 @@ inline bool Value::IsDataView() const {
|
|
|
417
451
|
}
|
|
418
452
|
|
|
419
453
|
inline bool Value::IsBuffer() const {
|
|
420
|
-
if (
|
|
454
|
+
if (IsEmpty()) {
|
|
421
455
|
return false;
|
|
422
456
|
}
|
|
423
457
|
|
|
@@ -1060,7 +1094,7 @@ inline bool Object::Delete(uint32_t index) {
|
|
|
1060
1094
|
return result;
|
|
1061
1095
|
}
|
|
1062
1096
|
|
|
1063
|
-
inline Array Object::GetPropertyNames() {
|
|
1097
|
+
inline Array Object::GetPropertyNames() const {
|
|
1064
1098
|
napi_value result;
|
|
1065
1099
|
napi_status status = napi_get_property_names(_env, _value, &result);
|
|
1066
1100
|
NAPI_THROW_IF_FAILED(_env, status, Array());
|
|
@@ -1309,8 +1343,8 @@ inline DataView DataView::New(napi_env env,
|
|
|
1309
1343
|
size_t byteOffset) {
|
|
1310
1344
|
if (byteOffset > arrayBuffer.ByteLength()) {
|
|
1311
1345
|
NAPI_THROW(RangeError::New(env,
|
|
1312
|
-
"Start offset is outside the bounds of the buffer")
|
|
1313
|
-
|
|
1346
|
+
"Start offset is outside the bounds of the buffer"),
|
|
1347
|
+
DataView());
|
|
1314
1348
|
}
|
|
1315
1349
|
return New(env, arrayBuffer, byteOffset,
|
|
1316
1350
|
arrayBuffer.ByteLength() - byteOffset);
|
|
@@ -1321,8 +1355,8 @@ inline DataView DataView::New(napi_env env,
|
|
|
1321
1355
|
size_t byteOffset,
|
|
1322
1356
|
size_t byteLength) {
|
|
1323
1357
|
if (byteOffset + byteLength > arrayBuffer.ByteLength()) {
|
|
1324
|
-
NAPI_THROW(RangeError::New(env, "Invalid DataView length")
|
|
1325
|
-
|
|
1358
|
+
NAPI_THROW(RangeError::New(env, "Invalid DataView length"),
|
|
1359
|
+
DataView());
|
|
1326
1360
|
}
|
|
1327
1361
|
napi_value value;
|
|
1328
1362
|
napi_status status = napi_create_dataview(
|
|
@@ -1448,8 +1482,7 @@ inline T DataView::ReadData(size_t byteOffset) const {
|
|
|
1448
1482
|
if (byteOffset + sizeof(T) > _length ||
|
|
1449
1483
|
byteOffset + sizeof(T) < byteOffset) { // overflow
|
|
1450
1484
|
NAPI_THROW(RangeError::New(_env,
|
|
1451
|
-
"Offset is outside the bounds of the DataView"));
|
|
1452
|
-
return 0;
|
|
1485
|
+
"Offset is outside the bounds of the DataView"), 0);
|
|
1453
1486
|
}
|
|
1454
1487
|
|
|
1455
1488
|
return *reinterpret_cast<T*>(static_cast<uint8_t*>(_data) + byteOffset);
|
|
@@ -1459,9 +1492,8 @@ template <typename T>
|
|
|
1459
1492
|
inline void DataView::WriteData(size_t byteOffset, T value) const {
|
|
1460
1493
|
if (byteOffset + sizeof(T) > _length ||
|
|
1461
1494
|
byteOffset + sizeof(T) < byteOffset) { // overflow
|
|
1462
|
-
|
|
1495
|
+
NAPI_THROW_VOID(RangeError::New(_env,
|
|
1463
1496
|
"Offset is outside the bounds of the DataView"));
|
|
1464
|
-
return;
|
|
1465
1497
|
}
|
|
1466
1498
|
|
|
1467
1499
|
*reinterpret_cast<T*>(static_cast<uint8_t*>(_data) + byteOffset) = value;
|
|
@@ -1597,7 +1629,7 @@ inline TypedArrayOf<T>::TypedArrayOf(napi_env env,
|
|
|
1597
1629
|
: TypedArray(env, value, type, length), _data(data) {
|
|
1598
1630
|
if (!(type == TypedArrayTypeForPrimitiveType<T>() ||
|
|
1599
1631
|
(type == napi_uint8_clamped_array && std::is_same<T, uint8_t>::value))) {
|
|
1600
|
-
|
|
1632
|
+
NAPI_THROW_VOID(TypeError::New(env, "Array type must match the template parameter. "
|
|
1601
1633
|
"(Uint8 arrays may optionally have the \"clamped\" array type.)"));
|
|
1602
1634
|
}
|
|
1603
1635
|
}
|
|
@@ -1657,7 +1689,11 @@ inline Function Function::New(napi_env env,
|
|
|
1657
1689
|
CbData::Wrapper,
|
|
1658
1690
|
callbackData,
|
|
1659
1691
|
&value);
|
|
1660
|
-
|
|
1692
|
+
if (status != napi_ok) {
|
|
1693
|
+
delete callbackData;
|
|
1694
|
+
NAPI_THROW_IF_FAILED(env, status, Function());
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1661
1697
|
return Function(env, value);
|
|
1662
1698
|
}
|
|
1663
1699
|
|
|
@@ -2031,8 +2067,20 @@ inline const std::string& Error::Message() const NAPI_NOEXCEPT {
|
|
|
2031
2067
|
inline void Error::ThrowAsJavaScriptException() const {
|
|
2032
2068
|
HandleScope scope(_env);
|
|
2033
2069
|
if (!IsEmpty()) {
|
|
2070
|
+
|
|
2071
|
+
// We intentionally don't use `NAPI_THROW_*` macros here to ensure
|
|
2072
|
+
// that there is no possible recursion as `ThrowAsJavaScriptException`
|
|
2073
|
+
// is part of `NAPI_THROW_*` macro definition for noexcept.
|
|
2074
|
+
|
|
2034
2075
|
napi_status status = napi_throw(_env, Value());
|
|
2035
|
-
|
|
2076
|
+
|
|
2077
|
+
#ifdef NAPI_CPP_EXCEPTIONS
|
|
2078
|
+
if (status != napi_ok) {
|
|
2079
|
+
throw Error::New(_env);
|
|
2080
|
+
}
|
|
2081
|
+
#else // NAPI_CPP_EXCEPTIONS
|
|
2082
|
+
NAPI_FATAL_IF_FAILED(status, "Error::ThrowAsJavaScriptException", "napi_throw");
|
|
2083
|
+
#endif // NAPI_CPP_EXCEPTIONS
|
|
2036
2084
|
}
|
|
2037
2085
|
}
|
|
2038
2086
|
|
|
@@ -2603,12 +2651,15 @@ PropertyDescriptor::Accessor(Napi::Env env,
|
|
|
2603
2651
|
const char* utf8name,
|
|
2604
2652
|
Getter getter,
|
|
2605
2653
|
napi_property_attributes attributes,
|
|
2606
|
-
void*
|
|
2654
|
+
void* data) {
|
|
2607
2655
|
typedef details::CallbackData<Getter, Napi::Value> CbData;
|
|
2608
|
-
auto callbackData = new CbData({ getter,
|
|
2656
|
+
auto callbackData = new CbData({ getter, data });
|
|
2609
2657
|
|
|
2610
2658
|
napi_status status = AttachData(env, object, callbackData);
|
|
2611
|
-
|
|
2659
|
+
if (status != napi_ok) {
|
|
2660
|
+
delete callbackData;
|
|
2661
|
+
NAPI_THROW_IF_FAILED(env, status, napi_property_descriptor());
|
|
2662
|
+
}
|
|
2612
2663
|
|
|
2613
2664
|
return PropertyDescriptor({
|
|
2614
2665
|
utf8name,
|
|
@@ -2638,12 +2689,15 @@ inline PropertyDescriptor PropertyDescriptor::Accessor(Napi::Env env,
|
|
|
2638
2689
|
Name name,
|
|
2639
2690
|
Getter getter,
|
|
2640
2691
|
napi_property_attributes attributes,
|
|
2641
|
-
void*
|
|
2692
|
+
void* data) {
|
|
2642
2693
|
typedef details::CallbackData<Getter, Napi::Value> CbData;
|
|
2643
|
-
auto callbackData = new CbData({ getter,
|
|
2694
|
+
auto callbackData = new CbData({ getter, data });
|
|
2644
2695
|
|
|
2645
2696
|
napi_status status = AttachData(env, object, callbackData);
|
|
2646
|
-
|
|
2697
|
+
if (status != napi_ok) {
|
|
2698
|
+
delete callbackData;
|
|
2699
|
+
NAPI_THROW_IF_FAILED(env, status, napi_property_descriptor());
|
|
2700
|
+
}
|
|
2647
2701
|
|
|
2648
2702
|
return PropertyDescriptor({
|
|
2649
2703
|
nullptr,
|
|
@@ -2664,12 +2718,15 @@ inline PropertyDescriptor PropertyDescriptor::Accessor(Napi::Env env,
|
|
|
2664
2718
|
Getter getter,
|
|
2665
2719
|
Setter setter,
|
|
2666
2720
|
napi_property_attributes attributes,
|
|
2667
|
-
void*
|
|
2721
|
+
void* data) {
|
|
2668
2722
|
typedef details::AccessorCallbackData<Getter, Setter> CbData;
|
|
2669
|
-
auto callbackData = new CbData({ getter, setter });
|
|
2723
|
+
auto callbackData = new CbData({ getter, setter, data });
|
|
2670
2724
|
|
|
2671
2725
|
napi_status status = AttachData(env, object, callbackData);
|
|
2672
|
-
|
|
2726
|
+
if (status != napi_ok) {
|
|
2727
|
+
delete callbackData;
|
|
2728
|
+
NAPI_THROW_IF_FAILED(env, status, napi_property_descriptor());
|
|
2729
|
+
}
|
|
2673
2730
|
|
|
2674
2731
|
return PropertyDescriptor({
|
|
2675
2732
|
utf8name,
|
|
@@ -2701,12 +2758,15 @@ inline PropertyDescriptor PropertyDescriptor::Accessor(Napi::Env env,
|
|
|
2701
2758
|
Getter getter,
|
|
2702
2759
|
Setter setter,
|
|
2703
2760
|
napi_property_attributes attributes,
|
|
2704
|
-
void*
|
|
2761
|
+
void* data) {
|
|
2705
2762
|
typedef details::AccessorCallbackData<Getter, Setter> CbData;
|
|
2706
|
-
auto callbackData = new CbData({ getter, setter });
|
|
2763
|
+
auto callbackData = new CbData({ getter, setter, data });
|
|
2707
2764
|
|
|
2708
2765
|
napi_status status = AttachData(env, object, callbackData);
|
|
2709
|
-
|
|
2766
|
+
if (status != napi_ok) {
|
|
2767
|
+
delete callbackData;
|
|
2768
|
+
NAPI_THROW_IF_FAILED(env, status, napi_property_descriptor());
|
|
2769
|
+
}
|
|
2710
2770
|
|
|
2711
2771
|
return PropertyDescriptor({
|
|
2712
2772
|
nullptr,
|
|
@@ -3524,7 +3584,34 @@ inline AsyncWorker::AsyncWorker(const Object& receiver,
|
|
|
3524
3584
|
const Object& resource)
|
|
3525
3585
|
: _env(callback.Env()),
|
|
3526
3586
|
_receiver(Napi::Persistent(receiver)),
|
|
3527
|
-
_callback(Napi::Persistent(callback))
|
|
3587
|
+
_callback(Napi::Persistent(callback)),
|
|
3588
|
+
_suppress_destruct(false) {
|
|
3589
|
+
napi_value resource_id;
|
|
3590
|
+
napi_status status = napi_create_string_latin1(
|
|
3591
|
+
_env, resource_name, NAPI_AUTO_LENGTH, &resource_id);
|
|
3592
|
+
NAPI_THROW_IF_FAILED_VOID(_env, status);
|
|
3593
|
+
|
|
3594
|
+
status = napi_create_async_work(_env, resource, resource_id, OnExecute,
|
|
3595
|
+
OnWorkComplete, this, &_work);
|
|
3596
|
+
NAPI_THROW_IF_FAILED_VOID(_env, status);
|
|
3597
|
+
}
|
|
3598
|
+
|
|
3599
|
+
inline AsyncWorker::AsyncWorker(Napi::Env env)
|
|
3600
|
+
: AsyncWorker(env, "generic") {
|
|
3601
|
+
}
|
|
3602
|
+
|
|
3603
|
+
inline AsyncWorker::AsyncWorker(Napi::Env env,
|
|
3604
|
+
const char* resource_name)
|
|
3605
|
+
: AsyncWorker(env, resource_name, Object::New(env)) {
|
|
3606
|
+
}
|
|
3607
|
+
|
|
3608
|
+
inline AsyncWorker::AsyncWorker(Napi::Env env,
|
|
3609
|
+
const char* resource_name,
|
|
3610
|
+
const Object& resource)
|
|
3611
|
+
: _env(env),
|
|
3612
|
+
_receiver(),
|
|
3613
|
+
_callback(),
|
|
3614
|
+
_suppress_destruct(false) {
|
|
3528
3615
|
napi_value resource_id;
|
|
3529
3616
|
napi_status status = napi_create_string_latin1(
|
|
3530
3617
|
_env, resource_name, NAPI_AUTO_LENGTH, &resource_id);
|
|
@@ -3542,6 +3629,10 @@ inline AsyncWorker::~AsyncWorker() {
|
|
|
3542
3629
|
}
|
|
3543
3630
|
}
|
|
3544
3631
|
|
|
3632
|
+
inline void AsyncWorker::Destroy() {
|
|
3633
|
+
delete this;
|
|
3634
|
+
}
|
|
3635
|
+
|
|
3545
3636
|
inline AsyncWorker::AsyncWorker(AsyncWorker&& other) {
|
|
3546
3637
|
_env = other._env;
|
|
3547
3638
|
other._env = nullptr;
|
|
@@ -3550,6 +3641,7 @@ inline AsyncWorker::AsyncWorker(AsyncWorker&& other) {
|
|
|
3550
3641
|
_receiver = std::move(other._receiver);
|
|
3551
3642
|
_callback = std::move(other._callback);
|
|
3552
3643
|
_error = std::move(other._error);
|
|
3644
|
+
_suppress_destruct = other._suppress_destruct;
|
|
3553
3645
|
}
|
|
3554
3646
|
|
|
3555
3647
|
inline AsyncWorker& AsyncWorker::operator =(AsyncWorker&& other) {
|
|
@@ -3560,6 +3652,7 @@ inline AsyncWorker& AsyncWorker::operator =(AsyncWorker&& other) {
|
|
|
3560
3652
|
_receiver = std::move(other._receiver);
|
|
3561
3653
|
_callback = std::move(other._callback);
|
|
3562
3654
|
_error = std::move(other._error);
|
|
3655
|
+
_suppress_destruct = other._suppress_destruct;
|
|
3563
3656
|
return *this;
|
|
3564
3657
|
}
|
|
3565
3658
|
|
|
@@ -3589,19 +3682,34 @@ inline FunctionReference& AsyncWorker::Callback() {
|
|
|
3589
3682
|
return _callback;
|
|
3590
3683
|
}
|
|
3591
3684
|
|
|
3685
|
+
inline void AsyncWorker::SuppressDestruct() {
|
|
3686
|
+
_suppress_destruct = true;
|
|
3687
|
+
}
|
|
3688
|
+
|
|
3592
3689
|
inline void AsyncWorker::OnOK() {
|
|
3593
|
-
_callback.
|
|
3690
|
+
if (!_callback.IsEmpty()) {
|
|
3691
|
+
_callback.Call(_receiver.Value(), GetResult(_callback.Env()));
|
|
3692
|
+
}
|
|
3594
3693
|
}
|
|
3595
3694
|
|
|
3596
3695
|
inline void AsyncWorker::OnError(const Error& e) {
|
|
3597
|
-
_callback.
|
|
3696
|
+
if (!_callback.IsEmpty()) {
|
|
3697
|
+
_callback.Call(_receiver.Value(), std::initializer_list<napi_value>{ e.Value() });
|
|
3698
|
+
}
|
|
3598
3699
|
}
|
|
3599
3700
|
|
|
3600
3701
|
inline void AsyncWorker::SetError(const std::string& error) {
|
|
3601
3702
|
_error = error;
|
|
3602
3703
|
}
|
|
3603
3704
|
|
|
3604
|
-
inline
|
|
3705
|
+
inline std::vector<napi_value> AsyncWorker::GetResult(Napi::Env /*env*/) {
|
|
3706
|
+
return {};
|
|
3707
|
+
}
|
|
3708
|
+
// The OnExecute method receives an napi_env argument. However, do NOT
|
|
3709
|
+
// use it within this method, as it does not run on the main thread and must
|
|
3710
|
+
// not run any method that would cause JavaScript to run. In practice, this
|
|
3711
|
+
// means that almost any use of napi_env will be incorrect.
|
|
3712
|
+
inline void AsyncWorker::OnExecute(napi_env /*DO_NOT_USE*/, void* this_pointer) {
|
|
3605
3713
|
AsyncWorker* self = static_cast<AsyncWorker*>(this_pointer);
|
|
3606
3714
|
#ifdef NAPI_CPP_EXCEPTIONS
|
|
3607
3715
|
try {
|
|
@@ -3629,9 +3737,332 @@ inline void AsyncWorker::OnWorkComplete(
|
|
|
3629
3737
|
return nullptr;
|
|
3630
3738
|
});
|
|
3631
3739
|
}
|
|
3632
|
-
|
|
3740
|
+
if (!self->_suppress_destruct) {
|
|
3741
|
+
self->Destroy();
|
|
3742
|
+
}
|
|
3743
|
+
}
|
|
3744
|
+
|
|
3745
|
+
#if (NAPI_VERSION > 3)
|
|
3746
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
3747
|
+
// ThreadSafeFunction class
|
|
3748
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
3749
|
+
|
|
3750
|
+
// static
|
|
3751
|
+
template <typename ResourceString>
|
|
3752
|
+
inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
|
|
3753
|
+
const Function& callback,
|
|
3754
|
+
ResourceString resourceName,
|
|
3755
|
+
size_t maxQueueSize,
|
|
3756
|
+
size_t initialThreadCount) {
|
|
3757
|
+
return New(env, callback, Object(), resourceName, maxQueueSize,
|
|
3758
|
+
initialThreadCount);
|
|
3759
|
+
}
|
|
3760
|
+
|
|
3761
|
+
// static
|
|
3762
|
+
template <typename ResourceString, typename ContextType>
|
|
3763
|
+
inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
|
|
3764
|
+
const Function& callback,
|
|
3765
|
+
ResourceString resourceName,
|
|
3766
|
+
size_t maxQueueSize,
|
|
3767
|
+
size_t initialThreadCount,
|
|
3768
|
+
ContextType* context) {
|
|
3769
|
+
return New(env, callback, Object(), resourceName, maxQueueSize,
|
|
3770
|
+
initialThreadCount, context);
|
|
3771
|
+
}
|
|
3772
|
+
|
|
3773
|
+
// static
|
|
3774
|
+
template <typename ResourceString, typename Finalizer>
|
|
3775
|
+
inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
|
|
3776
|
+
const Function& callback,
|
|
3777
|
+
ResourceString resourceName,
|
|
3778
|
+
size_t maxQueueSize,
|
|
3779
|
+
size_t initialThreadCount,
|
|
3780
|
+
Finalizer finalizeCallback) {
|
|
3781
|
+
return New(env, callback, Object(), resourceName, maxQueueSize,
|
|
3782
|
+
initialThreadCount, finalizeCallback);
|
|
3783
|
+
}
|
|
3784
|
+
|
|
3785
|
+
// static
|
|
3786
|
+
template <typename ResourceString, typename Finalizer,
|
|
3787
|
+
typename FinalizerDataType>
|
|
3788
|
+
inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
|
|
3789
|
+
const Function& callback,
|
|
3790
|
+
ResourceString resourceName,
|
|
3791
|
+
size_t maxQueueSize,
|
|
3792
|
+
size_t initialThreadCount,
|
|
3793
|
+
Finalizer finalizeCallback,
|
|
3794
|
+
FinalizerDataType* data) {
|
|
3795
|
+
return New(env, callback, Object(), resourceName, maxQueueSize,
|
|
3796
|
+
initialThreadCount, finalizeCallback, data);
|
|
3797
|
+
}
|
|
3798
|
+
|
|
3799
|
+
// static
|
|
3800
|
+
template <typename ResourceString, typename ContextType, typename Finalizer>
|
|
3801
|
+
inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
|
|
3802
|
+
const Function& callback,
|
|
3803
|
+
ResourceString resourceName,
|
|
3804
|
+
size_t maxQueueSize,
|
|
3805
|
+
size_t initialThreadCount,
|
|
3806
|
+
ContextType* context,
|
|
3807
|
+
Finalizer finalizeCallback) {
|
|
3808
|
+
return New(env, callback, Object(), resourceName, maxQueueSize,
|
|
3809
|
+
initialThreadCount, context, finalizeCallback);
|
|
3810
|
+
}
|
|
3811
|
+
|
|
3812
|
+
// static
|
|
3813
|
+
template <typename ResourceString, typename ContextType,
|
|
3814
|
+
typename Finalizer, typename FinalizerDataType>
|
|
3815
|
+
inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
|
|
3816
|
+
const Function& callback,
|
|
3817
|
+
ResourceString resourceName,
|
|
3818
|
+
size_t maxQueueSize,
|
|
3819
|
+
size_t initialThreadCount,
|
|
3820
|
+
ContextType* context,
|
|
3821
|
+
Finalizer finalizeCallback,
|
|
3822
|
+
FinalizerDataType* data) {
|
|
3823
|
+
return New(env, callback, Object(), resourceName, maxQueueSize,
|
|
3824
|
+
initialThreadCount, context, finalizeCallback, data);
|
|
3825
|
+
}
|
|
3826
|
+
|
|
3827
|
+
// static
|
|
3828
|
+
template <typename ResourceString>
|
|
3829
|
+
inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
|
|
3830
|
+
const Function& callback,
|
|
3831
|
+
const Object& resource,
|
|
3832
|
+
ResourceString resourceName,
|
|
3833
|
+
size_t maxQueueSize,
|
|
3834
|
+
size_t initialThreadCount) {
|
|
3835
|
+
return New(env, callback, resource, resourceName, maxQueueSize,
|
|
3836
|
+
initialThreadCount, static_cast<void*>(nullptr) /* context */);
|
|
3837
|
+
}
|
|
3838
|
+
|
|
3839
|
+
// static
|
|
3840
|
+
template <typename ResourceString, typename ContextType>
|
|
3841
|
+
inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
|
|
3842
|
+
const Function& callback,
|
|
3843
|
+
const Object& resource,
|
|
3844
|
+
ResourceString resourceName,
|
|
3845
|
+
size_t maxQueueSize,
|
|
3846
|
+
size_t initialThreadCount,
|
|
3847
|
+
ContextType* context) {
|
|
3848
|
+
return New(env, callback, resource, resourceName, maxQueueSize,
|
|
3849
|
+
initialThreadCount, context,
|
|
3850
|
+
[](Env, ContextType*) {} /* empty finalizer */);
|
|
3851
|
+
}
|
|
3852
|
+
|
|
3853
|
+
// static
|
|
3854
|
+
template <typename ResourceString, typename Finalizer>
|
|
3855
|
+
inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
|
|
3856
|
+
const Function& callback,
|
|
3857
|
+
const Object& resource,
|
|
3858
|
+
ResourceString resourceName,
|
|
3859
|
+
size_t maxQueueSize,
|
|
3860
|
+
size_t initialThreadCount,
|
|
3861
|
+
Finalizer finalizeCallback) {
|
|
3862
|
+
return New(env, callback, resource, resourceName, maxQueueSize,
|
|
3863
|
+
initialThreadCount, static_cast<void*>(nullptr) /* context */,
|
|
3864
|
+
finalizeCallback, static_cast<void*>(nullptr) /* data */,
|
|
3865
|
+
details::ThreadSafeFinalize<void, Finalizer>::Wrapper);
|
|
3866
|
+
}
|
|
3867
|
+
|
|
3868
|
+
// static
|
|
3869
|
+
template <typename ResourceString, typename Finalizer,
|
|
3870
|
+
typename FinalizerDataType>
|
|
3871
|
+
inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
|
|
3872
|
+
const Function& callback,
|
|
3873
|
+
const Object& resource,
|
|
3874
|
+
ResourceString resourceName,
|
|
3875
|
+
size_t maxQueueSize,
|
|
3876
|
+
size_t initialThreadCount,
|
|
3877
|
+
Finalizer finalizeCallback,
|
|
3878
|
+
FinalizerDataType* data) {
|
|
3879
|
+
return New(env, callback, resource, resourceName, maxQueueSize,
|
|
3880
|
+
initialThreadCount, static_cast<void*>(nullptr) /* context */,
|
|
3881
|
+
finalizeCallback, data,
|
|
3882
|
+
details::ThreadSafeFinalize<
|
|
3883
|
+
void, Finalizer, FinalizerDataType>::FinalizeWrapperWithData);
|
|
3884
|
+
}
|
|
3885
|
+
|
|
3886
|
+
// static
|
|
3887
|
+
template <typename ResourceString, typename ContextType, typename Finalizer>
|
|
3888
|
+
inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
|
|
3889
|
+
const Function& callback,
|
|
3890
|
+
const Object& resource,
|
|
3891
|
+
ResourceString resourceName,
|
|
3892
|
+
size_t maxQueueSize,
|
|
3893
|
+
size_t initialThreadCount,
|
|
3894
|
+
ContextType* context,
|
|
3895
|
+
Finalizer finalizeCallback) {
|
|
3896
|
+
return New(env, callback, resource, resourceName, maxQueueSize,
|
|
3897
|
+
initialThreadCount, context, finalizeCallback,
|
|
3898
|
+
static_cast<void*>(nullptr) /* data */,
|
|
3899
|
+
details::ThreadSafeFinalize<
|
|
3900
|
+
ContextType, Finalizer>::FinalizeWrapperWithContext);
|
|
3901
|
+
}
|
|
3902
|
+
|
|
3903
|
+
// static
|
|
3904
|
+
template <typename ResourceString, typename ContextType,
|
|
3905
|
+
typename Finalizer, typename FinalizerDataType>
|
|
3906
|
+
inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
|
|
3907
|
+
const Function& callback,
|
|
3908
|
+
const Object& resource,
|
|
3909
|
+
ResourceString resourceName,
|
|
3910
|
+
size_t maxQueueSize,
|
|
3911
|
+
size_t initialThreadCount,
|
|
3912
|
+
ContextType* context,
|
|
3913
|
+
Finalizer finalizeCallback,
|
|
3914
|
+
FinalizerDataType* data) {
|
|
3915
|
+
return New(env, callback, resource, resourceName, maxQueueSize,
|
|
3916
|
+
initialThreadCount, context, finalizeCallback, data,
|
|
3917
|
+
details::ThreadSafeFinalize<ContextType, Finalizer,
|
|
3918
|
+
FinalizerDataType>::FinalizeFinalizeWrapperWithDataAndContext);
|
|
3919
|
+
}
|
|
3920
|
+
|
|
3921
|
+
inline ThreadSafeFunction::ThreadSafeFunction()
|
|
3922
|
+
: _tsfn(new napi_threadsafe_function(nullptr)) {
|
|
3923
|
+
}
|
|
3924
|
+
|
|
3925
|
+
inline ThreadSafeFunction::ThreadSafeFunction(
|
|
3926
|
+
napi_threadsafe_function tsfn)
|
|
3927
|
+
: _tsfn(new napi_threadsafe_function(tsfn)) {
|
|
3928
|
+
}
|
|
3929
|
+
|
|
3930
|
+
inline ThreadSafeFunction::ThreadSafeFunction(ThreadSafeFunction&& other)
|
|
3931
|
+
: _tsfn(std::move(other._tsfn)) {
|
|
3932
|
+
other._tsfn.reset();
|
|
3933
|
+
}
|
|
3934
|
+
|
|
3935
|
+
inline ThreadSafeFunction& ThreadSafeFunction::operator =(
|
|
3936
|
+
ThreadSafeFunction&& other) {
|
|
3937
|
+
if (*_tsfn != nullptr) {
|
|
3938
|
+
Error::Fatal("ThreadSafeFunction::operator =",
|
|
3939
|
+
"You cannot assign a new TSFN because existing one is still alive.");
|
|
3940
|
+
return *this;
|
|
3941
|
+
}
|
|
3942
|
+
_tsfn = std::move(other._tsfn);
|
|
3943
|
+
other._tsfn.reset();
|
|
3944
|
+
return *this;
|
|
3945
|
+
}
|
|
3946
|
+
|
|
3947
|
+
inline napi_status ThreadSafeFunction::BlockingCall() const {
|
|
3948
|
+
return CallInternal(nullptr, napi_tsfn_blocking);
|
|
3949
|
+
}
|
|
3950
|
+
|
|
3951
|
+
template <typename Callback>
|
|
3952
|
+
inline napi_status ThreadSafeFunction::BlockingCall(
|
|
3953
|
+
Callback callback) const {
|
|
3954
|
+
return CallInternal(new CallbackWrapper(callback), napi_tsfn_blocking);
|
|
3955
|
+
}
|
|
3956
|
+
|
|
3957
|
+
template <typename DataType, typename Callback>
|
|
3958
|
+
inline napi_status ThreadSafeFunction::BlockingCall(
|
|
3959
|
+
DataType* data, Callback callback) const {
|
|
3960
|
+
auto wrapper = [data, callback](Env env, Function jsCallback) {
|
|
3961
|
+
callback(env, jsCallback, data);
|
|
3962
|
+
};
|
|
3963
|
+
return CallInternal(new CallbackWrapper(wrapper), napi_tsfn_blocking);
|
|
3964
|
+
}
|
|
3965
|
+
|
|
3966
|
+
inline napi_status ThreadSafeFunction::NonBlockingCall() const {
|
|
3967
|
+
return CallInternal(nullptr, napi_tsfn_nonblocking);
|
|
3968
|
+
}
|
|
3969
|
+
|
|
3970
|
+
template <typename Callback>
|
|
3971
|
+
inline napi_status ThreadSafeFunction::NonBlockingCall(
|
|
3972
|
+
Callback callback) const {
|
|
3973
|
+
return CallInternal(new CallbackWrapper(callback), napi_tsfn_nonblocking);
|
|
3974
|
+
}
|
|
3975
|
+
|
|
3976
|
+
template <typename DataType, typename Callback>
|
|
3977
|
+
inline napi_status ThreadSafeFunction::NonBlockingCall(
|
|
3978
|
+
DataType* data, Callback callback) const {
|
|
3979
|
+
auto wrapper = [data, callback](Env env, Function jsCallback) {
|
|
3980
|
+
callback(env, jsCallback, data);
|
|
3981
|
+
};
|
|
3982
|
+
return CallInternal(new CallbackWrapper(wrapper), napi_tsfn_nonblocking);
|
|
3983
|
+
}
|
|
3984
|
+
|
|
3985
|
+
inline napi_status ThreadSafeFunction::Acquire() const {
|
|
3986
|
+
return napi_acquire_threadsafe_function(*_tsfn);
|
|
3987
|
+
}
|
|
3988
|
+
|
|
3989
|
+
inline napi_status ThreadSafeFunction::Release() {
|
|
3990
|
+
return napi_release_threadsafe_function(*_tsfn, napi_tsfn_release);
|
|
3991
|
+
}
|
|
3992
|
+
|
|
3993
|
+
inline napi_status ThreadSafeFunction::Abort() {
|
|
3994
|
+
return napi_release_threadsafe_function(*_tsfn, napi_tsfn_abort);
|
|
3995
|
+
}
|
|
3996
|
+
|
|
3997
|
+
inline ThreadSafeFunction::ConvertibleContext
|
|
3998
|
+
ThreadSafeFunction::GetContext() const {
|
|
3999
|
+
void* context;
|
|
4000
|
+
napi_get_threadsafe_function_context(*_tsfn, &context);
|
|
4001
|
+
return ConvertibleContext({ context });
|
|
4002
|
+
}
|
|
4003
|
+
|
|
4004
|
+
// static
|
|
4005
|
+
template <typename ResourceString, typename ContextType,
|
|
4006
|
+
typename Finalizer, typename FinalizerDataType>
|
|
4007
|
+
inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
|
|
4008
|
+
const Function& callback,
|
|
4009
|
+
const Object& resource,
|
|
4010
|
+
ResourceString resourceName,
|
|
4011
|
+
size_t maxQueueSize,
|
|
4012
|
+
size_t initialThreadCount,
|
|
4013
|
+
ContextType* context,
|
|
4014
|
+
Finalizer finalizeCallback,
|
|
4015
|
+
FinalizerDataType* data,
|
|
4016
|
+
napi_finalize wrapper) {
|
|
4017
|
+
static_assert(details::can_make_string<ResourceString>::value
|
|
4018
|
+
|| std::is_convertible<ResourceString, napi_value>::value,
|
|
4019
|
+
"Resource name should be convertible to the string type");
|
|
4020
|
+
|
|
4021
|
+
ThreadSafeFunction tsfn;
|
|
4022
|
+
auto* finalizeData = new details::ThreadSafeFinalize<ContextType, Finalizer,
|
|
4023
|
+
FinalizerDataType>({ data, finalizeCallback, tsfn._tsfn.get() });
|
|
4024
|
+
napi_status status = napi_create_threadsafe_function(env, callback, resource,
|
|
4025
|
+
Value::From(env, resourceName), maxQueueSize, initialThreadCount,
|
|
4026
|
+
finalizeData, wrapper, context, CallJS, tsfn._tsfn.get());
|
|
4027
|
+
if (status != napi_ok) {
|
|
4028
|
+
delete finalizeData;
|
|
4029
|
+
NAPI_THROW_IF_FAILED(env, status, ThreadSafeFunction());
|
|
4030
|
+
}
|
|
4031
|
+
|
|
4032
|
+
return tsfn;
|
|
4033
|
+
}
|
|
4034
|
+
|
|
4035
|
+
inline napi_status ThreadSafeFunction::CallInternal(
|
|
4036
|
+
CallbackWrapper* callbackWrapper,
|
|
4037
|
+
napi_threadsafe_function_call_mode mode) const {
|
|
4038
|
+
napi_status status = napi_call_threadsafe_function(
|
|
4039
|
+
*_tsfn, callbackWrapper, mode);
|
|
4040
|
+
if (status != napi_ok && callbackWrapper != nullptr) {
|
|
4041
|
+
delete callbackWrapper;
|
|
4042
|
+
}
|
|
4043
|
+
|
|
4044
|
+
return status;
|
|
3633
4045
|
}
|
|
3634
4046
|
|
|
4047
|
+
// static
|
|
4048
|
+
inline void ThreadSafeFunction::CallJS(napi_env env,
|
|
4049
|
+
napi_value jsCallback,
|
|
4050
|
+
void* /* context */,
|
|
4051
|
+
void* data) {
|
|
4052
|
+
if (env == nullptr && jsCallback == nullptr) {
|
|
4053
|
+
return;
|
|
4054
|
+
}
|
|
4055
|
+
|
|
4056
|
+
if (data != nullptr) {
|
|
4057
|
+
auto* callbackWrapper = static_cast<CallbackWrapper*>(data);
|
|
4058
|
+
(*callbackWrapper)(env, Function(env, jsCallback));
|
|
4059
|
+
delete callbackWrapper;
|
|
4060
|
+
} else if (jsCallback != nullptr) {
|
|
4061
|
+
Function(env, jsCallback).Call({});
|
|
4062
|
+
}
|
|
4063
|
+
}
|
|
4064
|
+
#endif
|
|
4065
|
+
|
|
3635
4066
|
////////////////////////////////////////////////////////////////////////////////
|
|
3636
4067
|
// Memory Management class
|
|
3637
4068
|
////////////////////////////////////////////////////////////////////////////////
|
|
@@ -3661,10 +4092,6 @@ inline const napi_node_version* VersionManagement::GetNodeVersion(Env env) {
|
|
|
3661
4092
|
return result;
|
|
3662
4093
|
}
|
|
3663
4094
|
|
|
3664
|
-
// These macros shouldn't be useful in user code.
|
|
3665
|
-
#undef NAPI_THROW
|
|
3666
|
-
#undef NAPI_THROW_IF_FAILED
|
|
3667
|
-
|
|
3668
4095
|
} // namespace Napi
|
|
3669
4096
|
|
|
3670
4097
|
#endif // SRC_NAPI_INL_H_
|