@@ -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
}
@@ -1774,7 +1792,8 @@ inline External<T> External<T>::New(napi_env env,
1774
1792
napi_status status =
1775
1793
napi_create_external (env,
1776
1794
data,
1777
- details::FinalizeData<T, Finalizer>::Wrapper,
1795
+ details::PostFinalizerWrapper<
1796
+ details::FinalizeData<T, Finalizer>::Wrapper>,
1778
1797
finalizeData,
1779
1798
&value);
1780
1799
if (status != napi_ok) {
@@ -1797,7 +1816,8 @@ inline External<T> External<T>::New(napi_env env,
1797
1816
napi_status status = napi_create_external (
1798
1817
env,
1799
1818
data,
1800
- details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint,
1819
+ details::PostFinalizerWrapper<
1820
+ details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint>,
1801
1821
finalizeData,
1802
1822
&value);
1803
1823
if (status != napi_ok) {
@@ -1910,7 +1930,8 @@ inline ArrayBuffer ArrayBuffer::New(napi_env env,
1910
1930
env,
1911
1931
externalData,
1912
1932
byteLength,
1913
- details::FinalizeData<void , Finalizer>::Wrapper,
1933
+ details::PostFinalizerWrapper<
1934
+ details::FinalizeData<void , Finalizer>::Wrapper>,
1914
1935
finalizeData,
1915
1936
&value);
1916
1937
if (status != napi_ok) {
@@ -1935,7 +1956,8 @@ inline ArrayBuffer ArrayBuffer::New(napi_env env,
1935
1956
env,
1936
1957
externalData,
1937
1958
byteLength,
1938
- details::FinalizeData<void , Finalizer, Hint>::WrapperWithHint,
1959
+ details::PostFinalizerWrapper<
1960
+ details::FinalizeData<void , Finalizer, Hint>::WrapperWithHint>,
1939
1961
finalizeData,
1940
1962
&value);
1941
1963
if (status != napi_ok) {
@@ -2652,13 +2674,14 @@ inline Buffer<T> Buffer<T>::New(napi_env env,
2652
2674
details::FinalizeData<T, Finalizer>* finalizeData =
2653
2675
new details::FinalizeData<T, Finalizer>(
2654
2676
{std::move (finalizeCallback), nullptr });
2655
- napi_status status =
2656
- napi_create_external_buffer (env,
2657
- length * sizeof (T),
2658
- data,
2659
- details::FinalizeData<T, Finalizer>::Wrapper,
2660
- finalizeData,
2661
- &value);
2677
+ napi_status status = napi_create_external_buffer (
2678
+ env,
2679
+ length * sizeof (T),
2680
+ data,
2681
+ details::PostFinalizerWrapper<
2682
+ details::FinalizeData<T, Finalizer>::Wrapper>,
2683
+ finalizeData,
2684
+ &value);
2662
2685
if (status != napi_ok) {
2663
2686
delete finalizeData;
2664
2687
NAPI_THROW_IF_FAILED (env, status, Buffer ());
@@ -2681,7 +2704,8 @@ inline Buffer<T> Buffer<T>::New(napi_env env,
2681
2704
env,
2682
2705
length * sizeof (T),
2683
2706
data,
2684
- details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint,
2707
+ details::PostFinalizerWrapper<
2708
+ details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint>,
2685
2709
finalizeData,
2686
2710
&value);
2687
2711
if (status != napi_ok) {
@@ -2720,13 +2744,14 @@ inline Buffer<T> Buffer<T>::NewOrCopy(napi_env env,
2720
2744
{std::move (finalizeCallback), nullptr });
2721
2745
#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
2722
2746
napi_value value;
2723
- napi_status status =
2724
- napi_create_external_buffer (env,
2725
- length * sizeof (T),
2726
- data,
2727
- details::FinalizeData<T, Finalizer>::Wrapper,
2728
- finalizeData,
2729
- &value);
2747
+ napi_status status = napi_create_external_buffer (
2748
+ env,
2749
+ length * sizeof (T),
2750
+ data,
2751
+ details::PostFinalizerWrapper<
2752
+ details::FinalizeData<T, Finalizer>::Wrapper>,
2753
+ finalizeData,
2754
+ &value);
2730
2755
if (status == details::napi_no_external_buffers_allowed) {
2731
2756
#endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
2732
2757
// If we can't create an external buffer, we'll just copy the data.
@@ -2759,7 +2784,8 @@ inline Buffer<T> Buffer<T>::NewOrCopy(napi_env env,
2759
2784
env,
2760
2785
length * sizeof (T),
2761
2786
data,
2762
- details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint,
2787
+ details::PostFinalizerWrapper<
2788
+ details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint>,
2763
2789
finalizeData,
2764
2790
&value);
2765
2791
if (status == details::napi_no_external_buffers_allowed) {
@@ -3054,7 +3080,12 @@ inline void Error::ThrowAsJavaScriptException() const {
3054
3080
3055
3081
status = napi_throw (_env, Value ());
3056
3082
3057
- if (status == napi_pending_exception) {
3083
+ #ifdef NAPI_EXPERIMENTAL
3084
+ napi_status expected_failure_mode = napi_cannot_run_js;
3085
+ #else
3086
+ napi_status expected_failure_mode = napi_pending_exception;
3087
+ #endif
3088
+ if (status == expected_failure_mode) {
3058
3089
// The environment must be terminating as we checked earlier and there
3059
3090
// was no pending exception. In this case continuing will result
3060
3091
// in a fatal error and there is nothing the author has done incorrectly
@@ -4428,7 +4459,12 @@ inline ObjectWrap<T>::ObjectWrap(const Napi::CallbackInfo& callbackInfo) {
4428
4459
napi_status status;
4429
4460
napi_ref ref;
4430
4461
T* instance = static_cast <T*>(this );
4431
- status = napi_wrap (env, wrapper, instance, FinalizeCallback, nullptr , &ref);
4462
+ status = napi_wrap (env,
4463
+ wrapper,
4464
+ instance,
4465
+ details::PostFinalizerWrapper<FinalizeCallback>,
4466
+ nullptr ,
4467
+ &ref);
4432
4468
NAPI_THROW_IF_FAILED_VOID (env, status);
4433
4469
4434
4470
Reference<Object>* instanceRef = instance;
@@ -5324,19 +5360,21 @@ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5324
5360
auto * finalizeData = new details::
5325
5361
ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
5326
5362
{data, finalizeCallback});
5327
- napi_status status = napi_create_threadsafe_function (
5328
- env,
5329
- nullptr ,
5330
- nullptr ,
5331
- String::From (env, resourceName),
5332
- maxQueueSize,
5333
- initialThreadCount,
5334
- finalizeData,
5363
+ auto fini =
5335
5364
details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
5336
- FinalizeFinalizeWrapperWithDataAndContext,
5337
- context,
5338
- CallJsInternal,
5339
- &tsfn._tsfn );
5365
+ FinalizeFinalizeWrapperWithDataAndContext;
5366
+ napi_status status =
5367
+ napi_create_threadsafe_function (env,
5368
+ nullptr ,
5369
+ nullptr ,
5370
+ String::From (env, resourceName),
5371
+ maxQueueSize,
5372
+ initialThreadCount,
5373
+ finalizeData,
5374
+ fini,
5375
+ context,
5376
+ CallJsInternal,
5377
+ &tsfn._tsfn );
5340
5378
if (status != napi_ok) {
5341
5379
delete finalizeData;
5342
5380
NAPI_THROW_IF_FAILED (
@@ -5368,19 +5406,21 @@ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5368
5406
auto * finalizeData = new details::
5369
5407
ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
5370
5408
{data, finalizeCallback});
5371
- napi_status status = napi_create_threadsafe_function (
5372
- env,
5373
- nullptr ,
5374
- resource,
5375
- String::From (env, resourceName),
5376
- maxQueueSize,
5377
- initialThreadCount,
5378
- finalizeData,
5409
+ auto fini =
5379
5410
details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
5380
- FinalizeFinalizeWrapperWithDataAndContext,
5381
- context,
5382
- CallJsInternal,
5383
- &tsfn._tsfn );
5411
+ FinalizeFinalizeWrapperWithDataAndContext;
5412
+ napi_status status =
5413
+ napi_create_threadsafe_function (env,
5414
+ nullptr ,
5415
+ resource,
5416
+ String::From (env, resourceName),
5417
+ maxQueueSize,
5418
+ initialThreadCount,
5419
+ finalizeData,
5420
+ fini,
5421
+ context,
5422
+ CallJsInternal,
5423
+ &tsfn._tsfn );
5384
5424
if (status != napi_ok) {
5385
5425
delete finalizeData;
5386
5426
NAPI_THROW_IF_FAILED (
@@ -5484,19 +5524,21 @@ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5484
5524
auto * finalizeData = new details::
5485
5525
ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
5486
5526
{data, finalizeCallback});
5487
- napi_status status = napi_create_threadsafe_function (
5488
- env,
5489
- callback,
5490
- nullptr ,
5491
- String::From (env, resourceName),
5492
- maxQueueSize,
5493
- initialThreadCount,
5494
- finalizeData,
5527
+ auto fini =
5495
5528
details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
5496
- FinalizeFinalizeWrapperWithDataAndContext,
5497
- context,
5498
- CallJsInternal,
5499
- &tsfn._tsfn );
5529
+ FinalizeFinalizeWrapperWithDataAndContext;
5530
+ napi_status status =
5531
+ napi_create_threadsafe_function (env,
5532
+ callback,
5533
+ nullptr ,
5534
+ String::From (env, resourceName),
5535
+ maxQueueSize,
5536
+ initialThreadCount,
5537
+ finalizeData,
5538
+ fini,
5539
+ context,
5540
+ CallJsInternal,
5541
+ &tsfn._tsfn );
5500
5542
if (status != napi_ok) {
5501
5543
delete finalizeData;
5502
5544
NAPI_THROW_IF_FAILED (
@@ -5530,6 +5572,9 @@ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5530
5572
auto * finalizeData = new details::
5531
5573
ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
5532
5574
{data, finalizeCallback});
5575
+ auto fini =
5576
+ details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
5577
+ FinalizeFinalizeWrapperWithDataAndContext;
5533
5578
napi_status status = napi_create_threadsafe_function (
5534
5579
env,
5535
5580
details::DefaultCallbackWrapper<
@@ -5541,8 +5586,7 @@ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5541
5586
maxQueueSize,
5542
5587
initialThreadCount,
5543
5588
finalizeData,
5544
- details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
5545
- FinalizeFinalizeWrapperWithDataAndContext,
5589
+ fini,
5546
5590
context,
5547
5591
CallJsInternal,
5548
5592
&tsfn._tsfn );
0 commit comments