node-addon-api 8.1.0 → 8.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/napi-inl.h +325 -102
- package/napi.h +78 -24
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ and exception handling semantics with low overhead.
|
|
|
19
19
|
API references are available in the [doc](doc/README.md) directory.
|
|
20
20
|
|
|
21
21
|
<!-- x-release-please-start-version -->
|
|
22
|
-
## Current version: 8.1
|
|
22
|
+
## Current version: 8.2.1
|
|
23
23
|
<!-- x-release-please-end -->
|
|
24
24
|
|
|
25
25
|
(See [CHANGELOG.md](CHANGELOG.md) for complete Changelog)
|
package/napi-inl.h
CHANGED
|
@@ -34,25 +34,10 @@ namespace details {
|
|
|
34
34
|
// Node.js releases. Only necessary when they are used in napi.h and napi-inl.h.
|
|
35
35
|
constexpr int napi_no_external_buffers_allowed = 22;
|
|
36
36
|
|
|
37
|
-
#if (defined(NAPI_EXPERIMENTAL) && \
|
|
38
|
-
defined(NODE_API_EXPERIMENTAL_HAS_POST_FINALIZER))
|
|
39
|
-
template <napi_finalize finalizer>
|
|
40
|
-
inline void PostFinalizerWrapper(node_api_nogc_env nogc_env,
|
|
41
|
-
void* data,
|
|
42
|
-
void* hint) {
|
|
43
|
-
napi_status status = node_api_post_finalizer(nogc_env, finalizer, data, hint);
|
|
44
|
-
NAPI_FATAL_IF_FAILED(
|
|
45
|
-
status, "PostFinalizerWrapper", "node_api_post_finalizer failed");
|
|
46
|
-
}
|
|
47
|
-
#else
|
|
48
|
-
template <napi_finalize finalizer>
|
|
49
|
-
inline void PostFinalizerWrapper(napi_env env, void* data, void* hint) {
|
|
50
|
-
finalizer(env, data, hint);
|
|
51
|
-
}
|
|
52
|
-
#endif
|
|
53
|
-
|
|
54
37
|
template <typename FreeType>
|
|
55
|
-
inline void
|
|
38
|
+
inline void default_basic_finalizer(node_addon_api_basic_env /*env*/,
|
|
39
|
+
void* data,
|
|
40
|
+
void* /*hint*/) {
|
|
56
41
|
delete static_cast<FreeType*>(data);
|
|
57
42
|
}
|
|
58
43
|
|
|
@@ -60,8 +45,9 @@ inline void default_finalizer(napi_env /*env*/, void* data, void* /*hint*/) {
|
|
|
60
45
|
// garbage-collected.
|
|
61
46
|
// TODO: Replace this code with `napi_add_finalizer()` whenever it becomes
|
|
62
47
|
// available on all supported versions of Node.js.
|
|
63
|
-
template <
|
|
64
|
-
|
|
48
|
+
template <
|
|
49
|
+
typename FreeType,
|
|
50
|
+
node_addon_api_basic_finalize finalizer = default_basic_finalizer<FreeType>>
|
|
65
51
|
inline napi_status AttachData(napi_env env,
|
|
66
52
|
napi_value obj,
|
|
67
53
|
FreeType* data,
|
|
@@ -85,8 +71,7 @@ inline napi_status AttachData(napi_env env,
|
|
|
85
71
|
}
|
|
86
72
|
}
|
|
87
73
|
#else // NAPI_VERSION >= 5
|
|
88
|
-
status = napi_add_finalizer(
|
|
89
|
-
env, obj, data, details::PostFinalizerWrapper<finalizer>, hint, nullptr);
|
|
74
|
+
status = napi_add_finalizer(env, obj, data, finalizer, hint, nullptr);
|
|
90
75
|
#endif
|
|
91
76
|
return status;
|
|
92
77
|
}
|
|
@@ -206,23 +191,102 @@ napi_value TemplatedInstanceVoidCallback(napi_env env, napi_callback_info info)
|
|
|
206
191
|
|
|
207
192
|
template <typename T, typename Finalizer, typename Hint = void>
|
|
208
193
|
struct FinalizeData {
|
|
209
|
-
|
|
194
|
+
#ifdef NODE_API_EXPERIMENTAL_HAS_POST_FINALIZER
|
|
195
|
+
template <typename F = Finalizer,
|
|
196
|
+
typename = std::enable_if_t<
|
|
197
|
+
std::is_invocable_v<F, node_addon_api_basic_env, T*>>>
|
|
198
|
+
#endif
|
|
199
|
+
static inline void Wrapper(node_addon_api_basic_env env,
|
|
210
200
|
void* data,
|
|
211
201
|
void* finalizeHint) NAPI_NOEXCEPT {
|
|
212
202
|
WrapVoidCallback([&] {
|
|
213
203
|
FinalizeData* finalizeData = static_cast<FinalizeData*>(finalizeHint);
|
|
214
|
-
finalizeData->callback(
|
|
204
|
+
finalizeData->callback(env, static_cast<T*>(data));
|
|
205
|
+
delete finalizeData;
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
#ifdef NODE_API_EXPERIMENTAL_HAS_POST_FINALIZER
|
|
210
|
+
template <typename F = Finalizer,
|
|
211
|
+
typename = std::enable_if_t<
|
|
212
|
+
!std::is_invocable_v<F, node_addon_api_basic_env, T*>>,
|
|
213
|
+
typename = void>
|
|
214
|
+
static inline void Wrapper(node_addon_api_basic_env env,
|
|
215
|
+
void* data,
|
|
216
|
+
void* finalizeHint) NAPI_NOEXCEPT {
|
|
217
|
+
#ifdef NODE_ADDON_API_REQUIRE_BASIC_FINALIZERS
|
|
218
|
+
static_assert(false,
|
|
219
|
+
"NODE_ADDON_API_REQUIRE_BASIC_FINALIZERS defined: Finalizer "
|
|
220
|
+
"must be basic.");
|
|
221
|
+
#endif
|
|
222
|
+
napi_status status =
|
|
223
|
+
node_api_post_finalizer(env, WrapperGC, data, finalizeHint);
|
|
224
|
+
NAPI_FATAL_IF_FAILED(
|
|
225
|
+
status, "FinalizeData::Wrapper", "node_api_post_finalizer failed");
|
|
226
|
+
}
|
|
227
|
+
#endif
|
|
228
|
+
|
|
229
|
+
#ifdef NODE_API_EXPERIMENTAL_HAS_POST_FINALIZER
|
|
230
|
+
template <typename F = Finalizer,
|
|
231
|
+
typename = std::enable_if_t<
|
|
232
|
+
std::is_invocable_v<F, node_addon_api_basic_env, T*, Hint*>>>
|
|
233
|
+
#endif
|
|
234
|
+
static inline void WrapperWithHint(node_addon_api_basic_env env,
|
|
235
|
+
void* data,
|
|
236
|
+
void* finalizeHint) NAPI_NOEXCEPT {
|
|
237
|
+
WrapVoidCallback([&] {
|
|
238
|
+
FinalizeData* finalizeData = static_cast<FinalizeData*>(finalizeHint);
|
|
239
|
+
finalizeData->callback(env, static_cast<T*>(data), finalizeData->hint);
|
|
215
240
|
delete finalizeData;
|
|
216
241
|
});
|
|
217
242
|
}
|
|
218
243
|
|
|
219
|
-
|
|
244
|
+
#ifdef NODE_API_EXPERIMENTAL_HAS_POST_FINALIZER
|
|
245
|
+
template <typename F = Finalizer,
|
|
246
|
+
typename = std::enable_if_t<
|
|
247
|
+
!std::is_invocable_v<F, node_addon_api_basic_env, T*, Hint*>>,
|
|
248
|
+
typename = void>
|
|
249
|
+
static inline void WrapperWithHint(node_addon_api_basic_env env,
|
|
220
250
|
void* data,
|
|
221
251
|
void* finalizeHint) NAPI_NOEXCEPT {
|
|
252
|
+
#ifdef NODE_ADDON_API_REQUIRE_BASIC_FINALIZERS
|
|
253
|
+
static_assert(false,
|
|
254
|
+
"NODE_ADDON_API_REQUIRE_BASIC_FINALIZERS defined: Finalizer "
|
|
255
|
+
"must be basic.");
|
|
256
|
+
#endif
|
|
257
|
+
napi_status status =
|
|
258
|
+
node_api_post_finalizer(env, WrapperGCWithHint, data, finalizeHint);
|
|
259
|
+
NAPI_FATAL_IF_FAILED(
|
|
260
|
+
status, "FinalizeData::Wrapper", "node_api_post_finalizer failed");
|
|
261
|
+
}
|
|
262
|
+
#endif
|
|
263
|
+
|
|
264
|
+
static inline void WrapperGCWithoutData(napi_env env,
|
|
265
|
+
void* /*data*/,
|
|
266
|
+
void* finalizeHint) NAPI_NOEXCEPT {
|
|
267
|
+
WrapVoidCallback([&] {
|
|
268
|
+
FinalizeData* finalizeData = static_cast<FinalizeData*>(finalizeHint);
|
|
269
|
+
finalizeData->callback(env);
|
|
270
|
+
delete finalizeData;
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
static inline void WrapperGC(napi_env env,
|
|
275
|
+
void* data,
|
|
276
|
+
void* finalizeHint) NAPI_NOEXCEPT {
|
|
277
|
+
WrapVoidCallback([&] {
|
|
278
|
+
FinalizeData* finalizeData = static_cast<FinalizeData*>(finalizeHint);
|
|
279
|
+
finalizeData->callback(env, static_cast<T*>(data));
|
|
280
|
+
delete finalizeData;
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
static inline void WrapperGCWithHint(napi_env env,
|
|
285
|
+
void* data,
|
|
286
|
+
void* finalizeHint) NAPI_NOEXCEPT {
|
|
222
287
|
WrapVoidCallback([&] {
|
|
223
288
|
FinalizeData* finalizeData = static_cast<FinalizeData*>(finalizeHint);
|
|
224
|
-
finalizeData->callback(
|
|
225
|
-
Env(env), static_cast<T*>(data), finalizeData->hint);
|
|
289
|
+
finalizeData->callback(env, static_cast<T*>(data), finalizeData->hint);
|
|
226
290
|
delete finalizeData;
|
|
227
291
|
});
|
|
228
292
|
}
|
|
@@ -373,6 +437,34 @@ inline std::string StringFormat(const char* format, ...) {
|
|
|
373
437
|
return result;
|
|
374
438
|
}
|
|
375
439
|
|
|
440
|
+
template <typename T>
|
|
441
|
+
class HasExtendedFinalizer {
|
|
442
|
+
private:
|
|
443
|
+
template <typename U, void (U::*)(Napi::Env)>
|
|
444
|
+
struct SFINAE {};
|
|
445
|
+
template <typename U>
|
|
446
|
+
static char test(SFINAE<U, &U::Finalize>*);
|
|
447
|
+
template <typename U>
|
|
448
|
+
static int test(...);
|
|
449
|
+
|
|
450
|
+
public:
|
|
451
|
+
static constexpr bool value = sizeof(test<T>(0)) == sizeof(char);
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
template <typename T>
|
|
455
|
+
class HasBasicFinalizer {
|
|
456
|
+
private:
|
|
457
|
+
template <typename U, void (U::*)(Napi::BasicEnv)>
|
|
458
|
+
struct SFINAE {};
|
|
459
|
+
template <typename U>
|
|
460
|
+
static char test(SFINAE<U, &U::Finalize>*);
|
|
461
|
+
template <typename U>
|
|
462
|
+
static int test(...);
|
|
463
|
+
|
|
464
|
+
public:
|
|
465
|
+
static constexpr bool value = sizeof(test<T>(0)) == sizeof(char);
|
|
466
|
+
};
|
|
467
|
+
|
|
376
468
|
} // namespace details
|
|
377
469
|
|
|
378
470
|
#ifndef NODE_ADDON_API_DISABLE_DEPRECATED
|
|
@@ -482,15 +574,21 @@ inline Maybe<T> Just(const T& t) {
|
|
|
482
574
|
}
|
|
483
575
|
|
|
484
576
|
////////////////////////////////////////////////////////////////////////////////
|
|
485
|
-
// Env class
|
|
577
|
+
// BasicEnv / Env class
|
|
486
578
|
////////////////////////////////////////////////////////////////////////////////
|
|
487
579
|
|
|
488
|
-
inline
|
|
580
|
+
inline BasicEnv::BasicEnv(node_addon_api_basic_env env) : _env(env) {}
|
|
489
581
|
|
|
490
|
-
inline
|
|
582
|
+
inline BasicEnv::operator node_addon_api_basic_env() const {
|
|
491
583
|
return _env;
|
|
492
584
|
}
|
|
493
585
|
|
|
586
|
+
inline Env::Env(napi_env env) : BasicEnv(env) {}
|
|
587
|
+
|
|
588
|
+
inline Env::operator napi_env() const {
|
|
589
|
+
return const_cast<napi_env>(_env);
|
|
590
|
+
}
|
|
591
|
+
|
|
494
592
|
inline Object Env::Global() const {
|
|
495
593
|
napi_value value;
|
|
496
594
|
napi_status status = napi_get_global(*this, &value);
|
|
@@ -514,7 +612,7 @@ inline Value Env::Null() const {
|
|
|
514
612
|
|
|
515
613
|
inline bool Env::IsExceptionPending() const {
|
|
516
614
|
bool result;
|
|
517
|
-
napi_status status = napi_is_exception_pending(
|
|
615
|
+
napi_status status = napi_is_exception_pending(*this, &result);
|
|
518
616
|
if (status != napi_ok)
|
|
519
617
|
result = false; // Checking for a pending exception shouldn't throw.
|
|
520
618
|
return result;
|
|
@@ -522,16 +620,16 @@ inline bool Env::IsExceptionPending() const {
|
|
|
522
620
|
|
|
523
621
|
inline Error Env::GetAndClearPendingException() const {
|
|
524
622
|
napi_value value;
|
|
525
|
-
napi_status status = napi_get_and_clear_last_exception(
|
|
623
|
+
napi_status status = napi_get_and_clear_last_exception(*this, &value);
|
|
526
624
|
if (status != napi_ok) {
|
|
527
625
|
// Don't throw another exception when failing to get the exception!
|
|
528
626
|
return Error();
|
|
529
627
|
}
|
|
530
|
-
return Error(
|
|
628
|
+
return Error(*this, value);
|
|
531
629
|
}
|
|
532
630
|
|
|
533
631
|
inline MaybeOrValue<Value> Env::RunScript(const char* utf8script) const {
|
|
534
|
-
String script = String::New(
|
|
632
|
+
String script = String::New(*this, utf8script);
|
|
535
633
|
return RunScript(script);
|
|
536
634
|
}
|
|
537
635
|
|
|
@@ -541,46 +639,46 @@ inline MaybeOrValue<Value> Env::RunScript(const std::string& utf8script) const {
|
|
|
541
639
|
|
|
542
640
|
inline MaybeOrValue<Value> Env::RunScript(String script) const {
|
|
543
641
|
napi_value result;
|
|
544
|
-
napi_status status = napi_run_script(
|
|
642
|
+
napi_status status = napi_run_script(*this, script, &result);
|
|
545
643
|
NAPI_RETURN_OR_THROW_IF_FAILED(
|
|
546
|
-
|
|
644
|
+
*this, status, Napi::Value(*this, result), Napi::Value);
|
|
547
645
|
}
|
|
548
646
|
|
|
549
647
|
#if NAPI_VERSION > 2
|
|
550
648
|
template <typename Hook, typename Arg>
|
|
551
|
-
void
|
|
552
|
-
auto* cleanupData =
|
|
553
|
-
|
|
554
|
-
data);
|
|
649
|
+
void BasicEnv::CleanupHook<Hook, Arg>::Wrapper(void* data) NAPI_NOEXCEPT {
|
|
650
|
+
auto* cleanupData = static_cast<
|
|
651
|
+
typename Napi::BasicEnv::CleanupHook<Hook, Arg>::CleanupData*>(data);
|
|
555
652
|
cleanupData->hook();
|
|
556
653
|
delete cleanupData;
|
|
557
654
|
}
|
|
558
655
|
|
|
559
656
|
template <typename Hook, typename Arg>
|
|
560
|
-
void
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
657
|
+
void BasicEnv::CleanupHook<Hook, Arg>::WrapperWithArg(void* data)
|
|
658
|
+
NAPI_NOEXCEPT {
|
|
659
|
+
auto* cleanupData = static_cast<
|
|
660
|
+
typename Napi::BasicEnv::CleanupHook<Hook, Arg>::CleanupData*>(data);
|
|
564
661
|
cleanupData->hook(static_cast<Arg*>(cleanupData->arg));
|
|
565
662
|
delete cleanupData;
|
|
566
663
|
}
|
|
567
664
|
#endif // NAPI_VERSION > 2
|
|
568
665
|
|
|
569
666
|
#if NAPI_VERSION > 5
|
|
570
|
-
template <typename T,
|
|
571
|
-
inline void
|
|
667
|
+
template <typename T, BasicEnv::Finalizer<T> fini>
|
|
668
|
+
inline void BasicEnv::SetInstanceData(T* data) const {
|
|
572
669
|
napi_status status = napi_set_instance_data(
|
|
573
670
|
_env,
|
|
574
671
|
data,
|
|
575
672
|
[](napi_env env, void* data, void*) { fini(env, static_cast<T*>(data)); },
|
|
576
673
|
nullptr);
|
|
577
|
-
|
|
674
|
+
NAPI_FATAL_IF_FAILED(
|
|
675
|
+
status, "BasicEnv::SetInstanceData", "invalid arguments");
|
|
578
676
|
}
|
|
579
677
|
|
|
580
678
|
template <typename DataType,
|
|
581
679
|
typename HintType,
|
|
582
|
-
Napi::
|
|
583
|
-
inline void
|
|
680
|
+
Napi::BasicEnv::FinalizerWithHint<DataType, HintType> fini>
|
|
681
|
+
inline void BasicEnv::SetInstanceData(DataType* data, HintType* hint) const {
|
|
584
682
|
napi_status status = napi_set_instance_data(
|
|
585
683
|
_env,
|
|
586
684
|
data,
|
|
@@ -588,35 +686,38 @@ inline void Env::SetInstanceData(DataType* data, HintType* hint) const {
|
|
|
588
686
|
fini(env, static_cast<DataType*>(data), static_cast<HintType*>(hint));
|
|
589
687
|
},
|
|
590
688
|
hint);
|
|
591
|
-
|
|
689
|
+
NAPI_FATAL_IF_FAILED(
|
|
690
|
+
status, "BasicEnv::SetInstanceData", "invalid arguments");
|
|
592
691
|
}
|
|
593
692
|
|
|
594
693
|
template <typename T>
|
|
595
|
-
inline T*
|
|
694
|
+
inline T* BasicEnv::GetInstanceData() const {
|
|
596
695
|
void* data = nullptr;
|
|
597
696
|
|
|
598
697
|
napi_status status = napi_get_instance_data(_env, &data);
|
|
599
|
-
|
|
698
|
+
NAPI_FATAL_IF_FAILED(
|
|
699
|
+
status, "BasicEnv::GetInstanceData", "invalid arguments");
|
|
600
700
|
|
|
601
701
|
return static_cast<T*>(data);
|
|
602
702
|
}
|
|
603
703
|
|
|
604
704
|
template <typename T>
|
|
605
|
-
void
|
|
705
|
+
void BasicEnv::DefaultFini(Env, T* data) {
|
|
606
706
|
delete data;
|
|
607
707
|
}
|
|
608
708
|
|
|
609
709
|
template <typename DataType, typename HintType>
|
|
610
|
-
void
|
|
710
|
+
void BasicEnv::DefaultFiniWithHint(Env, DataType* data, HintType*) {
|
|
611
711
|
delete data;
|
|
612
712
|
}
|
|
613
713
|
#endif // NAPI_VERSION > 5
|
|
614
714
|
|
|
615
715
|
#if NAPI_VERSION > 8
|
|
616
|
-
inline const char*
|
|
716
|
+
inline const char* BasicEnv::GetModuleFileName() const {
|
|
617
717
|
const char* result;
|
|
618
718
|
napi_status status = node_api_get_module_file_name(_env, &result);
|
|
619
|
-
|
|
719
|
+
NAPI_FATAL_IF_FAILED(
|
|
720
|
+
status, "BasicEnv::GetModuleFileName", "invalid arguments");
|
|
620
721
|
return result;
|
|
621
722
|
}
|
|
622
723
|
#endif // NAPI_VERSION > 8
|
|
@@ -796,6 +897,16 @@ inline T Value::As() const {
|
|
|
796
897
|
return T(_env, _value);
|
|
797
898
|
}
|
|
798
899
|
|
|
900
|
+
template <typename T>
|
|
901
|
+
inline T Value::UnsafeAs() const {
|
|
902
|
+
return T(_env, _value);
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
// static
|
|
906
|
+
inline void Value::CheckCast(napi_env /* env */, napi_value value) {
|
|
907
|
+
NAPI_CHECK(value != nullptr, "Value::CheckCast", "empty value");
|
|
908
|
+
}
|
|
909
|
+
|
|
799
910
|
inline MaybeOrValue<Boolean> Value::ToBoolean() const {
|
|
800
911
|
napi_value result;
|
|
801
912
|
napi_status status = napi_coerce_to_bool(_env, _value, &result);
|
|
@@ -1203,12 +1314,15 @@ inline Symbol Symbol::New(napi_env env, napi_value description) {
|
|
|
1203
1314
|
|
|
1204
1315
|
inline MaybeOrValue<Symbol> Symbol::WellKnown(napi_env env,
|
|
1205
1316
|
const std::string& name) {
|
|
1317
|
+
// No need to check if the return value is a symbol or undefined.
|
|
1318
|
+
// Well known symbols are definite and it is an develop time error
|
|
1319
|
+
// if the symbol does not exist.
|
|
1206
1320
|
#if defined(NODE_ADDON_API_ENABLE_MAYBE)
|
|
1207
1321
|
Value symbol_obj;
|
|
1208
1322
|
Value symbol_value;
|
|
1209
1323
|
if (Napi::Env(env).Global().Get("Symbol").UnwrapTo(&symbol_obj) &&
|
|
1210
1324
|
symbol_obj.As<Object>().Get(name).UnwrapTo(&symbol_value)) {
|
|
1211
|
-
return Just<Symbol>(symbol_value.
|
|
1325
|
+
return Just<Symbol>(symbol_value.UnsafeAs<Symbol>());
|
|
1212
1326
|
}
|
|
1213
1327
|
return Nothing<Symbol>();
|
|
1214
1328
|
#else
|
|
@@ -1217,7 +1331,7 @@ inline MaybeOrValue<Symbol> Symbol::WellKnown(napi_env env,
|
|
|
1217
1331
|
.Get("Symbol")
|
|
1218
1332
|
.As<Object>()
|
|
1219
1333
|
.Get(name)
|
|
1220
|
-
.
|
|
1334
|
+
.UnsafeAs<Symbol>();
|
|
1221
1335
|
#endif
|
|
1222
1336
|
}
|
|
1223
1337
|
|
|
@@ -1435,7 +1549,10 @@ inline void Object::CheckCast(napi_env env, napi_value value) {
|
|
|
1435
1549
|
napi_valuetype type;
|
|
1436
1550
|
napi_status status = napi_typeof(env, value, &type);
|
|
1437
1551
|
NAPI_CHECK(status == napi_ok, "Object::CheckCast", "napi_typeof failed");
|
|
1438
|
-
|
|
1552
|
+
NAPI_INTERNAL_CHECK(type == napi_object || type == napi_function,
|
|
1553
|
+
"Object::CheckCast",
|
|
1554
|
+
"Expect napi_object or napi_function, but got %d.",
|
|
1555
|
+
type);
|
|
1439
1556
|
}
|
|
1440
1557
|
|
|
1441
1558
|
inline Object::Object() : TypeTaggable() {}
|
|
@@ -1805,8 +1922,7 @@ inline External<T> External<T>::New(napi_env env,
|
|
|
1805
1922
|
napi_status status =
|
|
1806
1923
|
napi_create_external(env,
|
|
1807
1924
|
data,
|
|
1808
|
-
details::
|
|
1809
|
-
details::FinalizeData<T, Finalizer>::Wrapper>,
|
|
1925
|
+
details::FinalizeData<T, Finalizer>::Wrapper,
|
|
1810
1926
|
finalizeData,
|
|
1811
1927
|
&value);
|
|
1812
1928
|
if (status != napi_ok) {
|
|
@@ -1829,8 +1945,7 @@ inline External<T> External<T>::New(napi_env env,
|
|
|
1829
1945
|
napi_status status = napi_create_external(
|
|
1830
1946
|
env,
|
|
1831
1947
|
data,
|
|
1832
|
-
details::
|
|
1833
|
-
details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint>,
|
|
1948
|
+
details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint,
|
|
1834
1949
|
finalizeData,
|
|
1835
1950
|
&value);
|
|
1836
1951
|
if (status != napi_ok) {
|
|
@@ -1941,8 +2056,7 @@ inline ArrayBuffer ArrayBuffer::New(napi_env env,
|
|
|
1941
2056
|
env,
|
|
1942
2057
|
externalData,
|
|
1943
2058
|
byteLength,
|
|
1944
|
-
details::
|
|
1945
|
-
details::FinalizeData<void, Finalizer>::Wrapper>,
|
|
2059
|
+
details::FinalizeData<void, Finalizer>::Wrapper,
|
|
1946
2060
|
finalizeData,
|
|
1947
2061
|
&value);
|
|
1948
2062
|
if (status != napi_ok) {
|
|
@@ -1967,8 +2081,7 @@ inline ArrayBuffer ArrayBuffer::New(napi_env env,
|
|
|
1967
2081
|
env,
|
|
1968
2082
|
externalData,
|
|
1969
2083
|
byteLength,
|
|
1970
|
-
details::
|
|
1971
|
-
details::FinalizeData<void, Finalizer, Hint>::WrapperWithHint>,
|
|
2084
|
+
details::FinalizeData<void, Finalizer, Hint>::WrapperWithHint,
|
|
1972
2085
|
finalizeData,
|
|
1973
2086
|
&value);
|
|
1974
2087
|
if (status != napi_ok) {
|
|
@@ -2684,14 +2797,13 @@ inline Buffer<T> Buffer<T>::New(napi_env env,
|
|
|
2684
2797
|
details::FinalizeData<T, Finalizer>* finalizeData =
|
|
2685
2798
|
new details::FinalizeData<T, Finalizer>(
|
|
2686
2799
|
{std::move(finalizeCallback), nullptr});
|
|
2687
|
-
napi_status status =
|
|
2688
|
-
env,
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
&value);
|
|
2800
|
+
napi_status status =
|
|
2801
|
+
napi_create_external_buffer(env,
|
|
2802
|
+
length * sizeof(T),
|
|
2803
|
+
data,
|
|
2804
|
+
details::FinalizeData<T, Finalizer>::Wrapper,
|
|
2805
|
+
finalizeData,
|
|
2806
|
+
&value);
|
|
2695
2807
|
if (status != napi_ok) {
|
|
2696
2808
|
delete finalizeData;
|
|
2697
2809
|
NAPI_THROW_IF_FAILED(env, status, Buffer());
|
|
@@ -2714,8 +2826,7 @@ inline Buffer<T> Buffer<T>::New(napi_env env,
|
|
|
2714
2826
|
env,
|
|
2715
2827
|
length * sizeof(T),
|
|
2716
2828
|
data,
|
|
2717
|
-
details::
|
|
2718
|
-
details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint>,
|
|
2829
|
+
details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint,
|
|
2719
2830
|
finalizeData,
|
|
2720
2831
|
&value);
|
|
2721
2832
|
if (status != napi_ok) {
|
|
@@ -2754,19 +2865,18 @@ inline Buffer<T> Buffer<T>::NewOrCopy(napi_env env,
|
|
|
2754
2865
|
{std::move(finalizeCallback), nullptr});
|
|
2755
2866
|
#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
|
|
2756
2867
|
napi_value value;
|
|
2757
|
-
napi_status status =
|
|
2758
|
-
env,
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
&value);
|
|
2868
|
+
napi_status status =
|
|
2869
|
+
napi_create_external_buffer(env,
|
|
2870
|
+
length * sizeof(T),
|
|
2871
|
+
data,
|
|
2872
|
+
details::FinalizeData<T, Finalizer>::Wrapper,
|
|
2873
|
+
finalizeData,
|
|
2874
|
+
&value);
|
|
2765
2875
|
if (status == details::napi_no_external_buffers_allowed) {
|
|
2766
2876
|
#endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
|
|
2767
2877
|
// If we can't create an external buffer, we'll just copy the data.
|
|
2768
2878
|
Buffer<T> ret = Buffer<T>::Copy(env, data, length);
|
|
2769
|
-
details::FinalizeData<T, Finalizer>::
|
|
2879
|
+
details::FinalizeData<T, Finalizer>::WrapperGC(env, data, finalizeData);
|
|
2770
2880
|
return ret;
|
|
2771
2881
|
#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
|
|
2772
2882
|
}
|
|
@@ -2794,15 +2904,14 @@ inline Buffer<T> Buffer<T>::NewOrCopy(napi_env env,
|
|
|
2794
2904
|
env,
|
|
2795
2905
|
length * sizeof(T),
|
|
2796
2906
|
data,
|
|
2797
|
-
details::
|
|
2798
|
-
details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint>,
|
|
2907
|
+
details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint,
|
|
2799
2908
|
finalizeData,
|
|
2800
2909
|
&value);
|
|
2801
2910
|
if (status == details::napi_no_external_buffers_allowed) {
|
|
2802
2911
|
#endif
|
|
2803
2912
|
// If we can't create an external buffer, we'll just copy the data.
|
|
2804
2913
|
Buffer<T> ret = Buffer<T>::Copy(env, data, length);
|
|
2805
|
-
details::FinalizeData<T, Finalizer, Hint>::
|
|
2914
|
+
details::FinalizeData<T, Finalizer, Hint>::WrapperGCWithHint(
|
|
2806
2915
|
env, data, finalizeData);
|
|
2807
2916
|
return ret;
|
|
2808
2917
|
#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
|
|
@@ -3232,7 +3341,13 @@ template <typename T>
|
|
|
3232
3341
|
inline Reference<T>::~Reference() {
|
|
3233
3342
|
if (_ref != nullptr) {
|
|
3234
3343
|
if (!_suppressDestruct) {
|
|
3344
|
+
#ifdef NODE_API_EXPERIMENTAL_HAS_POST_FINALIZER
|
|
3345
|
+
Env().PostFinalizer(
|
|
3346
|
+
[](Napi::Env env, napi_ref ref) { napi_delete_reference(env, ref); },
|
|
3347
|
+
_ref);
|
|
3348
|
+
#else
|
|
3235
3349
|
napi_delete_reference(_env, _ref);
|
|
3350
|
+
#endif
|
|
3236
3351
|
}
|
|
3237
3352
|
|
|
3238
3353
|
_ref = nullptr;
|
|
@@ -4469,12 +4584,7 @@ inline ObjectWrap<T>::ObjectWrap(const Napi::CallbackInfo& callbackInfo) {
|
|
|
4469
4584
|
napi_status status;
|
|
4470
4585
|
napi_ref ref;
|
|
4471
4586
|
T* instance = static_cast<T*>(this);
|
|
4472
|
-
status = napi_wrap(env,
|
|
4473
|
-
wrapper,
|
|
4474
|
-
instance,
|
|
4475
|
-
details::PostFinalizerWrapper<FinalizeCallback>,
|
|
4476
|
-
nullptr,
|
|
4477
|
-
&ref);
|
|
4587
|
+
status = napi_wrap(env, wrapper, instance, FinalizeCallback, nullptr, &ref);
|
|
4478
4588
|
NAPI_THROW_IF_FAILED_VOID(env, status);
|
|
4479
4589
|
|
|
4480
4590
|
Reference<Object>* instanceRef = instance;
|
|
@@ -4837,6 +4947,9 @@ inline Value ObjectWrap<T>::OnCalledAsFunction(
|
|
|
4837
4947
|
template <typename T>
|
|
4838
4948
|
inline void ObjectWrap<T>::Finalize(Napi::Env /*env*/) {}
|
|
4839
4949
|
|
|
4950
|
+
template <typename T>
|
|
4951
|
+
inline void ObjectWrap<T>::Finalize(BasicEnv /*env*/) {}
|
|
4952
|
+
|
|
4840
4953
|
template <typename T>
|
|
4841
4954
|
inline napi_value ObjectWrap<T>::ConstructorCallbackWrapper(
|
|
4842
4955
|
napi_env env, napi_callback_info info) {
|
|
@@ -4922,10 +5035,59 @@ inline napi_value ObjectWrap<T>::StaticSetterCallbackWrapper(
|
|
|
4922
5035
|
}
|
|
4923
5036
|
|
|
4924
5037
|
template <typename T>
|
|
4925
|
-
inline void ObjectWrap<T>::FinalizeCallback(
|
|
5038
|
+
inline void ObjectWrap<T>::FinalizeCallback(node_addon_api_basic_env env,
|
|
4926
5039
|
void* data,
|
|
4927
5040
|
void* /*hint*/) {
|
|
4928
|
-
|
|
5041
|
+
// If the child class does not override _any_ Finalize() method, `env` will be
|
|
5042
|
+
// unused because of the constexpr guards. Explicitly reference it here to
|
|
5043
|
+
// bypass compiler warnings.
|
|
5044
|
+
(void)env;
|
|
5045
|
+
T* instance = static_cast<T*>(data);
|
|
5046
|
+
|
|
5047
|
+
// Prevent ~ObjectWrap from calling napi_remove_wrap
|
|
5048
|
+
instance->_ref = nullptr;
|
|
5049
|
+
|
|
5050
|
+
// If class overrides the basic finalizer, execute it.
|
|
5051
|
+
if constexpr (details::HasBasicFinalizer<T>::value) {
|
|
5052
|
+
#ifndef NODE_API_EXPERIMENTAL_HAS_POST_FINALIZER
|
|
5053
|
+
HandleScope scope(env);
|
|
5054
|
+
#endif
|
|
5055
|
+
|
|
5056
|
+
instance->Finalize(Napi::BasicEnv(env));
|
|
5057
|
+
}
|
|
5058
|
+
|
|
5059
|
+
// If class overrides the (extended) finalizer, either schedule it or
|
|
5060
|
+
// execute it immediately (depending on experimental features enabled).
|
|
5061
|
+
if constexpr (details::HasExtendedFinalizer<T>::value) {
|
|
5062
|
+
#ifdef NODE_API_EXPERIMENTAL_HAS_POST_FINALIZER
|
|
5063
|
+
// In experimental, attach via node_api_post_finalizer.
|
|
5064
|
+
// `PostFinalizeCallback` is responsible for deleting the `T* instance`,
|
|
5065
|
+
// after calling the user-provided finalizer.
|
|
5066
|
+
napi_status status =
|
|
5067
|
+
node_api_post_finalizer(env, PostFinalizeCallback, data, nullptr);
|
|
5068
|
+
NAPI_FATAL_IF_FAILED(status,
|
|
5069
|
+
"ObjectWrap<T>::FinalizeCallback",
|
|
5070
|
+
"node_api_post_finalizer failed");
|
|
5071
|
+
#else
|
|
5072
|
+
// In non-experimental, this `FinalizeCallback` already executes from a
|
|
5073
|
+
// non-basic environment. Execute the override directly.
|
|
5074
|
+
// `PostFinalizeCallback` is responsible for deleting the `T* instance`,
|
|
5075
|
+
// after calling the user-provided finalizer.
|
|
5076
|
+
HandleScope scope(env);
|
|
5077
|
+
PostFinalizeCallback(env, data, static_cast<void*>(nullptr));
|
|
5078
|
+
#endif
|
|
5079
|
+
}
|
|
5080
|
+
// If the instance does _not_ override the (extended) finalizer, delete the
|
|
5081
|
+
// `T* instance` immediately.
|
|
5082
|
+
else {
|
|
5083
|
+
delete instance;
|
|
5084
|
+
}
|
|
5085
|
+
}
|
|
5086
|
+
|
|
5087
|
+
template <typename T>
|
|
5088
|
+
inline void ObjectWrap<T>::PostFinalizeCallback(napi_env env,
|
|
5089
|
+
void* data,
|
|
5090
|
+
void* /*hint*/) {
|
|
4929
5091
|
T* instance = static_cast<T*>(data);
|
|
4930
5092
|
instance->Finalize(Napi::Env(env));
|
|
4931
5093
|
delete instance;
|
|
@@ -6605,12 +6767,12 @@ inline Napi::Object Addon<T>::DefineProperties(
|
|
|
6605
6767
|
|
|
6606
6768
|
#if NAPI_VERSION > 2
|
|
6607
6769
|
template <typename Hook, typename Arg>
|
|
6608
|
-
Env::CleanupHook<Hook, Arg>
|
|
6770
|
+
Env::CleanupHook<Hook, Arg> BasicEnv::AddCleanupHook(Hook hook, Arg* arg) {
|
|
6609
6771
|
return CleanupHook<Hook, Arg>(*this, hook, arg);
|
|
6610
6772
|
}
|
|
6611
6773
|
|
|
6612
6774
|
template <typename Hook>
|
|
6613
|
-
Env::CleanupHook<Hook>
|
|
6775
|
+
Env::CleanupHook<Hook> BasicEnv::AddCleanupHook(Hook hook) {
|
|
6614
6776
|
return CleanupHook<Hook>(*this, hook);
|
|
6615
6777
|
}
|
|
6616
6778
|
|
|
@@ -6620,7 +6782,7 @@ Env::CleanupHook<Hook, Arg>::CleanupHook() {
|
|
|
6620
6782
|
}
|
|
6621
6783
|
|
|
6622
6784
|
template <typename Hook, typename Arg>
|
|
6623
|
-
Env::CleanupHook<Hook, Arg>::CleanupHook(Napi::
|
|
6785
|
+
Env::CleanupHook<Hook, Arg>::CleanupHook(Napi::BasicEnv env, Hook hook)
|
|
6624
6786
|
: wrapper(Env::CleanupHook<Hook, Arg>::Wrapper) {
|
|
6625
6787
|
data = new CleanupData{std::move(hook), nullptr};
|
|
6626
6788
|
napi_status status = napi_add_env_cleanup_hook(env, wrapper, data);
|
|
@@ -6631,7 +6793,9 @@ Env::CleanupHook<Hook, Arg>::CleanupHook(Napi::Env env, Hook hook)
|
|
|
6631
6793
|
}
|
|
6632
6794
|
|
|
6633
6795
|
template <typename Hook, typename Arg>
|
|
6634
|
-
Env::CleanupHook<Hook, Arg>::CleanupHook(Napi::
|
|
6796
|
+
Env::CleanupHook<Hook, Arg>::CleanupHook(Napi::BasicEnv env,
|
|
6797
|
+
Hook hook,
|
|
6798
|
+
Arg* arg)
|
|
6635
6799
|
: wrapper(Env::CleanupHook<Hook, Arg>::WrapperWithArg) {
|
|
6636
6800
|
data = new CleanupData{std::move(hook), arg};
|
|
6637
6801
|
napi_status status = napi_add_env_cleanup_hook(env, wrapper, data);
|
|
@@ -6642,7 +6806,7 @@ Env::CleanupHook<Hook, Arg>::CleanupHook(Napi::Env env, Hook hook, Arg* arg)
|
|
|
6642
6806
|
}
|
|
6643
6807
|
|
|
6644
6808
|
template <class Hook, class Arg>
|
|
6645
|
-
bool Env::CleanupHook<Hook, Arg>::Remove(
|
|
6809
|
+
bool Env::CleanupHook<Hook, Arg>::Remove(BasicEnv env) {
|
|
6646
6810
|
napi_status status = napi_remove_env_cleanup_hook(env, wrapper, data);
|
|
6647
6811
|
delete data;
|
|
6648
6812
|
data = nullptr;
|
|
@@ -6655,6 +6819,65 @@ bool Env::CleanupHook<Hook, Arg>::IsEmpty() const {
|
|
|
6655
6819
|
}
|
|
6656
6820
|
#endif // NAPI_VERSION > 2
|
|
6657
6821
|
|
|
6822
|
+
#ifdef NODE_API_EXPERIMENTAL_HAS_POST_FINALIZER
|
|
6823
|
+
template <typename FinalizerType>
|
|
6824
|
+
inline void BasicEnv::PostFinalizer(FinalizerType finalizeCallback) const {
|
|
6825
|
+
using T = void*;
|
|
6826
|
+
details::FinalizeData<T, FinalizerType>* finalizeData =
|
|
6827
|
+
new details::FinalizeData<T, FinalizerType>(
|
|
6828
|
+
{std::move(finalizeCallback), nullptr});
|
|
6829
|
+
|
|
6830
|
+
napi_status status = node_api_post_finalizer(
|
|
6831
|
+
_env,
|
|
6832
|
+
details::FinalizeData<T, FinalizerType>::WrapperGCWithoutData,
|
|
6833
|
+
static_cast<void*>(nullptr),
|
|
6834
|
+
finalizeData);
|
|
6835
|
+
if (status != napi_ok) {
|
|
6836
|
+
delete finalizeData;
|
|
6837
|
+
NAPI_FATAL_IF_FAILED(
|
|
6838
|
+
status, "BasicEnv::PostFinalizer", "invalid arguments");
|
|
6839
|
+
}
|
|
6840
|
+
}
|
|
6841
|
+
|
|
6842
|
+
template <typename FinalizerType, typename T>
|
|
6843
|
+
inline void BasicEnv::PostFinalizer(FinalizerType finalizeCallback,
|
|
6844
|
+
T* data) const {
|
|
6845
|
+
details::FinalizeData<T, FinalizerType>* finalizeData =
|
|
6846
|
+
new details::FinalizeData<T, FinalizerType>(
|
|
6847
|
+
{std::move(finalizeCallback), nullptr});
|
|
6848
|
+
|
|
6849
|
+
napi_status status = node_api_post_finalizer(
|
|
6850
|
+
_env,
|
|
6851
|
+
details::FinalizeData<T, FinalizerType>::WrapperGC,
|
|
6852
|
+
data,
|
|
6853
|
+
finalizeData);
|
|
6854
|
+
if (status != napi_ok) {
|
|
6855
|
+
delete finalizeData;
|
|
6856
|
+
NAPI_FATAL_IF_FAILED(
|
|
6857
|
+
status, "BasicEnv::PostFinalizer", "invalid arguments");
|
|
6858
|
+
}
|
|
6859
|
+
}
|
|
6860
|
+
|
|
6861
|
+
template <typename FinalizerType, typename T, typename Hint>
|
|
6862
|
+
inline void BasicEnv::PostFinalizer(FinalizerType finalizeCallback,
|
|
6863
|
+
T* data,
|
|
6864
|
+
Hint* finalizeHint) const {
|
|
6865
|
+
details::FinalizeData<T, FinalizerType, Hint>* finalizeData =
|
|
6866
|
+
new details::FinalizeData<T, FinalizerType, Hint>(
|
|
6867
|
+
{std::move(finalizeCallback), finalizeHint});
|
|
6868
|
+
napi_status status = node_api_post_finalizer(
|
|
6869
|
+
_env,
|
|
6870
|
+
details::FinalizeData<T, FinalizerType, Hint>::WrapperGCWithHint,
|
|
6871
|
+
data,
|
|
6872
|
+
finalizeData);
|
|
6873
|
+
if (status != napi_ok) {
|
|
6874
|
+
delete finalizeData;
|
|
6875
|
+
NAPI_FATAL_IF_FAILED(
|
|
6876
|
+
status, "BasicEnv::PostFinalizer", "invalid arguments");
|
|
6877
|
+
}
|
|
6878
|
+
}
|
|
6879
|
+
#endif // NODE_API_EXPERIMENTAL_HAS_POST_FINALIZER
|
|
6880
|
+
|
|
6658
6881
|
#ifdef NAPI_CPP_CUSTOM_NAMESPACE
|
|
6659
6882
|
} // namespace NAPI_CPP_CUSTOM_NAMESPACE
|
|
6660
6883
|
#endif
|
package/napi.h
CHANGED
|
@@ -299,6 +299,14 @@ template <typename T>
|
|
|
299
299
|
using MaybeOrValue = T;
|
|
300
300
|
#endif
|
|
301
301
|
|
|
302
|
+
#ifdef NODE_API_EXPERIMENTAL_HAS_POST_FINALIZER
|
|
303
|
+
using node_addon_api_basic_env = node_api_nogc_env;
|
|
304
|
+
using node_addon_api_basic_finalize = node_api_nogc_finalize;
|
|
305
|
+
#else
|
|
306
|
+
using node_addon_api_basic_env = napi_env;
|
|
307
|
+
using node_addon_api_basic_finalize = napi_finalize;
|
|
308
|
+
#endif
|
|
309
|
+
|
|
302
310
|
/// Environment for Node-API values and operations.
|
|
303
311
|
///
|
|
304
312
|
/// All Node-API values and operations must be associated with an environment.
|
|
@@ -307,14 +315,13 @@ using MaybeOrValue = T;
|
|
|
307
315
|
/// Node-API operations within the callback. (Many methods infer the
|
|
308
316
|
/// environment from the `this` instance that the method is called on.)
|
|
309
317
|
///
|
|
310
|
-
///
|
|
311
|
-
/// although current implementations only support one environment per process.
|
|
318
|
+
/// Multiple environments may co-exist in a single process or a thread.
|
|
312
319
|
///
|
|
313
320
|
/// In the V8 JavaScript engine, a Node-API environment approximately
|
|
314
321
|
/// corresponds to an Isolate.
|
|
315
|
-
class
|
|
322
|
+
class BasicEnv {
|
|
316
323
|
private:
|
|
317
|
-
|
|
324
|
+
node_addon_api_basic_env _env;
|
|
318
325
|
#if NAPI_VERSION > 5
|
|
319
326
|
template <typename T>
|
|
320
327
|
static void DefaultFini(Env, T* data);
|
|
@@ -322,20 +329,22 @@ class Env {
|
|
|
322
329
|
static void DefaultFiniWithHint(Env, DataType* data, HintType* hint);
|
|
323
330
|
#endif // NAPI_VERSION > 5
|
|
324
331
|
public:
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
operator
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
332
|
+
BasicEnv(node_addon_api_basic_env env);
|
|
333
|
+
|
|
334
|
+
operator node_addon_api_basic_env() const;
|
|
335
|
+
|
|
336
|
+
// Without these operator overloads, the error:
|
|
337
|
+
//
|
|
338
|
+
// Use of overloaded operator '==' is ambiguous (with operand types
|
|
339
|
+
// 'Napi::Env' and 'Napi::Env')
|
|
340
|
+
//
|
|
341
|
+
// ... occurs when comparing foo.Env() == bar.Env() or foo.Env() == nullptr
|
|
342
|
+
bool operator==(const BasicEnv& other) const {
|
|
343
|
+
return _env == other._env;
|
|
344
|
+
};
|
|
345
|
+
bool operator==(std::nullptr_t /*other*/) const {
|
|
346
|
+
return _env == nullptr;
|
|
347
|
+
};
|
|
339
348
|
|
|
340
349
|
#if NAPI_VERSION > 2
|
|
341
350
|
template <typename Hook, typename Arg = void>
|
|
@@ -354,7 +363,7 @@ class Env {
|
|
|
354
363
|
|
|
355
364
|
template <typename T>
|
|
356
365
|
using Finalizer = void (*)(Env, T*);
|
|
357
|
-
template <typename T, Finalizer<T> fini =
|
|
366
|
+
template <typename T, Finalizer<T> fini = BasicEnv::DefaultFini<T>>
|
|
358
367
|
void SetInstanceData(T* data) const;
|
|
359
368
|
|
|
360
369
|
template <typename DataType, typename HintType>
|
|
@@ -362,7 +371,7 @@ class Env {
|
|
|
362
371
|
template <typename DataType,
|
|
363
372
|
typename HintType,
|
|
364
373
|
FinalizerWithHint<DataType, HintType> fini =
|
|
365
|
-
|
|
374
|
+
BasicEnv::DefaultFiniWithHint<DataType, HintType>>
|
|
366
375
|
void SetInstanceData(DataType* data, HintType* hint) const;
|
|
367
376
|
#endif // NAPI_VERSION > 5
|
|
368
377
|
|
|
@@ -371,9 +380,9 @@ class Env {
|
|
|
371
380
|
class CleanupHook {
|
|
372
381
|
public:
|
|
373
382
|
CleanupHook();
|
|
374
|
-
CleanupHook(
|
|
375
|
-
CleanupHook(
|
|
376
|
-
bool Remove(
|
|
383
|
+
CleanupHook(BasicEnv env, Hook hook, Arg* arg);
|
|
384
|
+
CleanupHook(BasicEnv env, Hook hook);
|
|
385
|
+
bool Remove(BasicEnv env);
|
|
377
386
|
bool IsEmpty() const;
|
|
378
387
|
|
|
379
388
|
private:
|
|
@@ -391,6 +400,39 @@ class Env {
|
|
|
391
400
|
#if NAPI_VERSION > 8
|
|
392
401
|
const char* GetModuleFileName() const;
|
|
393
402
|
#endif // NAPI_VERSION > 8
|
|
403
|
+
|
|
404
|
+
#ifdef NODE_API_EXPERIMENTAL_HAS_POST_FINALIZER
|
|
405
|
+
template <typename FinalizerType>
|
|
406
|
+
inline void PostFinalizer(FinalizerType finalizeCallback) const;
|
|
407
|
+
|
|
408
|
+
template <typename FinalizerType, typename T>
|
|
409
|
+
inline void PostFinalizer(FinalizerType finalizeCallback, T* data) const;
|
|
410
|
+
|
|
411
|
+
template <typename FinalizerType, typename T, typename Hint>
|
|
412
|
+
inline void PostFinalizer(FinalizerType finalizeCallback,
|
|
413
|
+
T* data,
|
|
414
|
+
Hint* finalizeHint) const;
|
|
415
|
+
#endif // NODE_API_EXPERIMENTAL_HAS_POST_FINALIZER
|
|
416
|
+
|
|
417
|
+
friend class Env;
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
class Env : public BasicEnv {
|
|
421
|
+
public:
|
|
422
|
+
Env(napi_env env);
|
|
423
|
+
|
|
424
|
+
operator napi_env() const;
|
|
425
|
+
|
|
426
|
+
Object Global() const;
|
|
427
|
+
Value Undefined() const;
|
|
428
|
+
Value Null() const;
|
|
429
|
+
|
|
430
|
+
bool IsExceptionPending() const;
|
|
431
|
+
Error GetAndClearPendingException() const;
|
|
432
|
+
|
|
433
|
+
MaybeOrValue<Value> RunScript(const char* utf8script) const;
|
|
434
|
+
MaybeOrValue<Value> RunScript(const std::string& utf8script) const;
|
|
435
|
+
MaybeOrValue<Value> RunScript(String script) const;
|
|
394
436
|
};
|
|
395
437
|
|
|
396
438
|
/// A JavaScript value of unknown type.
|
|
@@ -427,6 +469,8 @@ class Value {
|
|
|
427
469
|
template <typename T>
|
|
428
470
|
static Value From(napi_env env, const T& value);
|
|
429
471
|
|
|
472
|
+
static void CheckCast(napi_env env, napi_value value);
|
|
473
|
+
|
|
430
474
|
/// Converts to a Node-API value primitive.
|
|
431
475
|
///
|
|
432
476
|
/// If the instance is _empty_, this returns `nullptr`.
|
|
@@ -493,6 +537,10 @@ class Value {
|
|
|
493
537
|
template <typename T>
|
|
494
538
|
T As() const;
|
|
495
539
|
|
|
540
|
+
// Unsafe Value::As(), should be avoided.
|
|
541
|
+
template <typename T>
|
|
542
|
+
T UnsafeAs() const;
|
|
543
|
+
|
|
496
544
|
MaybeOrValue<Boolean> ToBoolean()
|
|
497
545
|
const; ///< Coerces a value to a JavaScript boolean.
|
|
498
546
|
MaybeOrValue<Number> ToNumber()
|
|
@@ -2415,6 +2463,7 @@ class ObjectWrap : public InstanceWrap<T>, public Reference<Object> {
|
|
|
2415
2463
|
napi_property_attributes attributes = napi_default);
|
|
2416
2464
|
static Napi::Value OnCalledAsFunction(const Napi::CallbackInfo& callbackInfo);
|
|
2417
2465
|
virtual void Finalize(Napi::Env env);
|
|
2466
|
+
virtual void Finalize(BasicEnv env);
|
|
2418
2467
|
|
|
2419
2468
|
private:
|
|
2420
2469
|
using This = ObjectWrap<T>;
|
|
@@ -2429,7 +2478,12 @@ class ObjectWrap : public InstanceWrap<T>, public Reference<Object> {
|
|
|
2429
2478
|
napi_callback_info info);
|
|
2430
2479
|
static napi_value StaticSetterCallbackWrapper(napi_env env,
|
|
2431
2480
|
napi_callback_info info);
|
|
2432
|
-
static void FinalizeCallback(
|
|
2481
|
+
static void FinalizeCallback(node_addon_api_basic_env env,
|
|
2482
|
+
void* data,
|
|
2483
|
+
void* hint);
|
|
2484
|
+
|
|
2485
|
+
static void PostFinalizeCallback(napi_env env, void* data, void* hint);
|
|
2486
|
+
|
|
2433
2487
|
static Function DefineClass(Napi::Env env,
|
|
2434
2488
|
const char* utf8name,
|
|
2435
2489
|
const size_t props_count,
|
package/package.json
CHANGED