@@ -31,6 +31,23 @@ namespace details {
31
31
// Node.js releases. Only necessary when they are used in napi.h and napi-inl.h.
32
32
constexpr int napi_no_external_buffers_allowed = 22 ;
33
33
34
+ #if (defined(NAPI_EXPERIMENTAL) && \
35
+ defined (NODE_API_EXPERIMENTAL_HAS_POST_FINALIZER))
36
+ template <napi_finalize finalizer>
37
+ inline void PostFinalizerWrapper(node_api_nogc_env nogc_env,
38
+ void * data,
39
+ void * hint) {
40
+ napi_status status = node_api_post_finalizer (nogc_env, finalizer, data, hint);
41
+ NAPI_FATAL_IF_FAILED (
42
+ status, " PostFinalizerWrapper" , " node_api_post_finalizer failed" );
43
+ }
44
+ #else
45
+ template <napi_finalize finalizer>
46
+ inline void PostFinalizerWrapper (napi_env env, void * data, void * hint) {
47
+ finalizer (env, data, hint);
48
+ }
49
+ #endif
50
+
34
51
template <typename FreeType>
35
52
inline void default_finalizer (napi_env /* env*/ , void * data, void * /* hint*/ ) {
36
53
delete static_cast <FreeType*>(data);
@@ -65,7 +82,8 @@ inline napi_status AttachData(napi_env env,
65
82
}
66
83
}
67
84
#else // NAPI_VERSION >= 5
68
- status = napi_add_finalizer (env, obj, data, finalizer, hint, nullptr );
85
+ status = napi_add_finalizer (
86
+ env, obj, data, details::PostFinalizerWrapper<finalizer>, hint, nullptr );
69
87
#endif
70
88
return status;
71
89
}
@@ -1777,7 +1795,8 @@ inline External<T> External<T>::New(napi_env env,
1777
1795
napi_status status =
1778
1796
napi_create_external (env,
1779
1797
data,
1780
- details::FinalizeData<T, Finalizer>::Wrapper,
1798
+ details::PostFinalizerWrapper<
1799
+ details::FinalizeData<T, Finalizer>::Wrapper>,
1781
1800
finalizeData,
1782
1801
&value);
1783
1802
if (status != napi_ok) {
@@ -1800,7 +1819,8 @@ inline External<T> External<T>::New(napi_env env,
1800
1819
napi_status status = napi_create_external (
1801
1820
env,
1802
1821
data,
1803
- details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint,
1822
+ details::PostFinalizerWrapper<
1823
+ details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint>,
1804
1824
finalizeData,
1805
1825
&value);
1806
1826
if (status != napi_ok) {
@@ -1913,7 +1933,8 @@ inline ArrayBuffer ArrayBuffer::New(napi_env env,
1913
1933
env,
1914
1934
externalData,
1915
1935
byteLength,
1916
- details::FinalizeData<void , Finalizer>::Wrapper,
1936
+ details::PostFinalizerWrapper<
1937
+ details::FinalizeData<void , Finalizer>::Wrapper>,
1917
1938
finalizeData,
1918
1939
&value);
1919
1940
if (status != napi_ok) {
@@ -1938,7 +1959,8 @@ inline ArrayBuffer ArrayBuffer::New(napi_env env,
1938
1959
env,
1939
1960
externalData,
1940
1961
byteLength,
1941
- details::FinalizeData<void , Finalizer, Hint>::WrapperWithHint,
1962
+ details::PostFinalizerWrapper<
1963
+ details::FinalizeData<void , Finalizer, Hint>::WrapperWithHint>,
1942
1964
finalizeData,
1943
1965
&value);
1944
1966
if (status != napi_ok) {
@@ -2655,13 +2677,14 @@ inline Buffer<T> Buffer<T>::New(napi_env env,
2655
2677
details::FinalizeData<T, Finalizer>* finalizeData =
2656
2678
new details::FinalizeData<T, Finalizer>(
2657
2679
{std::move (finalizeCallback), nullptr });
2658
- napi_status status =
2659
- napi_create_external_buffer (env,
2660
- length * sizeof (T),
2661
- data,
2662
- details::FinalizeData<T, Finalizer>::Wrapper,
2663
- finalizeData,
2664
- &value);
2680
+ napi_status status = napi_create_external_buffer (
2681
+ env,
2682
+ length * sizeof (T),
2683
+ data,
2684
+ details::PostFinalizerWrapper<
2685
+ details::FinalizeData<T, Finalizer>::Wrapper>,
2686
+ finalizeData,
2687
+ &value);
2665
2688
if (status != napi_ok) {
2666
2689
delete finalizeData;
2667
2690
NAPI_THROW_IF_FAILED (env, status, Buffer ());
@@ -2684,7 +2707,8 @@ inline Buffer<T> Buffer<T>::New(napi_env env,
2684
2707
env,
2685
2708
length * sizeof (T),
2686
2709
data,
2687
- details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint,
2710
+ details::PostFinalizerWrapper<
2711
+ details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint>,
2688
2712
finalizeData,
2689
2713
&value);
2690
2714
if (status != napi_ok) {
@@ -2723,13 +2747,14 @@ inline Buffer<T> Buffer<T>::NewOrCopy(napi_env env,
2723
2747
{std::move (finalizeCallback), nullptr });
2724
2748
#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
2725
2749
napi_value value;
2726
- napi_status status =
2727
- napi_create_external_buffer (env,
2728
- length * sizeof (T),
2729
- data,
2730
- details::FinalizeData<T, Finalizer>::Wrapper,
2731
- finalizeData,
2732
- &value);
2750
+ napi_status status = napi_create_external_buffer (
2751
+ env,
2752
+ length * sizeof (T),
2753
+ data,
2754
+ details::PostFinalizerWrapper<
2755
+ details::FinalizeData<T, Finalizer>::Wrapper>,
2756
+ finalizeData,
2757
+ &value);
2733
2758
if (status == details::napi_no_external_buffers_allowed) {
2734
2759
#endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
2735
2760
// If we can't create an external buffer, we'll just copy the data.
@@ -2762,7 +2787,8 @@ inline Buffer<T> Buffer<T>::NewOrCopy(napi_env env,
2762
2787
env,
2763
2788
length * sizeof (T),
2764
2789
data,
2765
- details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint,
2790
+ details::PostFinalizerWrapper<
2791
+ details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint>,
2766
2792
finalizeData,
2767
2793
&value);
2768
2794
if (status == details::napi_no_external_buffers_allowed) {
@@ -3057,7 +3083,12 @@ inline void Error::ThrowAsJavaScriptException() const {
3057
3083
3058
3084
status = napi_throw (_env, Value ());
3059
3085
3060
- if (status == napi_pending_exception) {
3086
+ #ifdef NAPI_EXPERIMENTAL
3087
+ napi_status expected_failure_mode = napi_cannot_run_js;
3088
+ #else
3089
+ napi_status expected_failure_mode = napi_pending_exception;
3090
+ #endif
3091
+ if (status == expected_failure_mode) {
3061
3092
// The environment must be terminating as we checked earlier and there
3062
3093
// was no pending exception. In this case continuing will result
3063
3094
// in a fatal error and there is nothing the author has done incorrectly
@@ -4431,7 +4462,12 @@ inline ObjectWrap<T>::ObjectWrap(const Napi::CallbackInfo& callbackInfo) {
4431
4462
napi_status status;
4432
4463
napi_ref ref;
4433
4464
T* instance = static_cast <T*>(this );
4434
- status = napi_wrap (env, wrapper, instance, FinalizeCallback, nullptr , &ref);
4465
+ status = napi_wrap (env,
4466
+ wrapper,
4467
+ instance,
4468
+ details::PostFinalizerWrapper<FinalizeCallback>,
4469
+ nullptr ,
4470
+ &ref);
4435
4471
NAPI_THROW_IF_FAILED_VOID (env, status);
4436
4472
4437
4473
Reference<Object>* instanceRef = instance;
@@ -5327,19 +5363,21 @@ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5327
5363
auto * finalizeData = new details::
5328
5364
ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
5329
5365
{data, finalizeCallback});
5330
- napi_status status = napi_create_threadsafe_function (
5331
- env,
5332
- nullptr ,
5333
- nullptr ,
5334
- String::From (env, resourceName),
5335
- maxQueueSize,
5336
- initialThreadCount,
5337
- finalizeData,
5366
+ auto fini =
5338
5367
details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
5339
- FinalizeFinalizeWrapperWithDataAndContext,
5340
- context,
5341
- CallJsInternal,
5342
- &tsfn._tsfn );
5368
+ FinalizeFinalizeWrapperWithDataAndContext;
5369
+ napi_status status =
5370
+ napi_create_threadsafe_function (env,
5371
+ nullptr ,
5372
+ nullptr ,
5373
+ String::From (env, resourceName),
5374
+ maxQueueSize,
5375
+ initialThreadCount,
5376
+ finalizeData,
5377
+ fini,
5378
+ context,
5379
+ CallJsInternal,
5380
+ &tsfn._tsfn );
5343
5381
if (status != napi_ok) {
5344
5382
delete finalizeData;
5345
5383
NAPI_THROW_IF_FAILED (
@@ -5371,19 +5409,21 @@ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5371
5409
auto * finalizeData = new details::
5372
5410
ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
5373
5411
{data, finalizeCallback});
5374
- napi_status status = napi_create_threadsafe_function (
5375
- env,
5376
- nullptr ,
5377
- resource,
5378
- String::From (env, resourceName),
5379
- maxQueueSize,
5380
- initialThreadCount,
5381
- finalizeData,
5412
+ auto fini =
5382
5413
details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
5383
- FinalizeFinalizeWrapperWithDataAndContext,
5384
- context,
5385
- CallJsInternal,
5386
- &tsfn._tsfn );
5414
+ FinalizeFinalizeWrapperWithDataAndContext;
5415
+ napi_status status =
5416
+ napi_create_threadsafe_function (env,
5417
+ nullptr ,
5418
+ resource,
5419
+ String::From (env, resourceName),
5420
+ maxQueueSize,
5421
+ initialThreadCount,
5422
+ finalizeData,
5423
+ fini,
5424
+ context,
5425
+ CallJsInternal,
5426
+ &tsfn._tsfn );
5387
5427
if (status != napi_ok) {
5388
5428
delete finalizeData;
5389
5429
NAPI_THROW_IF_FAILED (
@@ -5487,19 +5527,21 @@ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5487
5527
auto * finalizeData = new details::
5488
5528
ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
5489
5529
{data, finalizeCallback});
5490
- napi_status status = napi_create_threadsafe_function (
5491
- env,
5492
- callback,
5493
- nullptr ,
5494
- String::From (env, resourceName),
5495
- maxQueueSize,
5496
- initialThreadCount,
5497
- finalizeData,
5530
+ auto fini =
5498
5531
details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
5499
- FinalizeFinalizeWrapperWithDataAndContext,
5500
- context,
5501
- CallJsInternal,
5502
- &tsfn._tsfn );
5532
+ FinalizeFinalizeWrapperWithDataAndContext;
5533
+ napi_status status =
5534
+ napi_create_threadsafe_function (env,
5535
+ callback,
5536
+ nullptr ,
5537
+ String::From (env, resourceName),
5538
+ maxQueueSize,
5539
+ initialThreadCount,
5540
+ finalizeData,
5541
+ fini,
5542
+ context,
5543
+ CallJsInternal,
5544
+ &tsfn._tsfn );
5503
5545
if (status != napi_ok) {
5504
5546
delete finalizeData;
5505
5547
NAPI_THROW_IF_FAILED (
@@ -5533,6 +5575,9 @@ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5533
5575
auto * finalizeData = new details::
5534
5576
ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
5535
5577
{data, finalizeCallback});
5578
+ auto fini =
5579
+ details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
5580
+ FinalizeFinalizeWrapperWithDataAndContext;
5536
5581
napi_status status = napi_create_threadsafe_function (
5537
5582
env,
5538
5583
details::DefaultCallbackWrapper<
@@ -5544,8 +5589,7 @@ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5544
5589
maxQueueSize,
5545
5590
initialThreadCount,
5546
5591
finalizeData,
5547
- details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
5548
- FinalizeFinalizeWrapperWithDataAndContext,
5592
+ fini,
5549
5593
context,
5550
5594
CallJsInternal,
5551
5595
&tsfn._tsfn );
0 commit comments