node-addon-api 2.0.2 → 3.1.0
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/.clang-format +111 -0
- package/.github/workflows/ci.yml +55 -0
- package/.github/workflows/linter.yml +24 -0
- package/.github/workflows/stale.yml +18 -0
- package/.travis.yml +1 -5
- package/CHANGELOG.md +237 -23
- package/README.md +101 -31
- package/appveyor.yml +3 -14
- package/benchmark/README.md +47 -0
- package/benchmark/binding.gyp +25 -0
- package/benchmark/function_args.cc +217 -0
- package/benchmark/function_args.js +60 -0
- package/benchmark/index.js +34 -0
- package/benchmark/property_descriptor.cc +91 -0
- package/benchmark/property_descriptor.js +37 -0
- package/common.gypi +21 -0
- package/doc/addon.md +157 -0
- package/doc/array.md +81 -0
- package/doc/array_buffer.md +20 -0
- package/doc/async_context.md +1 -1
- package/doc/async_worker.md +34 -5
- package/doc/{async_progress_worker.md → async_worker_variants.md} +236 -23
- package/doc/bigint.md +7 -2
- package/doc/boolean.md +5 -1
- package/doc/buffer.md +4 -0
- package/doc/checker-tool.md +1 -1
- package/doc/class_property_descriptor.md +3 -3
- package/doc/creating_a_release.md +6 -6
- package/doc/dataview.md +4 -0
- package/doc/date.md +2 -2
- package/doc/env.md +69 -0
- package/doc/error.md +5 -0
- package/doc/escapable_handle_scope.md +1 -1
- package/doc/external.md +4 -0
- package/doc/function.md +111 -3
- package/doc/function_reference.md +1 -1
- package/doc/handle_scope.md +1 -1
- package/doc/hierarchy.md +91 -0
- package/doc/instance_wrap.md +408 -0
- package/doc/name.md +29 -0
- package/doc/number.md +1 -1
- package/doc/object.md +44 -1
- package/doc/object_lifetime_management.md +2 -2
- package/doc/object_reference.md +1 -1
- package/doc/object_wrap.md +220 -216
- package/doc/prebuild_tools.md +2 -2
- package/doc/promises.md +5 -0
- package/doc/property_descriptor.md +67 -12
- package/doc/setup.md +1 -2
- package/doc/string.md +5 -1
- package/doc/symbol.md +5 -1
- package/doc/threadsafe.md +121 -0
- package/doc/threadsafe_function.md +16 -46
- package/doc/typed_array.md +4 -0
- package/doc/typed_array_of.md +4 -0
- package/doc/typed_threadsafe_function.md +307 -0
- package/doc/value.md +166 -104
- package/doc/version_management.md +2 -2
- package/except.gypi +16 -0
- package/index.js +7 -41
- package/napi-inl.h +1685 -464
- package/napi.h +606 -141
- package/node_api.gyp +9 -0
- package/noexcept.gypi +16 -0
- package/{src/nothing.c → nothing.c} +0 -0
- package/package-support.json +21 -0
- package/package.json +106 -2
- package/tools/README.md +12 -6
- package/tools/clang-format.js +47 -0
- package/tools/conversion.js +4 -8
- package/doc/Doxyfile +0 -2450
- package/doc/basic_types.md +0 -423
- package/doc/working_with_javascript_values.md +0 -14
- package/external-napi/node_api.h +0 -7
- package/src/node_api.cc +0 -3655
- package/src/node_api.gyp +0 -21
- package/src/node_api.h +0 -588
- package/src/node_api_types.h +0 -115
- package/src/node_internals.cc +0 -142
- package/src/node_internals.h +0 -157
- package/src/util-inl.h +0 -38
- package/src/util.h +0 -7
package/napi-inl.h
CHANGED
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
// Note: Do not include this file directly! Include "napi.h" instead.
|
|
11
11
|
|
|
12
12
|
#include <algorithm>
|
|
13
|
-
#include <atomic>
|
|
14
13
|
#include <cstring>
|
|
15
14
|
#include <mutex>
|
|
16
15
|
#include <type_traits>
|
|
@@ -20,8 +19,6 @@ namespace Napi {
|
|
|
20
19
|
// Helpers to handle functions exposed from C++.
|
|
21
20
|
namespace details {
|
|
22
21
|
|
|
23
|
-
extern std::atomic_bool needs_objectwrap_destructor_fix;
|
|
24
|
-
|
|
25
22
|
// Attach a data item to an object and delete it when the object gets
|
|
26
23
|
// garbage-collected.
|
|
27
24
|
// TODO: Replace this code with `napi_add_finalizer()` whenever it becomes
|
|
@@ -85,6 +82,24 @@ inline napi_value WrapCallback(Callable callback) {
|
|
|
85
82
|
#endif // NAPI_CPP_EXCEPTIONS
|
|
86
83
|
}
|
|
87
84
|
|
|
85
|
+
// For use in JS to C++ void callback wrappers to catch any Napi::Error
|
|
86
|
+
// exceptions and rethrow them as JavaScript exceptions before returning from the
|
|
87
|
+
// callback.
|
|
88
|
+
template <typename Callable>
|
|
89
|
+
inline void WrapVoidCallback(Callable callback) {
|
|
90
|
+
#ifdef NAPI_CPP_EXCEPTIONS
|
|
91
|
+
try {
|
|
92
|
+
callback();
|
|
93
|
+
} catch (const Error& e) {
|
|
94
|
+
e.ThrowAsJavaScriptException();
|
|
95
|
+
}
|
|
96
|
+
#else // NAPI_CPP_EXCEPTIONS
|
|
97
|
+
// When C++ exceptions are disabled, errors are immediately thrown as JS
|
|
98
|
+
// exceptions, so there is no need to catch and rethrow them here.
|
|
99
|
+
callback();
|
|
100
|
+
#endif // NAPI_CPP_EXCEPTIONS
|
|
101
|
+
}
|
|
102
|
+
|
|
88
103
|
template <typename Callable, typename Return>
|
|
89
104
|
struct CallbackData {
|
|
90
105
|
static inline
|
|
@@ -120,27 +135,73 @@ struct CallbackData<Callable, void> {
|
|
|
120
135
|
void* data;
|
|
121
136
|
};
|
|
122
137
|
|
|
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
|
+
|
|
123
180
|
template <typename T, typename Finalizer, typename Hint = void>
|
|
124
181
|
struct FinalizeData {
|
|
125
182
|
static inline
|
|
126
|
-
void Wrapper(napi_env env, void* data, void* finalizeHint) {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
183
|
+
void Wrapper(napi_env env, void* data, void* finalizeHint) noexcept {
|
|
184
|
+
WrapVoidCallback([&] {
|
|
185
|
+
FinalizeData* finalizeData = static_cast<FinalizeData*>(finalizeHint);
|
|
186
|
+
finalizeData->callback(Env(env), static_cast<T*>(data));
|
|
187
|
+
delete finalizeData;
|
|
188
|
+
});
|
|
130
189
|
}
|
|
131
190
|
|
|
132
191
|
static inline
|
|
133
|
-
void WrapperWithHint(napi_env env, void* data, void* finalizeHint) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
192
|
+
void WrapperWithHint(napi_env env, void* data, void* finalizeHint) noexcept {
|
|
193
|
+
WrapVoidCallback([&] {
|
|
194
|
+
FinalizeData* finalizeData = static_cast<FinalizeData*>(finalizeHint);
|
|
195
|
+
finalizeData->callback(Env(env), static_cast<T*>(data), finalizeData->hint);
|
|
196
|
+
delete finalizeData;
|
|
197
|
+
});
|
|
137
198
|
}
|
|
138
199
|
|
|
139
200
|
Finalizer callback;
|
|
140
201
|
Hint* hint;
|
|
141
202
|
};
|
|
142
203
|
|
|
143
|
-
#if (NAPI_VERSION > 3)
|
|
204
|
+
#if (NAPI_VERSION > 3 && !defined(__wasm32__))
|
|
144
205
|
template <typename ContextType=void,
|
|
145
206
|
typename Finalizer=std::function<void(Env, void*, ContextType*)>,
|
|
146
207
|
typename FinalizerDataType=void>
|
|
@@ -153,9 +214,6 @@ struct ThreadSafeFinalize {
|
|
|
153
214
|
ThreadSafeFinalize* finalizeData =
|
|
154
215
|
static_cast<ThreadSafeFinalize*>(rawFinalizeData);
|
|
155
216
|
finalizeData->callback(Env(env));
|
|
156
|
-
if (finalizeData->tsfn) {
|
|
157
|
-
*finalizeData->tsfn = nullptr;
|
|
158
|
-
}
|
|
159
217
|
delete finalizeData;
|
|
160
218
|
}
|
|
161
219
|
|
|
@@ -169,9 +227,6 @@ struct ThreadSafeFinalize {
|
|
|
169
227
|
ThreadSafeFinalize* finalizeData =
|
|
170
228
|
static_cast<ThreadSafeFinalize*>(rawFinalizeData);
|
|
171
229
|
finalizeData->callback(Env(env), finalizeData->data);
|
|
172
|
-
if (finalizeData->tsfn) {
|
|
173
|
-
*finalizeData->tsfn = nullptr;
|
|
174
|
-
}
|
|
175
230
|
delete finalizeData;
|
|
176
231
|
}
|
|
177
232
|
|
|
@@ -185,9 +240,6 @@ struct ThreadSafeFinalize {
|
|
|
185
240
|
ThreadSafeFinalize* finalizeData =
|
|
186
241
|
static_cast<ThreadSafeFinalize*>(rawFinalizeData);
|
|
187
242
|
finalizeData->callback(Env(env), static_cast<ContextType*>(rawContext));
|
|
188
|
-
if (finalizeData->tsfn) {
|
|
189
|
-
*finalizeData->tsfn = nullptr;
|
|
190
|
-
}
|
|
191
243
|
delete finalizeData;
|
|
192
244
|
}
|
|
193
245
|
|
|
@@ -202,17 +254,52 @@ struct ThreadSafeFinalize {
|
|
|
202
254
|
static_cast<ThreadSafeFinalize*>(rawFinalizeData);
|
|
203
255
|
finalizeData->callback(Env(env), finalizeData->data,
|
|
204
256
|
static_cast<ContextType*>(rawContext));
|
|
205
|
-
if (finalizeData->tsfn) {
|
|
206
|
-
*finalizeData->tsfn = nullptr;
|
|
207
|
-
}
|
|
208
257
|
delete finalizeData;
|
|
209
258
|
}
|
|
210
259
|
|
|
211
260
|
FinalizerDataType* data;
|
|
212
261
|
Finalizer callback;
|
|
213
|
-
napi_threadsafe_function* tsfn;
|
|
214
262
|
};
|
|
215
|
-
|
|
263
|
+
|
|
264
|
+
template <typename ContextType, typename DataType, typename CallJs, CallJs call>
|
|
265
|
+
typename std::enable_if<call != nullptr>::type static inline CallJsWrapper(
|
|
266
|
+
napi_env env, napi_value jsCallback, void* context, void* data) {
|
|
267
|
+
call(env,
|
|
268
|
+
Function(env, jsCallback),
|
|
269
|
+
static_cast<ContextType*>(context),
|
|
270
|
+
static_cast<DataType*>(data));
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
template <typename ContextType, typename DataType, typename CallJs, CallJs call>
|
|
274
|
+
typename std::enable_if<call == nullptr>::type static inline CallJsWrapper(
|
|
275
|
+
napi_env env, napi_value jsCallback, void* /*context*/, void* /*data*/) {
|
|
276
|
+
if (jsCallback != nullptr) {
|
|
277
|
+
Function(env, jsCallback).Call(0, nullptr);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
#if NAPI_VERSION > 4
|
|
282
|
+
|
|
283
|
+
template <typename CallbackType, typename TSFN>
|
|
284
|
+
napi_value DefaultCallbackWrapper(napi_env /*env*/, std::nullptr_t /*cb*/) {
|
|
285
|
+
return nullptr;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
template <typename CallbackType, typename TSFN>
|
|
289
|
+
napi_value DefaultCallbackWrapper(napi_env /*env*/, Napi::Function cb) {
|
|
290
|
+
return cb;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
#else
|
|
294
|
+
template <typename CallbackType, typename TSFN>
|
|
295
|
+
napi_value DefaultCallbackWrapper(napi_env env, Napi::Function cb) {
|
|
296
|
+
if (cb.IsEmpty()) {
|
|
297
|
+
return TSFN::EmptyFunctionFactory(env);
|
|
298
|
+
}
|
|
299
|
+
return cb;
|
|
300
|
+
}
|
|
301
|
+
#endif // NAPI_VERSION > 4
|
|
302
|
+
#endif // NAPI_VERSION > 3 && !defined(__wasm32__)
|
|
216
303
|
|
|
217
304
|
template <typename Getter, typename Setter>
|
|
218
305
|
struct AccessorCallbackData {
|
|
@@ -254,30 +341,34 @@ struct AccessorCallbackData {
|
|
|
254
341
|
// Module registration
|
|
255
342
|
////////////////////////////////////////////////////////////////////////////////
|
|
256
343
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
}
|
|
263
|
-
napi_value __napi_ ## regfunc(napi_env env, \
|
|
264
|
-
napi_value exports) { \
|
|
265
|
-
return Napi::RegisterModule(env, exports, regfunc); \
|
|
266
|
-
} \
|
|
344
|
+
// Register an add-on based on an initializer function.
|
|
345
|
+
#define NODE_API_MODULE(modname, regfunc) \
|
|
346
|
+
napi_value __napi_ ## regfunc(napi_env env, \
|
|
347
|
+
napi_value exports) { \
|
|
348
|
+
return Napi::RegisterModule(env, exports, regfunc); \
|
|
349
|
+
} \
|
|
267
350
|
NAPI_MODULE(modname, __napi_ ## regfunc)
|
|
268
351
|
|
|
352
|
+
// Register an add-on based on a subclass of `Addon<T>` with a custom Node.js
|
|
353
|
+
// module name.
|
|
354
|
+
#define NODE_API_NAMED_ADDON(modname, classname) \
|
|
355
|
+
static napi_value __napi_ ## classname(napi_env env, \
|
|
356
|
+
napi_value exports) { \
|
|
357
|
+
return Napi::RegisterModule(env, exports, &classname::Init); \
|
|
358
|
+
} \
|
|
359
|
+
NAPI_MODULE(modname, __napi_ ## classname)
|
|
360
|
+
|
|
361
|
+
// Register an add-on based on a subclass of `Addon<T>` with the Node.js module
|
|
362
|
+
// name given by node-gyp from the `target_name` in binding.gyp.
|
|
363
|
+
#define NODE_API_ADDON(classname) \
|
|
364
|
+
NODE_API_NAMED_ADDON(NODE_GYP_MODULE_NAME, classname)
|
|
365
|
+
|
|
269
366
|
// Adapt the NAPI_MODULE registration function:
|
|
270
367
|
// - Wrap the arguments in NAPI wrappers.
|
|
271
368
|
// - Catch any NAPI errors and rethrow as JS exceptions.
|
|
272
369
|
inline napi_value RegisterModule(napi_env env,
|
|
273
370
|
napi_value exports,
|
|
274
371
|
ModuleRegisterCallback registerCallback) {
|
|
275
|
-
const napi_node_version* nver = Napi::VersionManagement::GetNodeVersion(env);
|
|
276
|
-
Napi::details::needs_objectwrap_destructor_fix =
|
|
277
|
-
(nver->major < 10 ||
|
|
278
|
-
(nver->major == 10 && nver->minor < 15) ||
|
|
279
|
-
(nver->major == 10 && nver->minor == 15 && nver->patch < 3));
|
|
280
|
-
|
|
281
372
|
return details::WrapCallback([&] {
|
|
282
373
|
return napi_value(registerCallback(Napi::Env(env),
|
|
283
374
|
Napi::Object(env, exports)));
|
|
@@ -333,6 +424,64 @@ inline Error Env::GetAndClearPendingException() {
|
|
|
333
424
|
return Error(_env, value);
|
|
334
425
|
}
|
|
335
426
|
|
|
427
|
+
inline Value Env::RunScript(const char* utf8script) {
|
|
428
|
+
String script = String::New(_env, utf8script);
|
|
429
|
+
return RunScript(script);
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
inline Value Env::RunScript(const std::string& utf8script) {
|
|
433
|
+
return RunScript(utf8script.c_str());
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
inline Value Env::RunScript(String script) {
|
|
437
|
+
napi_value result;
|
|
438
|
+
napi_status status = napi_run_script(_env, script, &result);
|
|
439
|
+
NAPI_THROW_IF_FAILED(_env, status, Undefined());
|
|
440
|
+
return Value(_env, result);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
#if NAPI_VERSION > 5
|
|
444
|
+
template <typename T, Env::Finalizer<T> fini>
|
|
445
|
+
inline void Env::SetInstanceData(T* data) {
|
|
446
|
+
napi_status status =
|
|
447
|
+
napi_set_instance_data(_env, data, [](napi_env env, void* data, void*) {
|
|
448
|
+
fini(env, static_cast<T*>(data));
|
|
449
|
+
}, nullptr);
|
|
450
|
+
NAPI_THROW_IF_FAILED_VOID(_env, status);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
template <typename DataType,
|
|
454
|
+
typename HintType,
|
|
455
|
+
Napi::Env::FinalizerWithHint<DataType, HintType> fini>
|
|
456
|
+
inline void Env::SetInstanceData(DataType* data, HintType* hint) {
|
|
457
|
+
napi_status status =
|
|
458
|
+
napi_set_instance_data(_env, data,
|
|
459
|
+
[](napi_env env, void* data, void* hint) {
|
|
460
|
+
fini(env, static_cast<DataType*>(data), static_cast<HintType*>(hint));
|
|
461
|
+
}, hint);
|
|
462
|
+
NAPI_THROW_IF_FAILED_VOID(_env, status);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
template <typename T>
|
|
466
|
+
inline T* Env::GetInstanceData() {
|
|
467
|
+
void* data = nullptr;
|
|
468
|
+
|
|
469
|
+
napi_status status = napi_get_instance_data(_env, &data);
|
|
470
|
+
NAPI_THROW_IF_FAILED(_env, status, nullptr);
|
|
471
|
+
|
|
472
|
+
return static_cast<T*>(data);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
template <typename T> void Env::DefaultFini(Env, T* data) {
|
|
476
|
+
delete data;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
template <typename DataType, typename HintType>
|
|
480
|
+
void Env::DefaultFiniWithHint(Env, DataType* data, HintType*) {
|
|
481
|
+
delete data;
|
|
482
|
+
}
|
|
483
|
+
#endif // NAPI_VERSION > 5
|
|
484
|
+
|
|
336
485
|
////////////////////////////////////////////////////////////////////////////////
|
|
337
486
|
// Value class
|
|
338
487
|
////////////////////////////////////////////////////////////////////////////////
|
|
@@ -397,14 +546,11 @@ inline bool Value::IsNumber() const {
|
|
|
397
546
|
return Type() == napi_number;
|
|
398
547
|
}
|
|
399
548
|
|
|
400
|
-
|
|
401
|
-
// Once it is no longer experimental guard with the NAPI_VERSION in which it is
|
|
402
|
-
// released instead.
|
|
403
|
-
#ifdef NAPI_EXPERIMENTAL
|
|
549
|
+
#if NAPI_VERSION > 5
|
|
404
550
|
inline bool Value::IsBigInt() const {
|
|
405
551
|
return Type() == napi_bigint;
|
|
406
552
|
}
|
|
407
|
-
#endif //
|
|
553
|
+
#endif // NAPI_VERSION > 5
|
|
408
554
|
|
|
409
555
|
#if (NAPI_VERSION > 4)
|
|
410
556
|
inline bool Value::IsDate() const {
|
|
@@ -635,10 +781,7 @@ inline double Number::DoubleValue() const {
|
|
|
635
781
|
return result;
|
|
636
782
|
}
|
|
637
783
|
|
|
638
|
-
|
|
639
|
-
// Once it is no longer experimental guard with the NAPI_VERSION in which it is
|
|
640
|
-
// released instead.
|
|
641
|
-
#ifdef NAPI_EXPERIMENTAL
|
|
784
|
+
#if NAPI_VERSION > 5
|
|
642
785
|
////////////////////////////////////////////////////////////////////////////////
|
|
643
786
|
// BigInt Class
|
|
644
787
|
////////////////////////////////////////////////////////////////////////////////
|
|
@@ -699,7 +842,7 @@ inline void BigInt::ToWords(int* sign_bit, size_t* word_count, uint64_t* words)
|
|
|
699
842
|
_env, _value, sign_bit, word_count, words);
|
|
700
843
|
NAPI_THROW_IF_FAILED_VOID(_env, status);
|
|
701
844
|
}
|
|
702
|
-
#endif //
|
|
845
|
+
#endif // NAPI_VERSION > 5
|
|
703
846
|
|
|
704
847
|
#if (NAPI_VERSION > 4)
|
|
705
848
|
////////////////////////////////////////////////////////////////////////////////
|
|
@@ -1344,7 +1487,7 @@ inline ArrayBuffer ArrayBuffer::New(napi_env env, size_t byteLength) {
|
|
|
1344
1487
|
napi_status status = napi_create_arraybuffer(env, byteLength, &data, &value);
|
|
1345
1488
|
NAPI_THROW_IF_FAILED(env, status, ArrayBuffer());
|
|
1346
1489
|
|
|
1347
|
-
return ArrayBuffer(env, value
|
|
1490
|
+
return ArrayBuffer(env, value);
|
|
1348
1491
|
}
|
|
1349
1492
|
|
|
1350
1493
|
inline ArrayBuffer ArrayBuffer::New(napi_env env,
|
|
@@ -1355,7 +1498,7 @@ inline ArrayBuffer ArrayBuffer::New(napi_env env,
|
|
|
1355
1498
|
env, externalData, byteLength, nullptr, nullptr, &value);
|
|
1356
1499
|
NAPI_THROW_IF_FAILED(env, status, ArrayBuffer());
|
|
1357
1500
|
|
|
1358
|
-
return ArrayBuffer(env, value
|
|
1501
|
+
return ArrayBuffer(env, value);
|
|
1359
1502
|
}
|
|
1360
1503
|
|
|
1361
1504
|
template <typename Finalizer>
|
|
@@ -1378,7 +1521,7 @@ inline ArrayBuffer ArrayBuffer::New(napi_env env,
|
|
|
1378
1521
|
NAPI_THROW_IF_FAILED(env, status, ArrayBuffer());
|
|
1379
1522
|
}
|
|
1380
1523
|
|
|
1381
|
-
return ArrayBuffer(env, value
|
|
1524
|
+
return ArrayBuffer(env, value);
|
|
1382
1525
|
}
|
|
1383
1526
|
|
|
1384
1527
|
template <typename Finalizer, typename Hint>
|
|
@@ -1402,39 +1545,43 @@ inline ArrayBuffer ArrayBuffer::New(napi_env env,
|
|
|
1402
1545
|
NAPI_THROW_IF_FAILED(env, status, ArrayBuffer());
|
|
1403
1546
|
}
|
|
1404
1547
|
|
|
1405
|
-
return ArrayBuffer(env, value
|
|
1548
|
+
return ArrayBuffer(env, value);
|
|
1406
1549
|
}
|
|
1407
1550
|
|
|
1408
|
-
inline ArrayBuffer::ArrayBuffer() : Object()
|
|
1551
|
+
inline ArrayBuffer::ArrayBuffer() : Object() {
|
|
1409
1552
|
}
|
|
1410
1553
|
|
|
1411
1554
|
inline ArrayBuffer::ArrayBuffer(napi_env env, napi_value value)
|
|
1412
|
-
: Object(env, value)
|
|
1413
|
-
}
|
|
1414
|
-
|
|
1415
|
-
inline ArrayBuffer::ArrayBuffer(napi_env env, napi_value value, void* data, size_t length)
|
|
1416
|
-
: Object(env, value), _data(data), _length(length) {
|
|
1555
|
+
: Object(env, value) {
|
|
1417
1556
|
}
|
|
1418
1557
|
|
|
1419
1558
|
inline void* ArrayBuffer::Data() {
|
|
1420
|
-
|
|
1421
|
-
|
|
1559
|
+
void* data;
|
|
1560
|
+
napi_status status = napi_get_arraybuffer_info(_env, _value, &data, nullptr);
|
|
1561
|
+
NAPI_THROW_IF_FAILED(_env, status, nullptr);
|
|
1562
|
+
return data;
|
|
1422
1563
|
}
|
|
1423
1564
|
|
|
1424
1565
|
inline size_t ArrayBuffer::ByteLength() {
|
|
1425
|
-
|
|
1426
|
-
|
|
1566
|
+
size_t length;
|
|
1567
|
+
napi_status status = napi_get_arraybuffer_info(_env, _value, nullptr, &length);
|
|
1568
|
+
NAPI_THROW_IF_FAILED(_env, status, 0);
|
|
1569
|
+
return length;
|
|
1427
1570
|
}
|
|
1428
1571
|
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1572
|
+
#if NAPI_VERSION >= 7
|
|
1573
|
+
inline bool ArrayBuffer::IsDetached() const {
|
|
1574
|
+
bool detached;
|
|
1575
|
+
napi_status status = napi_is_detached_arraybuffer(_env, _value, &detached);
|
|
1576
|
+
NAPI_THROW_IF_FAILED(_env, status, false);
|
|
1577
|
+
return detached;
|
|
1578
|
+
}
|
|
1579
|
+
|
|
1580
|
+
inline void ArrayBuffer::Detach() {
|
|
1581
|
+
napi_status status = napi_detach_arraybuffer(_env, _value);
|
|
1582
|
+
NAPI_THROW_IF_FAILED_VOID(_env, status);
|
|
1437
1583
|
}
|
|
1584
|
+
#endif // NAPI_VERSION >= 7
|
|
1438
1585
|
|
|
1439
1586
|
////////////////////////////////////////////////////////////////////////////////
|
|
1440
1587
|
// DataView class
|
|
@@ -1649,6 +1796,10 @@ inline uint8_t TypedArray::ElementSize() const {
|
|
|
1649
1796
|
case napi_float32_array:
|
|
1650
1797
|
return 4;
|
|
1651
1798
|
case napi_float64_array:
|
|
1799
|
+
#if (NAPI_VERSION > 5)
|
|
1800
|
+
case napi_bigint64_array:
|
|
1801
|
+
case napi_biguint64_array:
|
|
1802
|
+
#endif // (NAPI_VERSION > 5)
|
|
1652
1803
|
return 8;
|
|
1653
1804
|
default:
|
|
1654
1805
|
return 0;
|
|
@@ -1721,8 +1872,14 @@ inline TypedArrayOf<T>::TypedArrayOf() : TypedArray(), _data(nullptr) {
|
|
|
1721
1872
|
template <typename T>
|
|
1722
1873
|
inline TypedArrayOf<T>::TypedArrayOf(napi_env env, napi_value value)
|
|
1723
1874
|
: TypedArray(env, value), _data(nullptr) {
|
|
1724
|
-
napi_status status =
|
|
1725
|
-
|
|
1875
|
+
napi_status status = napi_ok;
|
|
1876
|
+
if (value != nullptr) {
|
|
1877
|
+
status = napi_get_typedarray_info(
|
|
1878
|
+
_env, _value, &_type, &_length, reinterpret_cast<void**>(&_data), nullptr, nullptr);
|
|
1879
|
+
} else {
|
|
1880
|
+
_type = TypedArrayTypeForPrimitiveType<T>();
|
|
1881
|
+
_length = 0;
|
|
1882
|
+
}
|
|
1726
1883
|
NAPI_THROW_IF_FAILED_VOID(_env, status);
|
|
1727
1884
|
}
|
|
1728
1885
|
|
|
@@ -1780,6 +1937,46 @@ CreateFunction(napi_env env,
|
|
|
1780
1937
|
return status;
|
|
1781
1938
|
}
|
|
1782
1939
|
|
|
1940
|
+
template <Function::VoidCallback cb>
|
|
1941
|
+
inline Function Function::New(napi_env env, const char* utf8name, void* data) {
|
|
1942
|
+
napi_value result = nullptr;
|
|
1943
|
+
napi_status status = napi_create_function(env,
|
|
1944
|
+
utf8name,
|
|
1945
|
+
NAPI_AUTO_LENGTH,
|
|
1946
|
+
details::TemplatedVoidCallback<cb>,
|
|
1947
|
+
data,
|
|
1948
|
+
&result);
|
|
1949
|
+
NAPI_THROW_IF_FAILED(env, status, Function());
|
|
1950
|
+
return Function(env, result);
|
|
1951
|
+
}
|
|
1952
|
+
|
|
1953
|
+
template <Function::Callback cb>
|
|
1954
|
+
inline Function Function::New(napi_env env, const char* utf8name, void* data) {
|
|
1955
|
+
napi_value result = nullptr;
|
|
1956
|
+
napi_status status = napi_create_function(env,
|
|
1957
|
+
utf8name,
|
|
1958
|
+
NAPI_AUTO_LENGTH,
|
|
1959
|
+
details::TemplatedCallback<cb>,
|
|
1960
|
+
data,
|
|
1961
|
+
&result);
|
|
1962
|
+
NAPI_THROW_IF_FAILED(env, status, Function());
|
|
1963
|
+
return Function(env, result);
|
|
1964
|
+
}
|
|
1965
|
+
|
|
1966
|
+
template <Function::VoidCallback cb>
|
|
1967
|
+
inline Function Function::New(napi_env env,
|
|
1968
|
+
const std::string& utf8name,
|
|
1969
|
+
void* data) {
|
|
1970
|
+
return Function::New<cb>(env, utf8name.c_str(), data);
|
|
1971
|
+
}
|
|
1972
|
+
|
|
1973
|
+
template <Function::Callback cb>
|
|
1974
|
+
inline Function Function::New(napi_env env,
|
|
1975
|
+
const std::string& utf8name,
|
|
1976
|
+
void* data) {
|
|
1977
|
+
return Function::New<cb>(env, utf8name.c_str(), data);
|
|
1978
|
+
}
|
|
1979
|
+
|
|
1783
1980
|
template <typename Callable>
|
|
1784
1981
|
inline Function Function::New(napi_env env,
|
|
1785
1982
|
Callable cb,
|
|
@@ -2051,12 +2248,19 @@ inline void Buffer<T>::EnsureInfo() const {
|
|
|
2051
2248
|
inline Error Error::New(napi_env env) {
|
|
2052
2249
|
napi_status status;
|
|
2053
2250
|
napi_value error = nullptr;
|
|
2054
|
-
|
|
2251
|
+
bool is_exception_pending;
|
|
2055
2252
|
const napi_extended_error_info* info;
|
|
2253
|
+
|
|
2254
|
+
// We must retrieve the last error info before doing anything else, because
|
|
2255
|
+
// doing anything else will replace the last error info.
|
|
2056
2256
|
status = napi_get_last_error_info(env, &info);
|
|
2057
2257
|
NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_get_last_error_info");
|
|
2058
2258
|
|
|
2059
|
-
|
|
2259
|
+
status = napi_is_exception_pending(env, &is_exception_pending);
|
|
2260
|
+
NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_is_exception_pending");
|
|
2261
|
+
|
|
2262
|
+
// A pending exception takes precedence over any internal error status.
|
|
2263
|
+
if (is_exception_pending) {
|
|
2060
2264
|
status = napi_get_and_clear_last_exception(env, &error);
|
|
2061
2265
|
NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_get_and_clear_last_exception");
|
|
2062
2266
|
}
|
|
@@ -2064,15 +2268,6 @@ inline Error Error::New(napi_env env) {
|
|
|
2064
2268
|
const char* error_message = info->error_message != nullptr ?
|
|
2065
2269
|
info->error_message : "Error in native callback";
|
|
2066
2270
|
|
|
2067
|
-
bool isExceptionPending;
|
|
2068
|
-
status = napi_is_exception_pending(env, &isExceptionPending);
|
|
2069
|
-
NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_is_exception_pending");
|
|
2070
|
-
|
|
2071
|
-
if (isExceptionPending) {
|
|
2072
|
-
status = napi_get_and_clear_last_exception(env, &error);
|
|
2073
|
-
NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_get_and_clear_last_exception");
|
|
2074
|
-
}
|
|
2075
|
-
|
|
2076
2271
|
napi_value message;
|
|
2077
2272
|
status = napi_create_string_utf8(
|
|
2078
2273
|
env,
|
|
@@ -2134,7 +2329,7 @@ inline Error& Error::operator =(Error&& other) {
|
|
|
2134
2329
|
inline Error::Error(const Error& other) : ObjectReference(other) {
|
|
2135
2330
|
}
|
|
2136
2331
|
|
|
2137
|
-
inline Error& Error::operator =(Error& other) {
|
|
2332
|
+
inline Error& Error::operator =(const Error& other) {
|
|
2138
2333
|
Reset();
|
|
2139
2334
|
|
|
2140
2335
|
_env = other.Env();
|
|
@@ -2746,6 +2941,91 @@ inline void CallbackInfo::SetData(void* data) {
|
|
|
2746
2941
|
// PropertyDescriptor class
|
|
2747
2942
|
////////////////////////////////////////////////////////////////////////////////
|
|
2748
2943
|
|
|
2944
|
+
template <typename PropertyDescriptor::GetterCallback Getter>
|
|
2945
|
+
PropertyDescriptor
|
|
2946
|
+
PropertyDescriptor::Accessor(const char* utf8name,
|
|
2947
|
+
napi_property_attributes attributes,
|
|
2948
|
+
void* data) {
|
|
2949
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
2950
|
+
|
|
2951
|
+
desc.utf8name = utf8name;
|
|
2952
|
+
desc.getter = details::TemplatedCallback<Getter>;
|
|
2953
|
+
desc.attributes = attributes;
|
|
2954
|
+
desc.data = data;
|
|
2955
|
+
|
|
2956
|
+
return desc;
|
|
2957
|
+
}
|
|
2958
|
+
|
|
2959
|
+
template <typename PropertyDescriptor::GetterCallback Getter>
|
|
2960
|
+
PropertyDescriptor
|
|
2961
|
+
PropertyDescriptor::Accessor(const std::string& utf8name,
|
|
2962
|
+
napi_property_attributes attributes,
|
|
2963
|
+
void* data) {
|
|
2964
|
+
return Accessor<Getter>(utf8name.c_str(), attributes, data);
|
|
2965
|
+
}
|
|
2966
|
+
|
|
2967
|
+
template <typename PropertyDescriptor::GetterCallback Getter>
|
|
2968
|
+
PropertyDescriptor
|
|
2969
|
+
PropertyDescriptor::Accessor(Name name,
|
|
2970
|
+
napi_property_attributes attributes,
|
|
2971
|
+
void* data) {
|
|
2972
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
2973
|
+
|
|
2974
|
+
desc.name = name;
|
|
2975
|
+
desc.getter = details::TemplatedCallback<Getter>;
|
|
2976
|
+
desc.attributes = attributes;
|
|
2977
|
+
desc.data = data;
|
|
2978
|
+
|
|
2979
|
+
return desc;
|
|
2980
|
+
}
|
|
2981
|
+
|
|
2982
|
+
template <
|
|
2983
|
+
typename PropertyDescriptor::GetterCallback Getter,
|
|
2984
|
+
typename PropertyDescriptor::SetterCallback Setter>
|
|
2985
|
+
PropertyDescriptor
|
|
2986
|
+
PropertyDescriptor::Accessor(const char* utf8name,
|
|
2987
|
+
napi_property_attributes attributes,
|
|
2988
|
+
void* data) {
|
|
2989
|
+
|
|
2990
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
2991
|
+
|
|
2992
|
+
desc.utf8name = utf8name;
|
|
2993
|
+
desc.getter = details::TemplatedCallback<Getter>;
|
|
2994
|
+
desc.setter = details::TemplatedVoidCallback<Setter>;
|
|
2995
|
+
desc.attributes = attributes;
|
|
2996
|
+
desc.data = data;
|
|
2997
|
+
|
|
2998
|
+
return desc;
|
|
2999
|
+
}
|
|
3000
|
+
|
|
3001
|
+
template <
|
|
3002
|
+
typename PropertyDescriptor::GetterCallback Getter,
|
|
3003
|
+
typename PropertyDescriptor::SetterCallback Setter>
|
|
3004
|
+
PropertyDescriptor
|
|
3005
|
+
PropertyDescriptor::Accessor(const std::string& utf8name,
|
|
3006
|
+
napi_property_attributes attributes,
|
|
3007
|
+
void* data) {
|
|
3008
|
+
return Accessor<Getter, Setter>(utf8name.c_str(), attributes, data);
|
|
3009
|
+
}
|
|
3010
|
+
|
|
3011
|
+
template <
|
|
3012
|
+
typename PropertyDescriptor::GetterCallback Getter,
|
|
3013
|
+
typename PropertyDescriptor::SetterCallback Setter>
|
|
3014
|
+
PropertyDescriptor
|
|
3015
|
+
PropertyDescriptor::Accessor(Name name,
|
|
3016
|
+
napi_property_attributes attributes,
|
|
3017
|
+
void* data) {
|
|
3018
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
3019
|
+
|
|
3020
|
+
desc.name = name;
|
|
3021
|
+
desc.getter = details::TemplatedCallback<Getter>;
|
|
3022
|
+
desc.setter = details::TemplatedVoidCallback<Setter>;
|
|
3023
|
+
desc.attributes = attributes;
|
|
3024
|
+
desc.data = data;
|
|
3025
|
+
|
|
3026
|
+
return desc;
|
|
3027
|
+
}
|
|
3028
|
+
|
|
2749
3029
|
template <typename Getter>
|
|
2750
3030
|
inline PropertyDescriptor
|
|
2751
3031
|
PropertyDescriptor::Accessor(Napi::Env env,
|
|
@@ -2973,90 +3253,400 @@ inline PropertyDescriptor::operator const napi_property_descriptor&() const {
|
|
|
2973
3253
|
}
|
|
2974
3254
|
|
|
2975
3255
|
////////////////////////////////////////////////////////////////////////////////
|
|
2976
|
-
//
|
|
3256
|
+
// InstanceWrap<T> class
|
|
2977
3257
|
////////////////////////////////////////////////////////////////////////////////
|
|
2978
3258
|
|
|
2979
3259
|
template <typename T>
|
|
2980
|
-
inline
|
|
2981
|
-
|
|
2982
|
-
|
|
3260
|
+
inline void InstanceWrap<T>::AttachPropData(napi_env env,
|
|
3261
|
+
napi_value value,
|
|
3262
|
+
const napi_property_descriptor* prop) {
|
|
2983
3263
|
napi_status status;
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
3264
|
+
if (prop->method != nullptr && !(prop->attributes & napi_static)) {
|
|
3265
|
+
if (prop->method == T::InstanceVoidMethodCallbackWrapper) {
|
|
3266
|
+
status = Napi::details::AttachData(env,
|
|
3267
|
+
value,
|
|
3268
|
+
static_cast<InstanceVoidMethodCallbackData*>(prop->data));
|
|
3269
|
+
NAPI_THROW_IF_FAILED_VOID(env, status);
|
|
3270
|
+
} else if (prop->method == T::InstanceMethodCallbackWrapper) {
|
|
3271
|
+
status = Napi::details::AttachData(env,
|
|
3272
|
+
value,
|
|
3273
|
+
static_cast<InstanceMethodCallbackData*>(prop->data));
|
|
3274
|
+
NAPI_THROW_IF_FAILED_VOID(env, status);
|
|
3275
|
+
} else if (prop->getter == T::InstanceGetterCallbackWrapper ||
|
|
3276
|
+
prop->setter == T::InstanceSetterCallbackWrapper) {
|
|
3277
|
+
status = Napi::details::AttachData(env,
|
|
3278
|
+
value,
|
|
3279
|
+
static_cast<InstanceAccessorCallbackData*>(prop->data));
|
|
3280
|
+
NAPI_THROW_IF_FAILED_VOID(env, status);
|
|
3281
|
+
}
|
|
3282
|
+
}
|
|
2990
3283
|
}
|
|
2991
3284
|
|
|
2992
3285
|
template <typename T>
|
|
2993
|
-
inline
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
if (!object.IsEmpty() && _construction_failed) {
|
|
3001
|
-
napi_remove_wrap(Env(), object, nullptr);
|
|
3286
|
+
inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceMethod(
|
|
3287
|
+
const char* utf8name,
|
|
3288
|
+
InstanceVoidMethodCallback method,
|
|
3289
|
+
napi_property_attributes attributes,
|
|
3290
|
+
void* data) {
|
|
3291
|
+
InstanceVoidMethodCallbackData* callbackData =
|
|
3292
|
+
new InstanceVoidMethodCallbackData({ method, data});
|
|
3002
3293
|
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
_ref = nullptr;
|
|
3010
|
-
_env = nullptr;
|
|
3011
|
-
}
|
|
3012
|
-
}
|
|
3013
|
-
}
|
|
3294
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
3295
|
+
desc.utf8name = utf8name;
|
|
3296
|
+
desc.method = T::InstanceVoidMethodCallbackWrapper;
|
|
3297
|
+
desc.data = callbackData;
|
|
3298
|
+
desc.attributes = attributes;
|
|
3299
|
+
return desc;
|
|
3014
3300
|
}
|
|
3015
3301
|
|
|
3016
|
-
template<typename T>
|
|
3017
|
-
inline T
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3302
|
+
template <typename T>
|
|
3303
|
+
inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceMethod(
|
|
3304
|
+
const char* utf8name,
|
|
3305
|
+
InstanceMethodCallback method,
|
|
3306
|
+
napi_property_attributes attributes,
|
|
3307
|
+
void* data) {
|
|
3308
|
+
InstanceMethodCallbackData* callbackData = new InstanceMethodCallbackData({ method, data });
|
|
3309
|
+
|
|
3310
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
3311
|
+
desc.utf8name = utf8name;
|
|
3312
|
+
desc.method = T::InstanceMethodCallbackWrapper;
|
|
3313
|
+
desc.data = callbackData;
|
|
3314
|
+
desc.attributes = attributes;
|
|
3315
|
+
return desc;
|
|
3022
3316
|
}
|
|
3023
3317
|
|
|
3024
3318
|
template <typename T>
|
|
3025
|
-
inline
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
std::vector<napi_property_descriptor> props(props_count);
|
|
3319
|
+
inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceMethod(
|
|
3320
|
+
Symbol name,
|
|
3321
|
+
InstanceVoidMethodCallback method,
|
|
3322
|
+
napi_property_attributes attributes,
|
|
3323
|
+
void* data) {
|
|
3324
|
+
InstanceVoidMethodCallbackData* callbackData =
|
|
3325
|
+
new InstanceVoidMethodCallbackData({ method, data});
|
|
3033
3326
|
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3327
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
3328
|
+
desc.name = name;
|
|
3329
|
+
desc.method = T::InstanceVoidMethodCallbackWrapper;
|
|
3330
|
+
desc.data = callbackData;
|
|
3331
|
+
desc.attributes = attributes;
|
|
3332
|
+
return desc;
|
|
3333
|
+
}
|
|
3334
|
+
|
|
3335
|
+
template <typename T>
|
|
3336
|
+
inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceMethod(
|
|
3337
|
+
Symbol name,
|
|
3338
|
+
InstanceMethodCallback method,
|
|
3339
|
+
napi_property_attributes attributes,
|
|
3340
|
+
void* data) {
|
|
3341
|
+
InstanceMethodCallbackData* callbackData = new InstanceMethodCallbackData({ method, data });
|
|
3342
|
+
|
|
3343
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
3344
|
+
desc.name = name;
|
|
3345
|
+
desc.method = T::InstanceMethodCallbackWrapper;
|
|
3346
|
+
desc.data = callbackData;
|
|
3347
|
+
desc.attributes = attributes;
|
|
3348
|
+
return desc;
|
|
3349
|
+
}
|
|
3350
|
+
|
|
3351
|
+
template <typename T>
|
|
3352
|
+
template <typename InstanceWrap<T>::InstanceVoidMethodCallback method>
|
|
3353
|
+
inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceMethod(
|
|
3354
|
+
const char* utf8name,
|
|
3355
|
+
napi_property_attributes attributes,
|
|
3356
|
+
void* data) {
|
|
3357
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
3358
|
+
desc.utf8name = utf8name;
|
|
3359
|
+
desc.method = details::TemplatedInstanceVoidCallback<T, method>;
|
|
3360
|
+
desc.data = data;
|
|
3361
|
+
desc.attributes = attributes;
|
|
3362
|
+
return desc;
|
|
3363
|
+
}
|
|
3364
|
+
|
|
3365
|
+
template <typename T>
|
|
3366
|
+
template <typename InstanceWrap<T>::InstanceMethodCallback method>
|
|
3367
|
+
inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceMethod(
|
|
3368
|
+
const char* utf8name,
|
|
3369
|
+
napi_property_attributes attributes,
|
|
3370
|
+
void* data) {
|
|
3371
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
3372
|
+
desc.utf8name = utf8name;
|
|
3373
|
+
desc.method = details::TemplatedInstanceCallback<T, method>;
|
|
3374
|
+
desc.data = data;
|
|
3375
|
+
desc.attributes = attributes;
|
|
3376
|
+
return desc;
|
|
3377
|
+
}
|
|
3378
|
+
|
|
3379
|
+
template <typename T>
|
|
3380
|
+
template <typename InstanceWrap<T>::InstanceVoidMethodCallback method>
|
|
3381
|
+
inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceMethod(
|
|
3382
|
+
Symbol name,
|
|
3383
|
+
napi_property_attributes attributes,
|
|
3384
|
+
void* data) {
|
|
3385
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
3386
|
+
desc.name = name;
|
|
3387
|
+
desc.method = details::TemplatedInstanceVoidCallback<T, method>;
|
|
3388
|
+
desc.data = data;
|
|
3389
|
+
desc.attributes = attributes;
|
|
3390
|
+
return desc;
|
|
3391
|
+
}
|
|
3392
|
+
|
|
3393
|
+
template <typename T>
|
|
3394
|
+
template <typename InstanceWrap<T>::InstanceMethodCallback method>
|
|
3395
|
+
inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceMethod(
|
|
3396
|
+
Symbol name,
|
|
3397
|
+
napi_property_attributes attributes,
|
|
3398
|
+
void* data) {
|
|
3399
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
3400
|
+
desc.name = name;
|
|
3401
|
+
desc.method = details::TemplatedInstanceCallback<T, method>;
|
|
3402
|
+
desc.data = data;
|
|
3403
|
+
desc.attributes = attributes;
|
|
3404
|
+
return desc;
|
|
3405
|
+
}
|
|
3406
|
+
|
|
3407
|
+
template <typename T>
|
|
3408
|
+
inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceAccessor(
|
|
3409
|
+
const char* utf8name,
|
|
3410
|
+
InstanceGetterCallback getter,
|
|
3411
|
+
InstanceSetterCallback setter,
|
|
3412
|
+
napi_property_attributes attributes,
|
|
3413
|
+
void* data) {
|
|
3414
|
+
InstanceAccessorCallbackData* callbackData =
|
|
3415
|
+
new InstanceAccessorCallbackData({ getter, setter, data });
|
|
3416
|
+
|
|
3417
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
3418
|
+
desc.utf8name = utf8name;
|
|
3419
|
+
desc.getter = getter != nullptr ? T::InstanceGetterCallbackWrapper : nullptr;
|
|
3420
|
+
desc.setter = setter != nullptr ? T::InstanceSetterCallbackWrapper : nullptr;
|
|
3421
|
+
desc.data = callbackData;
|
|
3422
|
+
desc.attributes = attributes;
|
|
3423
|
+
return desc;
|
|
3424
|
+
}
|
|
3425
|
+
|
|
3426
|
+
template <typename T>
|
|
3427
|
+
inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceAccessor(
|
|
3428
|
+
Symbol name,
|
|
3429
|
+
InstanceGetterCallback getter,
|
|
3430
|
+
InstanceSetterCallback setter,
|
|
3431
|
+
napi_property_attributes attributes,
|
|
3432
|
+
void* data) {
|
|
3433
|
+
InstanceAccessorCallbackData* callbackData =
|
|
3434
|
+
new InstanceAccessorCallbackData({ getter, setter, data });
|
|
3435
|
+
|
|
3436
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
3437
|
+
desc.name = name;
|
|
3438
|
+
desc.getter = getter != nullptr ? T::InstanceGetterCallbackWrapper : nullptr;
|
|
3439
|
+
desc.setter = setter != nullptr ? T::InstanceSetterCallbackWrapper : nullptr;
|
|
3440
|
+
desc.data = callbackData;
|
|
3441
|
+
desc.attributes = attributes;
|
|
3442
|
+
return desc;
|
|
3443
|
+
}
|
|
3444
|
+
|
|
3445
|
+
template <typename T>
|
|
3446
|
+
template <typename InstanceWrap<T>::InstanceGetterCallback getter,
|
|
3447
|
+
typename InstanceWrap<T>::InstanceSetterCallback setter>
|
|
3448
|
+
inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceAccessor(
|
|
3449
|
+
const char* utf8name,
|
|
3450
|
+
napi_property_attributes attributes,
|
|
3451
|
+
void* data) {
|
|
3452
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
3453
|
+
desc.utf8name = utf8name;
|
|
3454
|
+
desc.getter = details::TemplatedInstanceCallback<T, getter>;
|
|
3455
|
+
desc.setter = This::WrapSetter(This::SetterTag<setter>());
|
|
3456
|
+
desc.data = data;
|
|
3457
|
+
desc.attributes = attributes;
|
|
3458
|
+
return desc;
|
|
3459
|
+
}
|
|
3460
|
+
|
|
3461
|
+
template <typename T>
|
|
3462
|
+
template <typename InstanceWrap<T>::InstanceGetterCallback getter,
|
|
3463
|
+
typename InstanceWrap<T>::InstanceSetterCallback setter>
|
|
3464
|
+
inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceAccessor(
|
|
3465
|
+
Symbol name,
|
|
3466
|
+
napi_property_attributes attributes,
|
|
3467
|
+
void* data) {
|
|
3468
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
3469
|
+
desc.name = name;
|
|
3470
|
+
desc.getter = details::TemplatedInstanceCallback<T, getter>;
|
|
3471
|
+
desc.setter = This::WrapSetter(This::SetterTag<setter>());
|
|
3472
|
+
desc.data = data;
|
|
3473
|
+
desc.attributes = attributes;
|
|
3474
|
+
return desc;
|
|
3475
|
+
}
|
|
3476
|
+
|
|
3477
|
+
template <typename T>
|
|
3478
|
+
inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceValue(
|
|
3479
|
+
const char* utf8name,
|
|
3480
|
+
Napi::Value value,
|
|
3481
|
+
napi_property_attributes attributes) {
|
|
3482
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
3483
|
+
desc.utf8name = utf8name;
|
|
3484
|
+
desc.value = value;
|
|
3485
|
+
desc.attributes = attributes;
|
|
3486
|
+
return desc;
|
|
3487
|
+
}
|
|
3488
|
+
|
|
3489
|
+
template <typename T>
|
|
3490
|
+
inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceValue(
|
|
3491
|
+
Symbol name,
|
|
3492
|
+
Napi::Value value,
|
|
3493
|
+
napi_property_attributes attributes) {
|
|
3494
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
3495
|
+
desc.name = name;
|
|
3496
|
+
desc.value = value;
|
|
3497
|
+
desc.attributes = attributes;
|
|
3498
|
+
return desc;
|
|
3499
|
+
}
|
|
3500
|
+
|
|
3501
|
+
template <typename T>
|
|
3502
|
+
inline napi_value InstanceWrap<T>::InstanceVoidMethodCallbackWrapper(
|
|
3503
|
+
napi_env env,
|
|
3504
|
+
napi_callback_info info) {
|
|
3505
|
+
return details::WrapCallback([&] {
|
|
3506
|
+
CallbackInfo callbackInfo(env, info);
|
|
3507
|
+
InstanceVoidMethodCallbackData* callbackData =
|
|
3508
|
+
reinterpret_cast<InstanceVoidMethodCallbackData*>(callbackInfo.Data());
|
|
3509
|
+
callbackInfo.SetData(callbackData->data);
|
|
3510
|
+
T* instance = T::Unwrap(callbackInfo.This().As<Object>());
|
|
3511
|
+
auto cb = callbackData->callback;
|
|
3512
|
+
(instance->*cb)(callbackInfo);
|
|
3513
|
+
return nullptr;
|
|
3514
|
+
});
|
|
3515
|
+
}
|
|
3516
|
+
|
|
3517
|
+
template <typename T>
|
|
3518
|
+
inline napi_value InstanceWrap<T>::InstanceMethodCallbackWrapper(
|
|
3519
|
+
napi_env env,
|
|
3520
|
+
napi_callback_info info) {
|
|
3521
|
+
return details::WrapCallback([&] {
|
|
3522
|
+
CallbackInfo callbackInfo(env, info);
|
|
3523
|
+
InstanceMethodCallbackData* callbackData =
|
|
3524
|
+
reinterpret_cast<InstanceMethodCallbackData*>(callbackInfo.Data());
|
|
3525
|
+
callbackInfo.SetData(callbackData->data);
|
|
3526
|
+
T* instance = T::Unwrap(callbackInfo.This().As<Object>());
|
|
3527
|
+
auto cb = callbackData->callback;
|
|
3528
|
+
return (instance->*cb)(callbackInfo);
|
|
3529
|
+
});
|
|
3530
|
+
}
|
|
3531
|
+
|
|
3532
|
+
template <typename T>
|
|
3533
|
+
inline napi_value InstanceWrap<T>::InstanceGetterCallbackWrapper(
|
|
3534
|
+
napi_env env,
|
|
3535
|
+
napi_callback_info info) {
|
|
3536
|
+
return details::WrapCallback([&] {
|
|
3537
|
+
CallbackInfo callbackInfo(env, info);
|
|
3538
|
+
InstanceAccessorCallbackData* callbackData =
|
|
3539
|
+
reinterpret_cast<InstanceAccessorCallbackData*>(callbackInfo.Data());
|
|
3540
|
+
callbackInfo.SetData(callbackData->data);
|
|
3541
|
+
T* instance = T::Unwrap(callbackInfo.This().As<Object>());
|
|
3542
|
+
auto cb = callbackData->getterCallback;
|
|
3543
|
+
return (instance->*cb)(callbackInfo);
|
|
3544
|
+
});
|
|
3545
|
+
}
|
|
3546
|
+
|
|
3547
|
+
template <typename T>
|
|
3548
|
+
inline napi_value InstanceWrap<T>::InstanceSetterCallbackWrapper(
|
|
3549
|
+
napi_env env,
|
|
3550
|
+
napi_callback_info info) {
|
|
3551
|
+
return details::WrapCallback([&] {
|
|
3552
|
+
CallbackInfo callbackInfo(env, info);
|
|
3553
|
+
InstanceAccessorCallbackData* callbackData =
|
|
3554
|
+
reinterpret_cast<InstanceAccessorCallbackData*>(callbackInfo.Data());
|
|
3555
|
+
callbackInfo.SetData(callbackData->data);
|
|
3556
|
+
T* instance = T::Unwrap(callbackInfo.This().As<Object>());
|
|
3557
|
+
auto cb = callbackData->setterCallback;
|
|
3558
|
+
(instance->*cb)(callbackInfo, callbackInfo[0]);
|
|
3559
|
+
return nullptr;
|
|
3560
|
+
});
|
|
3561
|
+
}
|
|
3562
|
+
|
|
3563
|
+
template <typename T>
|
|
3564
|
+
template <typename InstanceWrap<T>::InstanceSetterCallback method>
|
|
3565
|
+
inline napi_value InstanceWrap<T>::WrappedMethod(napi_env env, napi_callback_info info) noexcept {
|
|
3566
|
+
return details::WrapCallback([&] {
|
|
3567
|
+
const CallbackInfo cbInfo(env, info);
|
|
3568
|
+
T* instance = T::Unwrap(cbInfo.This().As<Object>());
|
|
3569
|
+
(instance->*method)(cbInfo, cbInfo[0]);
|
|
3570
|
+
return nullptr;
|
|
3571
|
+
});
|
|
3572
|
+
}
|
|
3573
|
+
|
|
3574
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
3575
|
+
// ObjectWrap<T> class
|
|
3576
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
3577
|
+
|
|
3578
|
+
template <typename T>
|
|
3579
|
+
inline ObjectWrap<T>::ObjectWrap(const Napi::CallbackInfo& callbackInfo) {
|
|
3580
|
+
napi_env env = callbackInfo.Env();
|
|
3581
|
+
napi_value wrapper = callbackInfo.This();
|
|
3582
|
+
napi_status status;
|
|
3583
|
+
napi_ref ref;
|
|
3584
|
+
T* instance = static_cast<T*>(this);
|
|
3585
|
+
status = napi_wrap(env, wrapper, instance, FinalizeCallback, nullptr, &ref);
|
|
3586
|
+
NAPI_THROW_IF_FAILED_VOID(env, status);
|
|
3587
|
+
|
|
3588
|
+
Reference<Object>* instanceRef = instance;
|
|
3589
|
+
*instanceRef = Reference<Object>(env, ref);
|
|
3590
|
+
}
|
|
3591
|
+
|
|
3592
|
+
template <typename T>
|
|
3593
|
+
inline ObjectWrap<T>::~ObjectWrap() {
|
|
3594
|
+
// If the JS object still exists at this point, remove the finalizer added
|
|
3595
|
+
// through `napi_wrap()`.
|
|
3596
|
+
if (!IsEmpty()) {
|
|
3597
|
+
Object object = Value();
|
|
3598
|
+
// It is not valid to call `napi_remove_wrap()` with an empty `object`.
|
|
3599
|
+
// This happens e.g. during garbage collection.
|
|
3600
|
+
if (!object.IsEmpty() && _construction_failed) {
|
|
3601
|
+
napi_remove_wrap(Env(), object, nullptr);
|
|
3602
|
+
}
|
|
3603
|
+
}
|
|
3604
|
+
}
|
|
3605
|
+
|
|
3606
|
+
template<typename T>
|
|
3607
|
+
inline T* ObjectWrap<T>::Unwrap(Object wrapper) {
|
|
3608
|
+
T* unwrapped;
|
|
3609
|
+
napi_status status = napi_unwrap(wrapper.Env(), wrapper, reinterpret_cast<void**>(&unwrapped));
|
|
3610
|
+
NAPI_THROW_IF_FAILED(wrapper.Env(), status, nullptr);
|
|
3611
|
+
return unwrapped;
|
|
3612
|
+
}
|
|
3613
|
+
|
|
3614
|
+
template <typename T>
|
|
3615
|
+
inline Function
|
|
3616
|
+
ObjectWrap<T>::DefineClass(Napi::Env env,
|
|
3617
|
+
const char* utf8name,
|
|
3618
|
+
const size_t props_count,
|
|
3619
|
+
const napi_property_descriptor* descriptors,
|
|
3620
|
+
void* data) {
|
|
3621
|
+
napi_status status;
|
|
3622
|
+
std::vector<napi_property_descriptor> props(props_count);
|
|
3623
|
+
|
|
3624
|
+
// We copy the descriptors to a local array because before defining the class
|
|
3625
|
+
// we must replace static method property descriptors with value property
|
|
3626
|
+
// descriptors such that the value is a function-valued `napi_value` created
|
|
3627
|
+
// with `CreateFunction()`.
|
|
3628
|
+
//
|
|
3629
|
+
// This replacement could be made for instance methods as well, but V8 aborts
|
|
3630
|
+
// if we do that, because it expects methods defined on the prototype template
|
|
3631
|
+
// to have `FunctionTemplate`s.
|
|
3042
3632
|
for (size_t index = 0; index < props_count; index++) {
|
|
3043
3633
|
props[index] = descriptors[index];
|
|
3044
3634
|
napi_property_descriptor* prop = &props[index];
|
|
3045
3635
|
if (prop->method == T::StaticMethodCallbackWrapper) {
|
|
3046
3636
|
status = CreateFunction(env,
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3637
|
+
utf8name,
|
|
3638
|
+
prop->method,
|
|
3639
|
+
static_cast<StaticMethodCallbackData*>(prop->data),
|
|
3050
3640
|
&(prop->value));
|
|
3051
3641
|
NAPI_THROW_IF_FAILED(env, status, Function());
|
|
3052
3642
|
prop->method = nullptr;
|
|
3053
3643
|
prop->data = nullptr;
|
|
3054
3644
|
} else if (prop->method == T::StaticVoidMethodCallbackWrapper) {
|
|
3055
3645
|
status = CreateFunction(env,
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3646
|
+
utf8name,
|
|
3647
|
+
prop->method,
|
|
3648
|
+
static_cast<StaticVoidMethodCallbackData*>(prop->data),
|
|
3649
|
+
&(prop->value));
|
|
3060
3650
|
NAPI_THROW_IF_FAILED(env, status, Function());
|
|
3061
3651
|
prop->method = nullptr;
|
|
3062
3652
|
prop->data = nullptr;
|
|
@@ -3086,24 +3676,10 @@ ObjectWrap<T>::DefineClass(Napi::Env env,
|
|
|
3086
3676
|
value,
|
|
3087
3677
|
static_cast<StaticAccessorCallbackData*>(prop->data));
|
|
3088
3678
|
NAPI_THROW_IF_FAILED(env, status, Function());
|
|
3089
|
-
} else
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
static_cast<InstanceAccessorCallbackData*>(prop->data));
|
|
3094
|
-
NAPI_THROW_IF_FAILED(env, status, Function());
|
|
3095
|
-
} else if (prop->method != nullptr && !(prop->attributes & napi_static)) {
|
|
3096
|
-
if (prop->method == T::InstanceVoidMethodCallbackWrapper) {
|
|
3097
|
-
status = Napi::details::AttachData(env,
|
|
3098
|
-
value,
|
|
3099
|
-
static_cast<InstanceVoidMethodCallbackData*>(prop->data));
|
|
3100
|
-
NAPI_THROW_IF_FAILED(env, status, Function());
|
|
3101
|
-
} else if (prop->method == T::InstanceMethodCallbackWrapper) {
|
|
3102
|
-
status = Napi::details::AttachData(env,
|
|
3103
|
-
value,
|
|
3104
|
-
static_cast<InstanceMethodCallbackData*>(prop->data));
|
|
3105
|
-
NAPI_THROW_IF_FAILED(env, status, Function());
|
|
3106
|
-
}
|
|
3679
|
+
} else {
|
|
3680
|
+
// InstanceWrap<T>::AttachPropData is responsible for attaching the data
|
|
3681
|
+
// of instance methods and accessors.
|
|
3682
|
+
T::AttachPropData(env, value, prop);
|
|
3107
3683
|
}
|
|
3108
3684
|
}
|
|
3109
3685
|
|
|
@@ -3201,188 +3777,148 @@ inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticMethod(
|
|
|
3201
3777
|
}
|
|
3202
3778
|
|
|
3203
3779
|
template <typename T>
|
|
3204
|
-
|
|
3780
|
+
template <typename ObjectWrap<T>::StaticVoidMethodCallback method>
|
|
3781
|
+
inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticMethod(
|
|
3205
3782
|
const char* utf8name,
|
|
3206
|
-
StaticGetterCallback getter,
|
|
3207
|
-
StaticSetterCallback setter,
|
|
3208
3783
|
napi_property_attributes attributes,
|
|
3209
3784
|
void* data) {
|
|
3210
|
-
StaticAccessorCallbackData* callbackData =
|
|
3211
|
-
new StaticAccessorCallbackData({ getter, setter, data });
|
|
3212
|
-
|
|
3213
3785
|
napi_property_descriptor desc = napi_property_descriptor();
|
|
3214
3786
|
desc.utf8name = utf8name;
|
|
3215
|
-
desc.
|
|
3216
|
-
desc.
|
|
3217
|
-
desc.data = callbackData;
|
|
3787
|
+
desc.method = details::TemplatedVoidCallback<method>;
|
|
3788
|
+
desc.data = data;
|
|
3218
3789
|
desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
|
|
3219
3790
|
return desc;
|
|
3220
3791
|
}
|
|
3221
3792
|
|
|
3222
3793
|
template <typename T>
|
|
3223
|
-
|
|
3794
|
+
template <typename ObjectWrap<T>::StaticVoidMethodCallback method>
|
|
3795
|
+
inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticMethod(
|
|
3224
3796
|
Symbol name,
|
|
3225
|
-
StaticGetterCallback getter,
|
|
3226
|
-
StaticSetterCallback setter,
|
|
3227
3797
|
napi_property_attributes attributes,
|
|
3228
3798
|
void* data) {
|
|
3229
|
-
StaticAccessorCallbackData* callbackData =
|
|
3230
|
-
new StaticAccessorCallbackData({ getter, setter, data });
|
|
3231
|
-
|
|
3232
3799
|
napi_property_descriptor desc = napi_property_descriptor();
|
|
3233
3800
|
desc.name = name;
|
|
3234
|
-
desc.
|
|
3235
|
-
desc.
|
|
3236
|
-
desc.data = callbackData;
|
|
3801
|
+
desc.method = details::TemplatedVoidCallback<method>;
|
|
3802
|
+
desc.data = data;
|
|
3237
3803
|
desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
|
|
3238
3804
|
return desc;
|
|
3239
3805
|
}
|
|
3240
3806
|
|
|
3241
3807
|
template <typename T>
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
InstanceVoidMethodCallback method,
|
|
3245
|
-
napi_property_attributes attributes,
|
|
3246
|
-
void* data) {
|
|
3247
|
-
InstanceVoidMethodCallbackData* callbackData =
|
|
3248
|
-
new InstanceVoidMethodCallbackData({ method, data});
|
|
3249
|
-
|
|
3250
|
-
napi_property_descriptor desc = napi_property_descriptor();
|
|
3251
|
-
desc.utf8name = utf8name;
|
|
3252
|
-
desc.method = T::InstanceVoidMethodCallbackWrapper;
|
|
3253
|
-
desc.data = callbackData;
|
|
3254
|
-
desc.attributes = attributes;
|
|
3255
|
-
return desc;
|
|
3256
|
-
}
|
|
3257
|
-
|
|
3258
|
-
template <typename T>
|
|
3259
|
-
inline ClassPropertyDescriptor<T> ObjectWrap<T>::InstanceMethod(
|
|
3808
|
+
template <typename ObjectWrap<T>::StaticMethodCallback method>
|
|
3809
|
+
inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticMethod(
|
|
3260
3810
|
const char* utf8name,
|
|
3261
|
-
InstanceMethodCallback method,
|
|
3262
3811
|
napi_property_attributes attributes,
|
|
3263
3812
|
void* data) {
|
|
3264
|
-
InstanceMethodCallbackData* callbackData = new InstanceMethodCallbackData({ method, data });
|
|
3265
|
-
|
|
3266
3813
|
napi_property_descriptor desc = napi_property_descriptor();
|
|
3267
3814
|
desc.utf8name = utf8name;
|
|
3268
|
-
desc.method =
|
|
3269
|
-
desc.data =
|
|
3270
|
-
desc.attributes = attributes;
|
|
3271
|
-
return desc;
|
|
3272
|
-
}
|
|
3273
|
-
|
|
3274
|
-
template <typename T>
|
|
3275
|
-
inline ClassPropertyDescriptor<T> ObjectWrap<T>::InstanceMethod(
|
|
3276
|
-
Symbol name,
|
|
3277
|
-
InstanceVoidMethodCallback method,
|
|
3278
|
-
napi_property_attributes attributes,
|
|
3279
|
-
void* data) {
|
|
3280
|
-
InstanceVoidMethodCallbackData* callbackData =
|
|
3281
|
-
new InstanceVoidMethodCallbackData({ method, data});
|
|
3282
|
-
|
|
3283
|
-
napi_property_descriptor desc = napi_property_descriptor();
|
|
3284
|
-
desc.name = name;
|
|
3285
|
-
desc.method = T::InstanceVoidMethodCallbackWrapper;
|
|
3286
|
-
desc.data = callbackData;
|
|
3287
|
-
desc.attributes = attributes;
|
|
3815
|
+
desc.method = details::TemplatedCallback<method>;
|
|
3816
|
+
desc.data = data;
|
|
3817
|
+
desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
|
|
3288
3818
|
return desc;
|
|
3289
3819
|
}
|
|
3290
3820
|
|
|
3291
3821
|
template <typename T>
|
|
3292
|
-
|
|
3822
|
+
template <typename ObjectWrap<T>::StaticMethodCallback method>
|
|
3823
|
+
inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticMethod(
|
|
3293
3824
|
Symbol name,
|
|
3294
|
-
InstanceMethodCallback method,
|
|
3295
3825
|
napi_property_attributes attributes,
|
|
3296
3826
|
void* data) {
|
|
3297
|
-
InstanceMethodCallbackData* callbackData = new InstanceMethodCallbackData({ method, data });
|
|
3298
|
-
|
|
3299
3827
|
napi_property_descriptor desc = napi_property_descriptor();
|
|
3300
3828
|
desc.name = name;
|
|
3301
|
-
desc.method =
|
|
3302
|
-
desc.data =
|
|
3303
|
-
desc.attributes = attributes;
|
|
3829
|
+
desc.method = details::TemplatedCallback<method>;
|
|
3830
|
+
desc.data = data;
|
|
3831
|
+
desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
|
|
3304
3832
|
return desc;
|
|
3305
3833
|
}
|
|
3306
3834
|
|
|
3307
3835
|
template <typename T>
|
|
3308
|
-
inline ClassPropertyDescriptor<T> ObjectWrap<T>::
|
|
3836
|
+
inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticAccessor(
|
|
3309
3837
|
const char* utf8name,
|
|
3310
|
-
|
|
3311
|
-
|
|
3838
|
+
StaticGetterCallback getter,
|
|
3839
|
+
StaticSetterCallback setter,
|
|
3312
3840
|
napi_property_attributes attributes,
|
|
3313
3841
|
void* data) {
|
|
3314
|
-
|
|
3315
|
-
new
|
|
3842
|
+
StaticAccessorCallbackData* callbackData =
|
|
3843
|
+
new StaticAccessorCallbackData({ getter, setter, data });
|
|
3316
3844
|
|
|
3317
3845
|
napi_property_descriptor desc = napi_property_descriptor();
|
|
3318
3846
|
desc.utf8name = utf8name;
|
|
3319
|
-
desc.getter = getter != nullptr ? T::
|
|
3320
|
-
desc.setter = setter != nullptr ? T::
|
|
3847
|
+
desc.getter = getter != nullptr ? T::StaticGetterCallbackWrapper : nullptr;
|
|
3848
|
+
desc.setter = setter != nullptr ? T::StaticSetterCallbackWrapper : nullptr;
|
|
3321
3849
|
desc.data = callbackData;
|
|
3322
|
-
desc.attributes = attributes;
|
|
3850
|
+
desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
|
|
3323
3851
|
return desc;
|
|
3324
3852
|
}
|
|
3325
3853
|
|
|
3326
3854
|
template <typename T>
|
|
3327
|
-
inline ClassPropertyDescriptor<T> ObjectWrap<T>::
|
|
3855
|
+
inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticAccessor(
|
|
3328
3856
|
Symbol name,
|
|
3329
|
-
|
|
3330
|
-
|
|
3857
|
+
StaticGetterCallback getter,
|
|
3858
|
+
StaticSetterCallback setter,
|
|
3331
3859
|
napi_property_attributes attributes,
|
|
3332
3860
|
void* data) {
|
|
3333
|
-
|
|
3334
|
-
new
|
|
3861
|
+
StaticAccessorCallbackData* callbackData =
|
|
3862
|
+
new StaticAccessorCallbackData({ getter, setter, data });
|
|
3335
3863
|
|
|
3336
3864
|
napi_property_descriptor desc = napi_property_descriptor();
|
|
3337
3865
|
desc.name = name;
|
|
3338
|
-
desc.getter = getter != nullptr ? T::
|
|
3339
|
-
desc.setter = setter != nullptr ? T::
|
|
3866
|
+
desc.getter = getter != nullptr ? T::StaticGetterCallbackWrapper : nullptr;
|
|
3867
|
+
desc.setter = setter != nullptr ? T::StaticSetterCallbackWrapper : nullptr;
|
|
3340
3868
|
desc.data = callbackData;
|
|
3341
|
-
desc.attributes = attributes;
|
|
3869
|
+
desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
|
|
3342
3870
|
return desc;
|
|
3343
3871
|
}
|
|
3344
3872
|
|
|
3345
3873
|
template <typename T>
|
|
3346
|
-
|
|
3347
|
-
|
|
3874
|
+
template <typename ObjectWrap<T>::StaticGetterCallback getter,
|
|
3875
|
+
typename ObjectWrap<T>::StaticSetterCallback setter>
|
|
3876
|
+
inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticAccessor(
|
|
3877
|
+
const char* utf8name,
|
|
3878
|
+
napi_property_attributes attributes,
|
|
3879
|
+
void* data) {
|
|
3348
3880
|
napi_property_descriptor desc = napi_property_descriptor();
|
|
3349
3881
|
desc.utf8name = utf8name;
|
|
3350
|
-
desc.
|
|
3882
|
+
desc.getter = details::TemplatedCallback<getter>;
|
|
3883
|
+
desc.setter = This::WrapStaticSetter(This::StaticSetterTag<setter>());
|
|
3884
|
+
desc.data = data;
|
|
3351
3885
|
desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
|
|
3352
3886
|
return desc;
|
|
3353
3887
|
}
|
|
3354
3888
|
|
|
3355
3889
|
template <typename T>
|
|
3356
|
-
|
|
3357
|
-
|
|
3890
|
+
template <typename ObjectWrap<T>::StaticGetterCallback getter,
|
|
3891
|
+
typename ObjectWrap<T>::StaticSetterCallback setter>
|
|
3892
|
+
inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticAccessor(
|
|
3893
|
+
Symbol name,
|
|
3894
|
+
napi_property_attributes attributes,
|
|
3895
|
+
void* data) {
|
|
3358
3896
|
napi_property_descriptor desc = napi_property_descriptor();
|
|
3359
3897
|
desc.name = name;
|
|
3360
|
-
desc.
|
|
3898
|
+
desc.getter = details::TemplatedCallback<getter>;
|
|
3899
|
+
desc.setter = This::WrapStaticSetter(This::StaticSetterTag<setter>());
|
|
3900
|
+
desc.data = data;
|
|
3361
3901
|
desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
|
|
3362
3902
|
return desc;
|
|
3363
3903
|
}
|
|
3364
3904
|
|
|
3365
3905
|
template <typename T>
|
|
3366
|
-
inline ClassPropertyDescriptor<T> ObjectWrap<T>::
|
|
3367
|
-
|
|
3368
|
-
Napi::Value value,
|
|
3369
|
-
napi_property_attributes attributes) {
|
|
3906
|
+
inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticValue(const char* utf8name,
|
|
3907
|
+
Napi::Value value, napi_property_attributes attributes) {
|
|
3370
3908
|
napi_property_descriptor desc = napi_property_descriptor();
|
|
3371
3909
|
desc.utf8name = utf8name;
|
|
3372
3910
|
desc.value = value;
|
|
3373
|
-
desc.attributes = attributes;
|
|
3911
|
+
desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
|
|
3374
3912
|
return desc;
|
|
3375
3913
|
}
|
|
3376
3914
|
|
|
3377
3915
|
template <typename T>
|
|
3378
|
-
inline ClassPropertyDescriptor<T> ObjectWrap<T>::
|
|
3379
|
-
|
|
3380
|
-
Napi::Value value,
|
|
3381
|
-
napi_property_attributes attributes) {
|
|
3916
|
+
inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticValue(Symbol name,
|
|
3917
|
+
Napi::Value value, napi_property_attributes attributes) {
|
|
3382
3918
|
napi_property_descriptor desc = napi_property_descriptor();
|
|
3383
3919
|
desc.name = name;
|
|
3384
3920
|
desc.value = value;
|
|
3385
|
-
desc.attributes = attributes;
|
|
3921
|
+
desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
|
|
3386
3922
|
return desc;
|
|
3387
3923
|
}
|
|
3388
3924
|
|
|
@@ -3479,74 +4015,23 @@ inline napi_value ObjectWrap<T>::StaticSetterCallbackWrapper(
|
|
|
3479
4015
|
}
|
|
3480
4016
|
|
|
3481
4017
|
template <typename T>
|
|
3482
|
-
inline
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
InstanceVoidMethodCallbackData* callbackData =
|
|
3488
|
-
reinterpret_cast<InstanceVoidMethodCallbackData*>(callbackInfo.Data());
|
|
3489
|
-
callbackInfo.SetData(callbackData->data);
|
|
3490
|
-
T* instance = Unwrap(callbackInfo.This().As<Object>());
|
|
3491
|
-
auto cb = callbackData->callback;
|
|
3492
|
-
(instance->*cb)(callbackInfo);
|
|
3493
|
-
return nullptr;
|
|
3494
|
-
});
|
|
3495
|
-
}
|
|
3496
|
-
|
|
3497
|
-
template <typename T>
|
|
3498
|
-
inline napi_value ObjectWrap<T>::InstanceMethodCallbackWrapper(
|
|
3499
|
-
napi_env env,
|
|
3500
|
-
napi_callback_info info) {
|
|
3501
|
-
return details::WrapCallback([&] {
|
|
3502
|
-
CallbackInfo callbackInfo(env, info);
|
|
3503
|
-
InstanceMethodCallbackData* callbackData =
|
|
3504
|
-
reinterpret_cast<InstanceMethodCallbackData*>(callbackInfo.Data());
|
|
3505
|
-
callbackInfo.SetData(callbackData->data);
|
|
3506
|
-
T* instance = Unwrap(callbackInfo.This().As<Object>());
|
|
3507
|
-
auto cb = callbackData->callback;
|
|
3508
|
-
return (instance->*cb)(callbackInfo);
|
|
3509
|
-
});
|
|
3510
|
-
}
|
|
3511
|
-
|
|
3512
|
-
template <typename T>
|
|
3513
|
-
inline napi_value ObjectWrap<T>::InstanceGetterCallbackWrapper(
|
|
3514
|
-
napi_env env,
|
|
3515
|
-
napi_callback_info info) {
|
|
3516
|
-
return details::WrapCallback([&] {
|
|
3517
|
-
CallbackInfo callbackInfo(env, info);
|
|
3518
|
-
InstanceAccessorCallbackData* callbackData =
|
|
3519
|
-
reinterpret_cast<InstanceAccessorCallbackData*>(callbackInfo.Data());
|
|
3520
|
-
callbackInfo.SetData(callbackData->data);
|
|
3521
|
-
T* instance = Unwrap(callbackInfo.This().As<Object>());
|
|
3522
|
-
auto cb = callbackData->getterCallback;
|
|
3523
|
-
return (instance->*cb)(callbackInfo);
|
|
3524
|
-
});
|
|
4018
|
+
inline void ObjectWrap<T>::FinalizeCallback(napi_env env, void* data, void* /*hint*/) {
|
|
4019
|
+
HandleScope scope(env);
|
|
4020
|
+
T* instance = static_cast<T*>(data);
|
|
4021
|
+
instance->Finalize(Napi::Env(env));
|
|
4022
|
+
delete instance;
|
|
3525
4023
|
}
|
|
3526
4024
|
|
|
3527
4025
|
template <typename T>
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
napi_callback_info info) {
|
|
4026
|
+
template <typename ObjectWrap<T>::StaticSetterCallback method>
|
|
4027
|
+
inline napi_value ObjectWrap<T>::WrappedMethod(napi_env env, napi_callback_info info) noexcept {
|
|
3531
4028
|
return details::WrapCallback([&] {
|
|
3532
|
-
CallbackInfo
|
|
3533
|
-
|
|
3534
|
-
reinterpret_cast<InstanceAccessorCallbackData*>(callbackInfo.Data());
|
|
3535
|
-
callbackInfo.SetData(callbackData->data);
|
|
3536
|
-
T* instance = Unwrap(callbackInfo.This().As<Object>());
|
|
3537
|
-
auto cb = callbackData->setterCallback;
|
|
3538
|
-
(instance->*cb)(callbackInfo, callbackInfo[0]);
|
|
4029
|
+
const CallbackInfo cbInfo(env, info);
|
|
4030
|
+
method(cbInfo, cbInfo[0]);
|
|
3539
4031
|
return nullptr;
|
|
3540
4032
|
});
|
|
3541
4033
|
}
|
|
3542
4034
|
|
|
3543
|
-
template <typename T>
|
|
3544
|
-
inline void ObjectWrap<T>::FinalizeCallback(napi_env env, void* data, void* /*hint*/) {
|
|
3545
|
-
ObjectWrap<T>* instance = static_cast<ObjectWrap<T>*>(data);
|
|
3546
|
-
instance->Finalize(Napi::Env(env));
|
|
3547
|
-
delete instance;
|
|
3548
|
-
}
|
|
3549
|
-
|
|
3550
4035
|
////////////////////////////////////////////////////////////////////////////////
|
|
3551
4036
|
// HandleScope class
|
|
3552
4037
|
////////////////////////////////////////////////////////////////////////////////
|
|
@@ -3744,158 +4229,653 @@ inline AsyncWorker::AsyncWorker(const Object& receiver,
|
|
|
3744
4229
|
_env, resource_name, NAPI_AUTO_LENGTH, &resource_id);
|
|
3745
4230
|
NAPI_THROW_IF_FAILED_VOID(_env, status);
|
|
3746
4231
|
|
|
3747
|
-
status = napi_create_async_work(_env, resource, resource_id,
|
|
3748
|
-
|
|
4232
|
+
status = napi_create_async_work(_env, resource, resource_id, OnAsyncWorkExecute,
|
|
4233
|
+
OnAsyncWorkComplete, this, &_work);
|
|
4234
|
+
NAPI_THROW_IF_FAILED_VOID(_env, status);
|
|
4235
|
+
}
|
|
4236
|
+
|
|
4237
|
+
inline AsyncWorker::AsyncWorker(Napi::Env env)
|
|
4238
|
+
: AsyncWorker(env, "generic") {
|
|
4239
|
+
}
|
|
4240
|
+
|
|
4241
|
+
inline AsyncWorker::AsyncWorker(Napi::Env env,
|
|
4242
|
+
const char* resource_name)
|
|
4243
|
+
: AsyncWorker(env, resource_name, Object::New(env)) {
|
|
4244
|
+
}
|
|
4245
|
+
|
|
4246
|
+
inline AsyncWorker::AsyncWorker(Napi::Env env,
|
|
4247
|
+
const char* resource_name,
|
|
4248
|
+
const Object& resource)
|
|
4249
|
+
: _env(env),
|
|
4250
|
+
_receiver(),
|
|
4251
|
+
_callback(),
|
|
4252
|
+
_suppress_destruct(false) {
|
|
4253
|
+
napi_value resource_id;
|
|
4254
|
+
napi_status status = napi_create_string_latin1(
|
|
4255
|
+
_env, resource_name, NAPI_AUTO_LENGTH, &resource_id);
|
|
4256
|
+
NAPI_THROW_IF_FAILED_VOID(_env, status);
|
|
4257
|
+
|
|
4258
|
+
status = napi_create_async_work(_env, resource, resource_id, OnAsyncWorkExecute,
|
|
4259
|
+
OnAsyncWorkComplete, this, &_work);
|
|
4260
|
+
NAPI_THROW_IF_FAILED_VOID(_env, status);
|
|
4261
|
+
}
|
|
4262
|
+
|
|
4263
|
+
inline AsyncWorker::~AsyncWorker() {
|
|
4264
|
+
if (_work != nullptr) {
|
|
4265
|
+
napi_delete_async_work(_env, _work);
|
|
4266
|
+
_work = nullptr;
|
|
4267
|
+
}
|
|
4268
|
+
}
|
|
4269
|
+
|
|
4270
|
+
inline void AsyncWorker::Destroy() {
|
|
4271
|
+
delete this;
|
|
4272
|
+
}
|
|
4273
|
+
|
|
4274
|
+
inline AsyncWorker::AsyncWorker(AsyncWorker&& other) {
|
|
4275
|
+
_env = other._env;
|
|
4276
|
+
other._env = nullptr;
|
|
4277
|
+
_work = other._work;
|
|
4278
|
+
other._work = nullptr;
|
|
4279
|
+
_receiver = std::move(other._receiver);
|
|
4280
|
+
_callback = std::move(other._callback);
|
|
4281
|
+
_error = std::move(other._error);
|
|
4282
|
+
_suppress_destruct = other._suppress_destruct;
|
|
4283
|
+
}
|
|
4284
|
+
|
|
4285
|
+
inline AsyncWorker& AsyncWorker::operator =(AsyncWorker&& other) {
|
|
4286
|
+
_env = other._env;
|
|
4287
|
+
other._env = nullptr;
|
|
4288
|
+
_work = other._work;
|
|
4289
|
+
other._work = nullptr;
|
|
4290
|
+
_receiver = std::move(other._receiver);
|
|
4291
|
+
_callback = std::move(other._callback);
|
|
4292
|
+
_error = std::move(other._error);
|
|
4293
|
+
_suppress_destruct = other._suppress_destruct;
|
|
4294
|
+
return *this;
|
|
4295
|
+
}
|
|
4296
|
+
|
|
4297
|
+
inline AsyncWorker::operator napi_async_work() const {
|
|
4298
|
+
return _work;
|
|
4299
|
+
}
|
|
4300
|
+
|
|
4301
|
+
inline Napi::Env AsyncWorker::Env() const {
|
|
4302
|
+
return Napi::Env(_env);
|
|
4303
|
+
}
|
|
4304
|
+
|
|
4305
|
+
inline void AsyncWorker::Queue() {
|
|
4306
|
+
napi_status status = napi_queue_async_work(_env, _work);
|
|
4307
|
+
NAPI_THROW_IF_FAILED_VOID(_env, status);
|
|
4308
|
+
}
|
|
4309
|
+
|
|
4310
|
+
inline void AsyncWorker::Cancel() {
|
|
4311
|
+
napi_status status = napi_cancel_async_work(_env, _work);
|
|
3749
4312
|
NAPI_THROW_IF_FAILED_VOID(_env, status);
|
|
3750
4313
|
}
|
|
3751
4314
|
|
|
3752
|
-
inline AsyncWorker::
|
|
3753
|
-
|
|
4315
|
+
inline ObjectReference& AsyncWorker::Receiver() {
|
|
4316
|
+
return _receiver;
|
|
4317
|
+
}
|
|
4318
|
+
|
|
4319
|
+
inline FunctionReference& AsyncWorker::Callback() {
|
|
4320
|
+
return _callback;
|
|
4321
|
+
}
|
|
4322
|
+
|
|
4323
|
+
inline void AsyncWorker::SuppressDestruct() {
|
|
4324
|
+
_suppress_destruct = true;
|
|
4325
|
+
}
|
|
4326
|
+
|
|
4327
|
+
inline void AsyncWorker::OnOK() {
|
|
4328
|
+
if (!_callback.IsEmpty()) {
|
|
4329
|
+
_callback.Call(_receiver.Value(), GetResult(_callback.Env()));
|
|
4330
|
+
}
|
|
4331
|
+
}
|
|
4332
|
+
|
|
4333
|
+
inline void AsyncWorker::OnError(const Error& e) {
|
|
4334
|
+
if (!_callback.IsEmpty()) {
|
|
4335
|
+
_callback.Call(_receiver.Value(), std::initializer_list<napi_value>{ e.Value() });
|
|
4336
|
+
}
|
|
4337
|
+
}
|
|
4338
|
+
|
|
4339
|
+
inline void AsyncWorker::SetError(const std::string& error) {
|
|
4340
|
+
_error = error;
|
|
4341
|
+
}
|
|
4342
|
+
|
|
4343
|
+
inline std::vector<napi_value> AsyncWorker::GetResult(Napi::Env /*env*/) {
|
|
4344
|
+
return {};
|
|
4345
|
+
}
|
|
4346
|
+
// The OnAsyncWorkExecute method receives an napi_env argument. However, do NOT
|
|
4347
|
+
// use it within this method, as it does not run on the JavaScript thread and
|
|
4348
|
+
// must not run any method that would cause JavaScript to run. In practice,
|
|
4349
|
+
// this means that almost any use of napi_env will be incorrect.
|
|
4350
|
+
inline void AsyncWorker::OnAsyncWorkExecute(napi_env env, void* asyncworker) {
|
|
4351
|
+
AsyncWorker* self = static_cast<AsyncWorker*>(asyncworker);
|
|
4352
|
+
self->OnExecute(env);
|
|
4353
|
+
}
|
|
4354
|
+
// The OnExecute method receives an napi_env argument. However, do NOT
|
|
4355
|
+
// use it within this method, as it does not run on the JavaScript thread and
|
|
4356
|
+
// must not run any method that would cause JavaScript to run. In practice,
|
|
4357
|
+
// this means that almost any use of napi_env will be incorrect.
|
|
4358
|
+
inline void AsyncWorker::OnExecute(Napi::Env /*DO_NOT_USE*/) {
|
|
4359
|
+
#ifdef NAPI_CPP_EXCEPTIONS
|
|
4360
|
+
try {
|
|
4361
|
+
Execute();
|
|
4362
|
+
} catch (const std::exception& e) {
|
|
4363
|
+
SetError(e.what());
|
|
4364
|
+
}
|
|
4365
|
+
#else // NAPI_CPP_EXCEPTIONS
|
|
4366
|
+
Execute();
|
|
4367
|
+
#endif // NAPI_CPP_EXCEPTIONS
|
|
4368
|
+
}
|
|
4369
|
+
|
|
4370
|
+
inline void AsyncWorker::OnAsyncWorkComplete(napi_env env,
|
|
4371
|
+
napi_status status,
|
|
4372
|
+
void* asyncworker) {
|
|
4373
|
+
AsyncWorker* self = static_cast<AsyncWorker*>(asyncworker);
|
|
4374
|
+
self->OnWorkComplete(env, status);
|
|
4375
|
+
}
|
|
4376
|
+
inline void AsyncWorker::OnWorkComplete(Napi::Env /*env*/, napi_status status) {
|
|
4377
|
+
if (status != napi_cancelled) {
|
|
4378
|
+
HandleScope scope(_env);
|
|
4379
|
+
details::WrapCallback([&] {
|
|
4380
|
+
if (_error.size() == 0) {
|
|
4381
|
+
OnOK();
|
|
4382
|
+
}
|
|
4383
|
+
else {
|
|
4384
|
+
OnError(Error::New(_env, _error));
|
|
4385
|
+
}
|
|
4386
|
+
return nullptr;
|
|
4387
|
+
});
|
|
4388
|
+
}
|
|
4389
|
+
if (!_suppress_destruct) {
|
|
4390
|
+
Destroy();
|
|
4391
|
+
}
|
|
4392
|
+
}
|
|
4393
|
+
|
|
4394
|
+
#if (NAPI_VERSION > 3 && !defined(__wasm32__))
|
|
4395
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
4396
|
+
// TypedThreadSafeFunction<ContextType,DataType,CallJs> class
|
|
4397
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
4398
|
+
|
|
4399
|
+
// Starting with NAPI 5, the JavaScript function `func` parameter of
|
|
4400
|
+
// `napi_create_threadsafe_function` is optional.
|
|
4401
|
+
#if NAPI_VERSION > 4
|
|
4402
|
+
// static, with Callback [missing] Resource [missing] Finalizer [missing]
|
|
4403
|
+
template <typename ContextType,
|
|
4404
|
+
typename DataType,
|
|
4405
|
+
void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
|
|
4406
|
+
template <typename ResourceString>
|
|
4407
|
+
inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
|
|
4408
|
+
TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
|
|
4409
|
+
napi_env env,
|
|
4410
|
+
ResourceString resourceName,
|
|
4411
|
+
size_t maxQueueSize,
|
|
4412
|
+
size_t initialThreadCount,
|
|
4413
|
+
ContextType* context) {
|
|
4414
|
+
TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
|
|
4415
|
+
|
|
4416
|
+
napi_status status =
|
|
4417
|
+
napi_create_threadsafe_function(env,
|
|
4418
|
+
nullptr,
|
|
4419
|
+
nullptr,
|
|
4420
|
+
String::From(env, resourceName),
|
|
4421
|
+
maxQueueSize,
|
|
4422
|
+
initialThreadCount,
|
|
4423
|
+
nullptr,
|
|
4424
|
+
nullptr,
|
|
4425
|
+
context,
|
|
4426
|
+
CallJsInternal,
|
|
4427
|
+
&tsfn._tsfn);
|
|
4428
|
+
if (status != napi_ok) {
|
|
4429
|
+
NAPI_THROW_IF_FAILED(
|
|
4430
|
+
env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
|
|
4431
|
+
}
|
|
4432
|
+
|
|
4433
|
+
return tsfn;
|
|
4434
|
+
}
|
|
4435
|
+
|
|
4436
|
+
// static, with Callback [missing] Resource [passed] Finalizer [missing]
|
|
4437
|
+
template <typename ContextType,
|
|
4438
|
+
typename DataType,
|
|
4439
|
+
void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
|
|
4440
|
+
template <typename ResourceString>
|
|
4441
|
+
inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
|
|
4442
|
+
TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
|
|
4443
|
+
napi_env env,
|
|
4444
|
+
const Object& resource,
|
|
4445
|
+
ResourceString resourceName,
|
|
4446
|
+
size_t maxQueueSize,
|
|
4447
|
+
size_t initialThreadCount,
|
|
4448
|
+
ContextType* context) {
|
|
4449
|
+
TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
|
|
4450
|
+
|
|
4451
|
+
napi_status status =
|
|
4452
|
+
napi_create_threadsafe_function(env,
|
|
4453
|
+
nullptr,
|
|
4454
|
+
resource,
|
|
4455
|
+
String::From(env, resourceName),
|
|
4456
|
+
maxQueueSize,
|
|
4457
|
+
initialThreadCount,
|
|
4458
|
+
nullptr,
|
|
4459
|
+
nullptr,
|
|
4460
|
+
context,
|
|
4461
|
+
CallJsInternal,
|
|
4462
|
+
&tsfn._tsfn);
|
|
4463
|
+
if (status != napi_ok) {
|
|
4464
|
+
NAPI_THROW_IF_FAILED(
|
|
4465
|
+
env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
|
|
4466
|
+
}
|
|
4467
|
+
|
|
4468
|
+
return tsfn;
|
|
4469
|
+
}
|
|
4470
|
+
|
|
4471
|
+
// static, with Callback [missing] Resource [missing] Finalizer [passed]
|
|
4472
|
+
template <typename ContextType,
|
|
4473
|
+
typename DataType,
|
|
4474
|
+
void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
|
|
4475
|
+
template <typename ResourceString,
|
|
4476
|
+
typename Finalizer,
|
|
4477
|
+
typename FinalizerDataType>
|
|
4478
|
+
inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
|
|
4479
|
+
TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
|
|
4480
|
+
napi_env env,
|
|
4481
|
+
ResourceString resourceName,
|
|
4482
|
+
size_t maxQueueSize,
|
|
4483
|
+
size_t initialThreadCount,
|
|
4484
|
+
ContextType* context,
|
|
4485
|
+
Finalizer finalizeCallback,
|
|
4486
|
+
FinalizerDataType* data) {
|
|
4487
|
+
TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
|
|
4488
|
+
|
|
4489
|
+
auto* finalizeData = new details::
|
|
4490
|
+
ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
|
|
4491
|
+
{data, finalizeCallback});
|
|
4492
|
+
napi_status status = napi_create_threadsafe_function(
|
|
4493
|
+
env,
|
|
4494
|
+
nullptr,
|
|
4495
|
+
nullptr,
|
|
4496
|
+
String::From(env, resourceName),
|
|
4497
|
+
maxQueueSize,
|
|
4498
|
+
initialThreadCount,
|
|
4499
|
+
finalizeData,
|
|
4500
|
+
details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
|
|
4501
|
+
FinalizeFinalizeWrapperWithDataAndContext,
|
|
4502
|
+
context,
|
|
4503
|
+
CallJsInternal,
|
|
4504
|
+
&tsfn._tsfn);
|
|
4505
|
+
if (status != napi_ok) {
|
|
4506
|
+
delete finalizeData;
|
|
4507
|
+
NAPI_THROW_IF_FAILED(
|
|
4508
|
+
env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
|
|
4509
|
+
}
|
|
4510
|
+
|
|
4511
|
+
return tsfn;
|
|
4512
|
+
}
|
|
4513
|
+
|
|
4514
|
+
// static, with Callback [missing] Resource [passed] Finalizer [passed]
|
|
4515
|
+
template <typename ContextType,
|
|
4516
|
+
typename DataType,
|
|
4517
|
+
void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
|
|
4518
|
+
template <typename ResourceString,
|
|
4519
|
+
typename Finalizer,
|
|
4520
|
+
typename FinalizerDataType>
|
|
4521
|
+
inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
|
|
4522
|
+
TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
|
|
4523
|
+
napi_env env,
|
|
4524
|
+
const Object& resource,
|
|
4525
|
+
ResourceString resourceName,
|
|
4526
|
+
size_t maxQueueSize,
|
|
4527
|
+
size_t initialThreadCount,
|
|
4528
|
+
ContextType* context,
|
|
4529
|
+
Finalizer finalizeCallback,
|
|
4530
|
+
FinalizerDataType* data) {
|
|
4531
|
+
TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
|
|
4532
|
+
|
|
4533
|
+
auto* finalizeData = new details::
|
|
4534
|
+
ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
|
|
4535
|
+
{data, finalizeCallback});
|
|
4536
|
+
napi_status status = napi_create_threadsafe_function(
|
|
4537
|
+
env,
|
|
4538
|
+
nullptr,
|
|
4539
|
+
resource,
|
|
4540
|
+
String::From(env, resourceName),
|
|
4541
|
+
maxQueueSize,
|
|
4542
|
+
initialThreadCount,
|
|
4543
|
+
finalizeData,
|
|
4544
|
+
details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
|
|
4545
|
+
FinalizeFinalizeWrapperWithDataAndContext,
|
|
4546
|
+
context,
|
|
4547
|
+
CallJsInternal,
|
|
4548
|
+
&tsfn._tsfn);
|
|
4549
|
+
if (status != napi_ok) {
|
|
4550
|
+
delete finalizeData;
|
|
4551
|
+
NAPI_THROW_IF_FAILED(
|
|
4552
|
+
env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
|
|
4553
|
+
}
|
|
4554
|
+
|
|
4555
|
+
return tsfn;
|
|
4556
|
+
}
|
|
4557
|
+
#endif
|
|
4558
|
+
|
|
4559
|
+
// static, with Callback [passed] Resource [missing] Finalizer [missing]
|
|
4560
|
+
template <typename ContextType,
|
|
4561
|
+
typename DataType,
|
|
4562
|
+
void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
|
|
4563
|
+
template <typename ResourceString>
|
|
4564
|
+
inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
|
|
4565
|
+
TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
|
|
4566
|
+
napi_env env,
|
|
4567
|
+
const Function& callback,
|
|
4568
|
+
ResourceString resourceName,
|
|
4569
|
+
size_t maxQueueSize,
|
|
4570
|
+
size_t initialThreadCount,
|
|
4571
|
+
ContextType* context) {
|
|
4572
|
+
TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
|
|
4573
|
+
|
|
4574
|
+
napi_status status =
|
|
4575
|
+
napi_create_threadsafe_function(env,
|
|
4576
|
+
callback,
|
|
4577
|
+
nullptr,
|
|
4578
|
+
String::From(env, resourceName),
|
|
4579
|
+
maxQueueSize,
|
|
4580
|
+
initialThreadCount,
|
|
4581
|
+
nullptr,
|
|
4582
|
+
nullptr,
|
|
4583
|
+
context,
|
|
4584
|
+
CallJsInternal,
|
|
4585
|
+
&tsfn._tsfn);
|
|
4586
|
+
if (status != napi_ok) {
|
|
4587
|
+
NAPI_THROW_IF_FAILED(
|
|
4588
|
+
env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
|
|
4589
|
+
}
|
|
4590
|
+
|
|
4591
|
+
return tsfn;
|
|
3754
4592
|
}
|
|
3755
4593
|
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
4594
|
+
// static, with Callback [passed] Resource [passed] Finalizer [missing]
|
|
4595
|
+
template <typename ContextType,
|
|
4596
|
+
typename DataType,
|
|
4597
|
+
void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
|
|
4598
|
+
template <typename ResourceString>
|
|
4599
|
+
inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
|
|
4600
|
+
TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
|
|
4601
|
+
napi_env env,
|
|
4602
|
+
const Function& callback,
|
|
4603
|
+
const Object& resource,
|
|
4604
|
+
ResourceString resourceName,
|
|
4605
|
+
size_t maxQueueSize,
|
|
4606
|
+
size_t initialThreadCount,
|
|
4607
|
+
ContextType* context) {
|
|
4608
|
+
TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
|
|
4609
|
+
|
|
4610
|
+
napi_status status =
|
|
4611
|
+
napi_create_threadsafe_function(env,
|
|
4612
|
+
callback,
|
|
4613
|
+
resource,
|
|
4614
|
+
String::From(env, resourceName),
|
|
4615
|
+
maxQueueSize,
|
|
4616
|
+
initialThreadCount,
|
|
4617
|
+
nullptr,
|
|
4618
|
+
nullptr,
|
|
4619
|
+
context,
|
|
4620
|
+
CallJsInternal,
|
|
4621
|
+
&tsfn._tsfn);
|
|
4622
|
+
if (status != napi_ok) {
|
|
4623
|
+
NAPI_THROW_IF_FAILED(
|
|
4624
|
+
env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
|
|
4625
|
+
}
|
|
4626
|
+
|
|
4627
|
+
return tsfn;
|
|
3759
4628
|
}
|
|
3760
4629
|
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
4630
|
+
// static, with Callback [passed] Resource [missing] Finalizer [passed]
|
|
4631
|
+
template <typename ContextType,
|
|
4632
|
+
typename DataType,
|
|
4633
|
+
void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
|
|
4634
|
+
template <typename ResourceString,
|
|
4635
|
+
typename Finalizer,
|
|
4636
|
+
typename FinalizerDataType>
|
|
4637
|
+
inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
|
|
4638
|
+
TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
|
|
4639
|
+
napi_env env,
|
|
4640
|
+
const Function& callback,
|
|
4641
|
+
ResourceString resourceName,
|
|
4642
|
+
size_t maxQueueSize,
|
|
4643
|
+
size_t initialThreadCount,
|
|
4644
|
+
ContextType* context,
|
|
4645
|
+
Finalizer finalizeCallback,
|
|
4646
|
+
FinalizerDataType* data) {
|
|
4647
|
+
TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
|
|
4648
|
+
|
|
4649
|
+
auto* finalizeData = new details::
|
|
4650
|
+
ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
|
|
4651
|
+
{data, finalizeCallback});
|
|
4652
|
+
napi_status status = napi_create_threadsafe_function(
|
|
4653
|
+
env,
|
|
4654
|
+
callback,
|
|
4655
|
+
nullptr,
|
|
4656
|
+
String::From(env, resourceName),
|
|
4657
|
+
maxQueueSize,
|
|
4658
|
+
initialThreadCount,
|
|
4659
|
+
finalizeData,
|
|
4660
|
+
details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
|
|
4661
|
+
FinalizeFinalizeWrapperWithDataAndContext,
|
|
4662
|
+
context,
|
|
4663
|
+
CallJsInternal,
|
|
4664
|
+
&tsfn._tsfn);
|
|
4665
|
+
if (status != napi_ok) {
|
|
4666
|
+
delete finalizeData;
|
|
4667
|
+
NAPI_THROW_IF_FAILED(
|
|
4668
|
+
env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
|
|
4669
|
+
}
|
|
3772
4670
|
|
|
3773
|
-
|
|
3774
|
-
OnWorkComplete, this, &_work);
|
|
3775
|
-
NAPI_THROW_IF_FAILED_VOID(_env, status);
|
|
4671
|
+
return tsfn;
|
|
3776
4672
|
}
|
|
3777
4673
|
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
|
|
4674
|
+
// static, with: Callback [passed] Resource [passed] Finalizer [passed]
|
|
4675
|
+
template <typename ContextType,
|
|
4676
|
+
typename DataType,
|
|
4677
|
+
void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
|
|
4678
|
+
template <typename CallbackType,
|
|
4679
|
+
typename ResourceString,
|
|
4680
|
+
typename Finalizer,
|
|
4681
|
+
typename FinalizerDataType>
|
|
4682
|
+
inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
|
|
4683
|
+
TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
|
|
4684
|
+
napi_env env,
|
|
4685
|
+
CallbackType callback,
|
|
4686
|
+
const Object& resource,
|
|
4687
|
+
ResourceString resourceName,
|
|
4688
|
+
size_t maxQueueSize,
|
|
4689
|
+
size_t initialThreadCount,
|
|
4690
|
+
ContextType* context,
|
|
4691
|
+
Finalizer finalizeCallback,
|
|
4692
|
+
FinalizerDataType* data) {
|
|
4693
|
+
TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
|
|
4694
|
+
|
|
4695
|
+
auto* finalizeData = new details::
|
|
4696
|
+
ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
|
|
4697
|
+
{data, finalizeCallback});
|
|
4698
|
+
napi_status status = napi_create_threadsafe_function(
|
|
4699
|
+
env,
|
|
4700
|
+
details::DefaultCallbackWrapper<
|
|
4701
|
+
CallbackType,
|
|
4702
|
+
TypedThreadSafeFunction<ContextType, DataType, CallJs>>(env,
|
|
4703
|
+
callback),
|
|
4704
|
+
resource,
|
|
4705
|
+
String::From(env, resourceName),
|
|
4706
|
+
maxQueueSize,
|
|
4707
|
+
initialThreadCount,
|
|
4708
|
+
finalizeData,
|
|
4709
|
+
details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
|
|
4710
|
+
FinalizeFinalizeWrapperWithDataAndContext,
|
|
4711
|
+
context,
|
|
4712
|
+
CallJsInternal,
|
|
4713
|
+
&tsfn._tsfn);
|
|
4714
|
+
if (status != napi_ok) {
|
|
4715
|
+
delete finalizeData;
|
|
4716
|
+
NAPI_THROW_IF_FAILED(
|
|
4717
|
+
env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
|
|
3782
4718
|
}
|
|
4719
|
+
|
|
4720
|
+
return tsfn;
|
|
3783
4721
|
}
|
|
3784
4722
|
|
|
3785
|
-
|
|
3786
|
-
|
|
4723
|
+
template <typename ContextType,
|
|
4724
|
+
typename DataType,
|
|
4725
|
+
void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
|
|
4726
|
+
inline TypedThreadSafeFunction<ContextType, DataType, CallJs>::
|
|
4727
|
+
TypedThreadSafeFunction()
|
|
4728
|
+
: _tsfn() {}
|
|
4729
|
+
|
|
4730
|
+
template <typename ContextType,
|
|
4731
|
+
typename DataType,
|
|
4732
|
+
void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
|
|
4733
|
+
inline TypedThreadSafeFunction<ContextType, DataType, CallJs>::
|
|
4734
|
+
TypedThreadSafeFunction(napi_threadsafe_function tsfn)
|
|
4735
|
+
: _tsfn(tsfn) {}
|
|
4736
|
+
|
|
4737
|
+
template <typename ContextType,
|
|
4738
|
+
typename DataType,
|
|
4739
|
+
void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
|
|
4740
|
+
inline TypedThreadSafeFunction<ContextType, DataType, CallJs>::
|
|
4741
|
+
operator napi_threadsafe_function() const {
|
|
4742
|
+
return _tsfn;
|
|
3787
4743
|
}
|
|
3788
4744
|
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
_error = std::move(other._error);
|
|
3797
|
-
_suppress_destruct = other._suppress_destruct;
|
|
4745
|
+
template <typename ContextType,
|
|
4746
|
+
typename DataType,
|
|
4747
|
+
void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
|
|
4748
|
+
inline napi_status
|
|
4749
|
+
TypedThreadSafeFunction<ContextType, DataType, CallJs>::BlockingCall(
|
|
4750
|
+
DataType* data) const {
|
|
4751
|
+
return napi_call_threadsafe_function(_tsfn, data, napi_tsfn_blocking);
|
|
3798
4752
|
}
|
|
3799
4753
|
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
_error = std::move(other._error);
|
|
3808
|
-
_suppress_destruct = other._suppress_destruct;
|
|
3809
|
-
return *this;
|
|
4754
|
+
template <typename ContextType,
|
|
4755
|
+
typename DataType,
|
|
4756
|
+
void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
|
|
4757
|
+
inline napi_status
|
|
4758
|
+
TypedThreadSafeFunction<ContextType, DataType, CallJs>::NonBlockingCall(
|
|
4759
|
+
DataType* data) const {
|
|
4760
|
+
return napi_call_threadsafe_function(_tsfn, data, napi_tsfn_nonblocking);
|
|
3810
4761
|
}
|
|
3811
4762
|
|
|
3812
|
-
|
|
3813
|
-
|
|
4763
|
+
template <typename ContextType,
|
|
4764
|
+
typename DataType,
|
|
4765
|
+
void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
|
|
4766
|
+
inline void TypedThreadSafeFunction<ContextType, DataType, CallJs>::Ref(
|
|
4767
|
+
napi_env env) const {
|
|
4768
|
+
if (_tsfn != nullptr) {
|
|
4769
|
+
napi_status status = napi_ref_threadsafe_function(env, _tsfn);
|
|
4770
|
+
NAPI_THROW_IF_FAILED_VOID(env, status);
|
|
4771
|
+
}
|
|
3814
4772
|
}
|
|
3815
4773
|
|
|
3816
|
-
|
|
3817
|
-
|
|
4774
|
+
template <typename ContextType,
|
|
4775
|
+
typename DataType,
|
|
4776
|
+
void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
|
|
4777
|
+
inline void TypedThreadSafeFunction<ContextType, DataType, CallJs>::Unref(
|
|
4778
|
+
napi_env env) const {
|
|
4779
|
+
if (_tsfn != nullptr) {
|
|
4780
|
+
napi_status status = napi_unref_threadsafe_function(env, _tsfn);
|
|
4781
|
+
NAPI_THROW_IF_FAILED_VOID(env, status);
|
|
4782
|
+
}
|
|
3818
4783
|
}
|
|
3819
4784
|
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
4785
|
+
template <typename ContextType,
|
|
4786
|
+
typename DataType,
|
|
4787
|
+
void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
|
|
4788
|
+
inline napi_status
|
|
4789
|
+
TypedThreadSafeFunction<ContextType, DataType, CallJs>::Acquire() const {
|
|
4790
|
+
return napi_acquire_threadsafe_function(_tsfn);
|
|
3823
4791
|
}
|
|
3824
4792
|
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
4793
|
+
template <typename ContextType,
|
|
4794
|
+
typename DataType,
|
|
4795
|
+
void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
|
|
4796
|
+
inline napi_status
|
|
4797
|
+
TypedThreadSafeFunction<ContextType, DataType, CallJs>::Release() {
|
|
4798
|
+
return napi_release_threadsafe_function(_tsfn, napi_tsfn_release);
|
|
3828
4799
|
}
|
|
3829
4800
|
|
|
3830
|
-
|
|
3831
|
-
|
|
4801
|
+
template <typename ContextType,
|
|
4802
|
+
typename DataType,
|
|
4803
|
+
void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
|
|
4804
|
+
inline napi_status
|
|
4805
|
+
TypedThreadSafeFunction<ContextType, DataType, CallJs>::Abort() {
|
|
4806
|
+
return napi_release_threadsafe_function(_tsfn, napi_tsfn_abort);
|
|
3832
4807
|
}
|
|
3833
4808
|
|
|
3834
|
-
|
|
3835
|
-
|
|
4809
|
+
template <typename ContextType,
|
|
4810
|
+
typename DataType,
|
|
4811
|
+
void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
|
|
4812
|
+
inline ContextType*
|
|
4813
|
+
TypedThreadSafeFunction<ContextType, DataType, CallJs>::GetContext() const {
|
|
4814
|
+
void* context;
|
|
4815
|
+
napi_status status = napi_get_threadsafe_function_context(_tsfn, &context);
|
|
4816
|
+
NAPI_FATAL_IF_FAILED(status,
|
|
4817
|
+
"TypedThreadSafeFunction::GetContext",
|
|
4818
|
+
"napi_get_threadsafe_function_context");
|
|
4819
|
+
return static_cast<ContextType*>(context);
|
|
3836
4820
|
}
|
|
3837
4821
|
|
|
3838
|
-
|
|
3839
|
-
|
|
4822
|
+
// static
|
|
4823
|
+
template <typename ContextType,
|
|
4824
|
+
typename DataType,
|
|
4825
|
+
void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
|
|
4826
|
+
void TypedThreadSafeFunction<ContextType, DataType, CallJs>::CallJsInternal(
|
|
4827
|
+
napi_env env, napi_value jsCallback, void* context, void* data) {
|
|
4828
|
+
details::CallJsWrapper<ContextType, DataType, decltype(CallJs), CallJs>(
|
|
4829
|
+
env, jsCallback, context, data);
|
|
3840
4830
|
}
|
|
3841
4831
|
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
4832
|
+
#if NAPI_VERSION == 4
|
|
4833
|
+
// static
|
|
4834
|
+
template <typename ContextType,
|
|
4835
|
+
typename DataType,
|
|
4836
|
+
void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
|
|
4837
|
+
Napi::Function
|
|
4838
|
+
TypedThreadSafeFunction<ContextType, DataType, CallJs>::EmptyFunctionFactory(
|
|
4839
|
+
Napi::Env env) {
|
|
4840
|
+
return Napi::Function::New(env, [](const CallbackInfo& cb) {});
|
|
3846
4841
|
}
|
|
3847
4842
|
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
4843
|
+
// static
|
|
4844
|
+
template <typename ContextType,
|
|
4845
|
+
typename DataType,
|
|
4846
|
+
void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
|
|
4847
|
+
Napi::Function
|
|
4848
|
+
TypedThreadSafeFunction<ContextType, DataType, CallJs>::FunctionOrEmpty(
|
|
4849
|
+
Napi::Env env, Napi::Function& callback) {
|
|
4850
|
+
if (callback.IsEmpty()) {
|
|
4851
|
+
return EmptyFunctionFactory(env);
|
|
3851
4852
|
}
|
|
4853
|
+
return callback;
|
|
3852
4854
|
}
|
|
3853
4855
|
|
|
3854
|
-
|
|
3855
|
-
|
|
4856
|
+
#else
|
|
4857
|
+
// static
|
|
4858
|
+
template <typename ContextType,
|
|
4859
|
+
typename DataType,
|
|
4860
|
+
void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
|
|
4861
|
+
std::nullptr_t
|
|
4862
|
+
TypedThreadSafeFunction<ContextType, DataType, CallJs>::EmptyFunctionFactory(
|
|
4863
|
+
Napi::Env /*env*/) {
|
|
4864
|
+
return nullptr;
|
|
3856
4865
|
}
|
|
3857
4866
|
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
AsyncWorker* self = static_cast<AsyncWorker*>(this_pointer);
|
|
3867
|
-
#ifdef NAPI_CPP_EXCEPTIONS
|
|
3868
|
-
try {
|
|
3869
|
-
self->Execute();
|
|
3870
|
-
} catch (const std::exception& e) {
|
|
3871
|
-
self->SetError(e.what());
|
|
3872
|
-
}
|
|
3873
|
-
#else // NAPI_CPP_EXCEPTIONS
|
|
3874
|
-
self->Execute();
|
|
3875
|
-
#endif // NAPI_CPP_EXCEPTIONS
|
|
4867
|
+
// static
|
|
4868
|
+
template <typename ContextType,
|
|
4869
|
+
typename DataType,
|
|
4870
|
+
void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
|
|
4871
|
+
Napi::Function
|
|
4872
|
+
TypedThreadSafeFunction<ContextType, DataType, CallJs>::FunctionOrEmpty(
|
|
4873
|
+
Napi::Env /*env*/, Napi::Function& callback) {
|
|
4874
|
+
return callback;
|
|
3876
4875
|
}
|
|
3877
4876
|
|
|
3878
|
-
|
|
3879
|
-
napi_env /*env*/, napi_status status, void* this_pointer) {
|
|
3880
|
-
AsyncWorker* self = static_cast<AsyncWorker*>(this_pointer);
|
|
3881
|
-
if (status != napi_cancelled) {
|
|
3882
|
-
HandleScope scope(self->_env);
|
|
3883
|
-
details::WrapCallback([&] {
|
|
3884
|
-
if (self->_error.size() == 0) {
|
|
3885
|
-
self->OnOK();
|
|
3886
|
-
}
|
|
3887
|
-
else {
|
|
3888
|
-
self->OnError(Error::New(self->_env, self->_error));
|
|
3889
|
-
}
|
|
3890
|
-
return nullptr;
|
|
3891
|
-
});
|
|
3892
|
-
}
|
|
3893
|
-
if (!self->_suppress_destruct) {
|
|
3894
|
-
self->Destroy();
|
|
3895
|
-
}
|
|
3896
|
-
}
|
|
4877
|
+
#endif
|
|
3897
4878
|
|
|
3898
|
-
#if (NAPI_VERSION > 3)
|
|
3899
4879
|
////////////////////////////////////////////////////////////////////////////////
|
|
3900
4880
|
// ThreadSafeFunction class
|
|
3901
4881
|
////////////////////////////////////////////////////////////////////////////////
|
|
@@ -4187,7 +5167,7 @@ inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
|
|
|
4187
5167
|
|
|
4188
5168
|
ThreadSafeFunction tsfn;
|
|
4189
5169
|
auto* finalizeData = new details::ThreadSafeFinalize<ContextType, Finalizer,
|
|
4190
|
-
FinalizerDataType>({ data, finalizeCallback
|
|
5170
|
+
FinalizerDataType>({ data, finalizeCallback });
|
|
4191
5171
|
napi_status status = napi_create_threadsafe_function(env, callback, resource,
|
|
4192
5172
|
Value::From(env, resourceName), maxQueueSize, initialThreadCount,
|
|
4193
5173
|
finalizeData, wrapper, context, CallJS, &tsfn._tsfn);
|
|
@@ -4230,9 +5210,90 @@ inline void ThreadSafeFunction::CallJS(napi_env env,
|
|
|
4230
5210
|
}
|
|
4231
5211
|
|
|
4232
5212
|
////////////////////////////////////////////////////////////////////////////////
|
|
4233
|
-
// Async Progress Worker class
|
|
5213
|
+
// Async Progress Worker Base class
|
|
4234
5214
|
////////////////////////////////////////////////////////////////////////////////
|
|
5215
|
+
template <typename DataType>
|
|
5216
|
+
inline AsyncProgressWorkerBase<DataType>::AsyncProgressWorkerBase(const Object& receiver,
|
|
5217
|
+
const Function& callback,
|
|
5218
|
+
const char* resource_name,
|
|
5219
|
+
const Object& resource,
|
|
5220
|
+
size_t queue_size)
|
|
5221
|
+
: AsyncWorker(receiver, callback, resource_name, resource) {
|
|
5222
|
+
// Fill all possible arguments to work around ambiguous ThreadSafeFunction::New signatures.
|
|
5223
|
+
_tsfn = ThreadSafeFunction::New(callback.Env(),
|
|
5224
|
+
callback,
|
|
5225
|
+
resource,
|
|
5226
|
+
resource_name,
|
|
5227
|
+
queue_size,
|
|
5228
|
+
/** initialThreadCount */ 1,
|
|
5229
|
+
/** context */ this,
|
|
5230
|
+
OnThreadSafeFunctionFinalize,
|
|
5231
|
+
/** finalizeData */ this);
|
|
5232
|
+
}
|
|
5233
|
+
|
|
5234
|
+
#if NAPI_VERSION > 4
|
|
5235
|
+
template <typename DataType>
|
|
5236
|
+
inline AsyncProgressWorkerBase<DataType>::AsyncProgressWorkerBase(Napi::Env env,
|
|
5237
|
+
const char* resource_name,
|
|
5238
|
+
const Object& resource,
|
|
5239
|
+
size_t queue_size)
|
|
5240
|
+
: AsyncWorker(env, resource_name, resource) {
|
|
5241
|
+
// TODO: Once the changes to make the callback optional for threadsafe
|
|
5242
|
+
// functions are available on all versions we can remove the dummy Function here.
|
|
5243
|
+
Function callback;
|
|
5244
|
+
// Fill all possible arguments to work around ambiguous ThreadSafeFunction::New signatures.
|
|
5245
|
+
_tsfn = ThreadSafeFunction::New(env,
|
|
5246
|
+
callback,
|
|
5247
|
+
resource,
|
|
5248
|
+
resource_name,
|
|
5249
|
+
queue_size,
|
|
5250
|
+
/** initialThreadCount */ 1,
|
|
5251
|
+
/** context */ this,
|
|
5252
|
+
OnThreadSafeFunctionFinalize,
|
|
5253
|
+
/** finalizeData */ this);
|
|
5254
|
+
}
|
|
5255
|
+
#endif
|
|
5256
|
+
|
|
5257
|
+
template<typename DataType>
|
|
5258
|
+
inline AsyncProgressWorkerBase<DataType>::~AsyncProgressWorkerBase() {
|
|
5259
|
+
// Abort pending tsfn call.
|
|
5260
|
+
// Don't send progress events after we've already completed.
|
|
5261
|
+
// It's ok to call ThreadSafeFunction::Abort and ThreadSafeFunction::Release duplicated.
|
|
5262
|
+
_tsfn.Abort();
|
|
5263
|
+
}
|
|
5264
|
+
|
|
5265
|
+
template <typename DataType>
|
|
5266
|
+
inline void AsyncProgressWorkerBase<DataType>::OnAsyncWorkProgress(Napi::Env /* env */,
|
|
5267
|
+
Napi::Function /* jsCallback */,
|
|
5268
|
+
void* data) {
|
|
5269
|
+
ThreadSafeData* tsd = static_cast<ThreadSafeData*>(data);
|
|
5270
|
+
tsd->asyncprogressworker()->OnWorkProgress(tsd->data());
|
|
5271
|
+
delete tsd;
|
|
5272
|
+
}
|
|
5273
|
+
|
|
5274
|
+
template <typename DataType>
|
|
5275
|
+
inline napi_status AsyncProgressWorkerBase<DataType>::NonBlockingCall(DataType* data) {
|
|
5276
|
+
auto tsd = new AsyncProgressWorkerBase::ThreadSafeData(this, data);
|
|
5277
|
+
return _tsfn.NonBlockingCall(tsd, OnAsyncWorkProgress);
|
|
5278
|
+
}
|
|
5279
|
+
|
|
5280
|
+
template <typename DataType>
|
|
5281
|
+
inline void AsyncProgressWorkerBase<DataType>::OnWorkComplete(Napi::Env /* env */, napi_status status) {
|
|
5282
|
+
_work_completed = true;
|
|
5283
|
+
_complete_status = status;
|
|
5284
|
+
_tsfn.Release();
|
|
5285
|
+
}
|
|
5286
|
+
|
|
5287
|
+
template <typename DataType>
|
|
5288
|
+
inline void AsyncProgressWorkerBase<DataType>::OnThreadSafeFunctionFinalize(Napi::Env env, void* /* data */, AsyncProgressWorkerBase* context) {
|
|
5289
|
+
if (context->_work_completed) {
|
|
5290
|
+
context->AsyncWorker::OnWorkComplete(env, context->_complete_status);
|
|
5291
|
+
}
|
|
5292
|
+
}
|
|
4235
5293
|
|
|
5294
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
5295
|
+
// Async Progress Worker class
|
|
5296
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
4236
5297
|
template<class T>
|
|
4237
5298
|
inline AsyncProgressWorker<T>::AsyncProgressWorker(const Function& callback)
|
|
4238
5299
|
: AsyncProgressWorker(callback, "generic") {
|
|
@@ -4256,14 +5317,14 @@ inline AsyncProgressWorker<T>::AsyncProgressWorker(const Function& callback,
|
|
|
4256
5317
|
|
|
4257
5318
|
template<class T>
|
|
4258
5319
|
inline AsyncProgressWorker<T>::AsyncProgressWorker(const Object& receiver,
|
|
4259
|
-
|
|
5320
|
+
const Function& callback)
|
|
4260
5321
|
: AsyncProgressWorker(receiver, callback, "generic") {
|
|
4261
5322
|
}
|
|
4262
5323
|
|
|
4263
5324
|
template<class T>
|
|
4264
5325
|
inline AsyncProgressWorker<T>::AsyncProgressWorker(const Object& receiver,
|
|
4265
|
-
|
|
4266
|
-
|
|
5326
|
+
const Function& callback,
|
|
5327
|
+
const char* resource_name)
|
|
4267
5328
|
: AsyncProgressWorker(receiver,
|
|
4268
5329
|
callback,
|
|
4269
5330
|
resource_name,
|
|
@@ -4275,10 +5336,9 @@ inline AsyncProgressWorker<T>::AsyncProgressWorker(const Object& receiver,
|
|
|
4275
5336
|
const Function& callback,
|
|
4276
5337
|
const char* resource_name,
|
|
4277
5338
|
const Object& resource)
|
|
4278
|
-
:
|
|
5339
|
+
: AsyncProgressWorkerBase(receiver, callback, resource_name, resource),
|
|
4279
5340
|
_asyncdata(nullptr),
|
|
4280
5341
|
_asyncsize(0) {
|
|
4281
|
-
_tsfn = ThreadSafeFunction::New(callback.Env(), callback, resource_name, 1, 1);
|
|
4282
5342
|
}
|
|
4283
5343
|
|
|
4284
5344
|
#if NAPI_VERSION > 4
|
|
@@ -4289,35 +5349,27 @@ inline AsyncProgressWorker<T>::AsyncProgressWorker(Napi::Env env)
|
|
|
4289
5349
|
|
|
4290
5350
|
template<class T>
|
|
4291
5351
|
inline AsyncProgressWorker<T>::AsyncProgressWorker(Napi::Env env,
|
|
4292
|
-
|
|
5352
|
+
const char* resource_name)
|
|
4293
5353
|
: AsyncProgressWorker(env, resource_name, Object::New(env)) {
|
|
4294
5354
|
}
|
|
4295
5355
|
|
|
4296
5356
|
template<class T>
|
|
4297
5357
|
inline AsyncProgressWorker<T>::AsyncProgressWorker(Napi::Env env,
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
:
|
|
5358
|
+
const char* resource_name,
|
|
5359
|
+
const Object& resource)
|
|
5360
|
+
: AsyncProgressWorkerBase(env, resource_name, resource),
|
|
4301
5361
|
_asyncdata(nullptr),
|
|
4302
5362
|
_asyncsize(0) {
|
|
4303
|
-
// TODO: Once the changes to make the callback optional for threadsafe
|
|
4304
|
-
// functions are no longer optional we can remove the dummy Function here.
|
|
4305
|
-
Function callback;
|
|
4306
|
-
_tsfn = ThreadSafeFunction::New(env, callback, resource_name, 1, 1);
|
|
4307
5363
|
}
|
|
4308
5364
|
#endif
|
|
4309
5365
|
|
|
4310
5366
|
template<class T>
|
|
4311
5367
|
inline AsyncProgressWorker<T>::~AsyncProgressWorker() {
|
|
4312
|
-
// Abort pending tsfn call.
|
|
4313
|
-
// Don't send progress events after we've already completed.
|
|
4314
|
-
_tsfn.Abort();
|
|
4315
5368
|
{
|
|
4316
|
-
std::lock_guard<std::mutex> lock(_mutex);
|
|
5369
|
+
std::lock_guard<std::mutex> lock(this->_mutex);
|
|
4317
5370
|
_asyncdata = nullptr;
|
|
4318
5371
|
_asyncsize = 0;
|
|
4319
5372
|
}
|
|
4320
|
-
_tsfn.Release();
|
|
4321
5373
|
}
|
|
4322
5374
|
|
|
4323
5375
|
template<class T>
|
|
@@ -4327,20 +5379,29 @@ inline void AsyncProgressWorker<T>::Execute() {
|
|
|
4327
5379
|
}
|
|
4328
5380
|
|
|
4329
5381
|
template<class T>
|
|
4330
|
-
inline void AsyncProgressWorker<T>::
|
|
4331
|
-
AsyncProgressWorker* self = static_cast<AsyncProgressWorker*>(_data);
|
|
4332
|
-
|
|
5382
|
+
inline void AsyncProgressWorker<T>::OnWorkProgress(void*) {
|
|
4333
5383
|
T* data;
|
|
4334
5384
|
size_t size;
|
|
4335
5385
|
{
|
|
4336
|
-
std::lock_guard<std::mutex> lock(
|
|
4337
|
-
data =
|
|
4338
|
-
size =
|
|
4339
|
-
|
|
4340
|
-
|
|
5386
|
+
std::lock_guard<std::mutex> lock(this->_mutex);
|
|
5387
|
+
data = this->_asyncdata;
|
|
5388
|
+
size = this->_asyncsize;
|
|
5389
|
+
this->_asyncdata = nullptr;
|
|
5390
|
+
this->_asyncsize = 0;
|
|
4341
5391
|
}
|
|
4342
5392
|
|
|
4343
|
-
|
|
5393
|
+
/**
|
|
5394
|
+
* The callback of ThreadSafeFunction is not been invoked immediately on the
|
|
5395
|
+
* callback of uv_async_t (uv io poll), rather the callback of TSFN is
|
|
5396
|
+
* invoked on the right next uv idle callback. There are chances that during
|
|
5397
|
+
* the deferring the signal of uv_async_t is been sent again, i.e. potential
|
|
5398
|
+
* not coalesced two calls of the TSFN callback.
|
|
5399
|
+
*/
|
|
5400
|
+
if (data == nullptr) {
|
|
5401
|
+
return;
|
|
5402
|
+
}
|
|
5403
|
+
|
|
5404
|
+
this->OnProgress(data, size);
|
|
4344
5405
|
delete[] data;
|
|
4345
5406
|
}
|
|
4346
5407
|
|
|
@@ -4351,19 +5412,19 @@ inline void AsyncProgressWorker<T>::SendProgress_(const T* data, size_t count) {
|
|
|
4351
5412
|
|
|
4352
5413
|
T* old_data;
|
|
4353
5414
|
{
|
|
4354
|
-
std::lock_guard<std::mutex> lock(_mutex);
|
|
5415
|
+
std::lock_guard<std::mutex> lock(this->_mutex);
|
|
4355
5416
|
old_data = _asyncdata;
|
|
4356
5417
|
_asyncdata = new_data;
|
|
4357
5418
|
_asyncsize = count;
|
|
4358
5419
|
}
|
|
4359
|
-
|
|
5420
|
+
this->NonBlockingCall(nullptr);
|
|
4360
5421
|
|
|
4361
5422
|
delete[] old_data;
|
|
4362
5423
|
}
|
|
4363
5424
|
|
|
4364
5425
|
template<class T>
|
|
4365
5426
|
inline void AsyncProgressWorker<T>::Signal() const {
|
|
4366
|
-
|
|
5427
|
+
this->NonBlockingCall(static_cast<T*>(nullptr));
|
|
4367
5428
|
}
|
|
4368
5429
|
|
|
4369
5430
|
template<class T>
|
|
@@ -4376,8 +5437,125 @@ inline void AsyncProgressWorker<T>::ExecutionProgress::Send(const T* data, size_
|
|
|
4376
5437
|
_worker->SendProgress_(data, count);
|
|
4377
5438
|
}
|
|
4378
5439
|
|
|
5440
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
5441
|
+
// Async Progress Queue Worker class
|
|
5442
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
5443
|
+
template<class T>
|
|
5444
|
+
inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(const Function& callback)
|
|
5445
|
+
: AsyncProgressQueueWorker(callback, "generic") {
|
|
5446
|
+
}
|
|
5447
|
+
|
|
5448
|
+
template<class T>
|
|
5449
|
+
inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(const Function& callback,
|
|
5450
|
+
const char* resource_name)
|
|
5451
|
+
: AsyncProgressQueueWorker(callback, resource_name, Object::New(callback.Env())) {
|
|
5452
|
+
}
|
|
5453
|
+
|
|
5454
|
+
template<class T>
|
|
5455
|
+
inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(const Function& callback,
|
|
5456
|
+
const char* resource_name,
|
|
5457
|
+
const Object& resource)
|
|
5458
|
+
: AsyncProgressQueueWorker(Object::New(callback.Env()),
|
|
5459
|
+
callback,
|
|
5460
|
+
resource_name,
|
|
5461
|
+
resource) {
|
|
5462
|
+
}
|
|
5463
|
+
|
|
5464
|
+
template<class T>
|
|
5465
|
+
inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(const Object& receiver,
|
|
5466
|
+
const Function& callback)
|
|
5467
|
+
: AsyncProgressQueueWorker(receiver, callback, "generic") {
|
|
5468
|
+
}
|
|
5469
|
+
|
|
5470
|
+
template<class T>
|
|
5471
|
+
inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(const Object& receiver,
|
|
5472
|
+
const Function& callback,
|
|
5473
|
+
const char* resource_name)
|
|
5474
|
+
: AsyncProgressQueueWorker(receiver,
|
|
5475
|
+
callback,
|
|
5476
|
+
resource_name,
|
|
5477
|
+
Object::New(callback.Env())) {
|
|
5478
|
+
}
|
|
5479
|
+
|
|
5480
|
+
template<class T>
|
|
5481
|
+
inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(const Object& receiver,
|
|
5482
|
+
const Function& callback,
|
|
5483
|
+
const char* resource_name,
|
|
5484
|
+
const Object& resource)
|
|
5485
|
+
: AsyncProgressWorkerBase<std::pair<T*, size_t>>(receiver, callback, resource_name, resource, /** unlimited queue size */0) {
|
|
5486
|
+
}
|
|
5487
|
+
|
|
5488
|
+
#if NAPI_VERSION > 4
|
|
5489
|
+
template<class T>
|
|
5490
|
+
inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(Napi::Env env)
|
|
5491
|
+
: AsyncProgressQueueWorker(env, "generic") {
|
|
5492
|
+
}
|
|
5493
|
+
|
|
5494
|
+
template<class T>
|
|
5495
|
+
inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(Napi::Env env,
|
|
5496
|
+
const char* resource_name)
|
|
5497
|
+
: AsyncProgressQueueWorker(env, resource_name, Object::New(env)) {
|
|
5498
|
+
}
|
|
5499
|
+
|
|
5500
|
+
template<class T>
|
|
5501
|
+
inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(Napi::Env env,
|
|
5502
|
+
const char* resource_name,
|
|
5503
|
+
const Object& resource)
|
|
5504
|
+
: AsyncProgressWorkerBase<std::pair<T*, size_t>>(env, resource_name, resource, /** unlimited queue size */0) {
|
|
5505
|
+
}
|
|
4379
5506
|
#endif
|
|
4380
5507
|
|
|
5508
|
+
template<class T>
|
|
5509
|
+
inline void AsyncProgressQueueWorker<T>::Execute() {
|
|
5510
|
+
ExecutionProgress progress(this);
|
|
5511
|
+
Execute(progress);
|
|
5512
|
+
}
|
|
5513
|
+
|
|
5514
|
+
template<class T>
|
|
5515
|
+
inline void AsyncProgressQueueWorker<T>::OnWorkProgress(std::pair<T*, size_t>* datapair) {
|
|
5516
|
+
if (datapair == nullptr) {
|
|
5517
|
+
return;
|
|
5518
|
+
}
|
|
5519
|
+
|
|
5520
|
+
T *data = datapair->first;
|
|
5521
|
+
size_t size = datapair->second;
|
|
5522
|
+
|
|
5523
|
+
this->OnProgress(data, size);
|
|
5524
|
+
delete datapair;
|
|
5525
|
+
delete[] data;
|
|
5526
|
+
}
|
|
5527
|
+
|
|
5528
|
+
template<class T>
|
|
5529
|
+
inline void AsyncProgressQueueWorker<T>::SendProgress_(const T* data, size_t count) {
|
|
5530
|
+
T* new_data = new T[count];
|
|
5531
|
+
std::copy(data, data + count, new_data);
|
|
5532
|
+
|
|
5533
|
+
auto pair = new std::pair<T*, size_t>(new_data, count);
|
|
5534
|
+
this->NonBlockingCall(pair);
|
|
5535
|
+
}
|
|
5536
|
+
|
|
5537
|
+
template<class T>
|
|
5538
|
+
inline void AsyncProgressQueueWorker<T>::Signal() const {
|
|
5539
|
+
this->NonBlockingCall(nullptr);
|
|
5540
|
+
}
|
|
5541
|
+
|
|
5542
|
+
template<class T>
|
|
5543
|
+
inline void AsyncProgressQueueWorker<T>::OnWorkComplete(Napi::Env env, napi_status status) {
|
|
5544
|
+
// Draining queued items in TSFN.
|
|
5545
|
+
AsyncProgressWorkerBase<std::pair<T*, size_t>>::OnWorkComplete(env, status);
|
|
5546
|
+
}
|
|
5547
|
+
|
|
5548
|
+
template<class T>
|
|
5549
|
+
inline void AsyncProgressQueueWorker<T>::ExecutionProgress::Signal() const {
|
|
5550
|
+
_worker->Signal();
|
|
5551
|
+
}
|
|
5552
|
+
|
|
5553
|
+
template<class T>
|
|
5554
|
+
inline void AsyncProgressQueueWorker<T>::ExecutionProgress::Send(const T* data, size_t count) const {
|
|
5555
|
+
_worker->SendProgress_(data, count);
|
|
5556
|
+
}
|
|
5557
|
+
#endif // NAPI_VERSION > 3 && !defined(__wasm32__)
|
|
5558
|
+
|
|
4381
5559
|
////////////////////////////////////////////////////////////////////////////////
|
|
4382
5560
|
// Memory Management class
|
|
4383
5561
|
////////////////////////////////////////////////////////////////////////////////
|
|
@@ -4407,6 +5585,49 @@ inline const napi_node_version* VersionManagement::GetNodeVersion(Env env) {
|
|
|
4407
5585
|
return result;
|
|
4408
5586
|
}
|
|
4409
5587
|
|
|
5588
|
+
#if NAPI_VERSION > 5
|
|
5589
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
5590
|
+
// Addon<T> class
|
|
5591
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
5592
|
+
|
|
5593
|
+
template <typename T>
|
|
5594
|
+
inline Object Addon<T>::Init(Env env, Object exports) {
|
|
5595
|
+
T* addon = new T(env, exports);
|
|
5596
|
+
env.SetInstanceData(addon);
|
|
5597
|
+
return addon->entry_point_;
|
|
5598
|
+
}
|
|
5599
|
+
|
|
5600
|
+
template <typename T>
|
|
5601
|
+
inline T* Addon<T>::Unwrap(Object wrapper) {
|
|
5602
|
+
return wrapper.Env().GetInstanceData<T>();
|
|
5603
|
+
}
|
|
5604
|
+
|
|
5605
|
+
template <typename T>
|
|
5606
|
+
inline void
|
|
5607
|
+
Addon<T>::DefineAddon(Object exports,
|
|
5608
|
+
const std::initializer_list<AddonProp>& props) {
|
|
5609
|
+
DefineProperties(exports, props);
|
|
5610
|
+
entry_point_ = exports;
|
|
5611
|
+
}
|
|
5612
|
+
|
|
5613
|
+
template <typename T>
|
|
5614
|
+
inline Napi::Object
|
|
5615
|
+
Addon<T>::DefineProperties(Object object,
|
|
5616
|
+
const std::initializer_list<AddonProp>& props) {
|
|
5617
|
+
const napi_property_descriptor* properties =
|
|
5618
|
+
reinterpret_cast<const napi_property_descriptor*>(props.begin());
|
|
5619
|
+
size_t size = props.size();
|
|
5620
|
+
napi_status status = napi_define_properties(object.Env(),
|
|
5621
|
+
object,
|
|
5622
|
+
size,
|
|
5623
|
+
properties);
|
|
5624
|
+
NAPI_THROW_IF_FAILED(object.Env(), status, object);
|
|
5625
|
+
for (size_t idx = 0; idx < size; idx++)
|
|
5626
|
+
T::AttachPropData(object.Env(), object, &properties[idx]);
|
|
5627
|
+
return object;
|
|
5628
|
+
}
|
|
5629
|
+
#endif // NAPI_VERSION > 5
|
|
5630
|
+
|
|
4410
5631
|
} // namespace Napi
|
|
4411
5632
|
|
|
4412
5633
|
#endif // SRC_NAPI_INL_H_
|