@@ -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;
0 commit comments