@@ -31,6 +31,23 @@ namespace details {
3131// Node.js releases. Only necessary when they are used in napi.h and napi-inl.h.
3232constexpr int napi_no_external_buffers_allowed = 22 ;
3333
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+
3451template <typename FreeType>
3552inline void default_finalizer (napi_env /* env*/ , void * data, void * /* hint*/ ) {
3653 delete static_cast <FreeType*>(data);
@@ -65,7 +82,8 @@ inline napi_status AttachData(napi_env env,
6582 }
6683 }
6784#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 );
6987#endif
7088 return status;
7189}
@@ -1777,7 +1795,8 @@ inline External<T> External<T>::New(napi_env env,
17771795 napi_status status =
17781796 napi_create_external (env,
17791797 data,
1780- details::FinalizeData<T, Finalizer>::Wrapper,
1798+ details::PostFinalizerWrapper<
1799+ details::FinalizeData<T, Finalizer>::Wrapper>,
17811800 finalizeData,
17821801 &value);
17831802 if (status != napi_ok) {
@@ -1800,7 +1819,8 @@ inline External<T> External<T>::New(napi_env env,
18001819 napi_status status = napi_create_external (
18011820 env,
18021821 data,
1803- details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint,
1822+ details::PostFinalizerWrapper<
1823+ details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint>,
18041824 finalizeData,
18051825 &value);
18061826 if (status != napi_ok) {
@@ -1913,7 +1933,8 @@ inline ArrayBuffer ArrayBuffer::New(napi_env env,
19131933 env,
19141934 externalData,
19151935 byteLength,
1916- details::FinalizeData<void , Finalizer>::Wrapper,
1936+ details::PostFinalizerWrapper<
1937+ details::FinalizeData<void , Finalizer>::Wrapper>,
19171938 finalizeData,
19181939 &value);
19191940 if (status != napi_ok) {
@@ -1938,7 +1959,8 @@ inline ArrayBuffer ArrayBuffer::New(napi_env env,
19381959 env,
19391960 externalData,
19401961 byteLength,
1941- details::FinalizeData<void , Finalizer, Hint>::WrapperWithHint,
1962+ details::PostFinalizerWrapper<
1963+ details::FinalizeData<void , Finalizer, Hint>::WrapperWithHint>,
19421964 finalizeData,
19431965 &value);
19441966 if (status != napi_ok) {
@@ -2655,13 +2677,14 @@ inline Buffer<T> Buffer<T>::New(napi_env env,
26552677 details::FinalizeData<T, Finalizer>* finalizeData =
26562678 new details::FinalizeData<T, Finalizer>(
26572679 {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);
26652688 if (status != napi_ok) {
26662689 delete finalizeData;
26672690 NAPI_THROW_IF_FAILED (env, status, Buffer ());
@@ -2684,7 +2707,8 @@ inline Buffer<T> Buffer<T>::New(napi_env env,
26842707 env,
26852708 length * sizeof (T),
26862709 data,
2687- details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint,
2710+ details::PostFinalizerWrapper<
2711+ details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint>,
26882712 finalizeData,
26892713 &value);
26902714 if (status != napi_ok) {
@@ -2723,13 +2747,14 @@ inline Buffer<T> Buffer<T>::NewOrCopy(napi_env env,
27232747 {std::move (finalizeCallback), nullptr });
27242748#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
27252749 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);
27332758 if (status == details::napi_no_external_buffers_allowed) {
27342759#endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
27352760 // 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,
27622787 env,
27632788 length * sizeof (T),
27642789 data,
2765- details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint,
2790+ details::PostFinalizerWrapper<
2791+ details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint>,
27662792 finalizeData,
27672793 &value);
27682794 if (status == details::napi_no_external_buffers_allowed) {
@@ -3057,7 +3083,12 @@ inline void Error::ThrowAsJavaScriptException() const {
30573083
30583084 status = napi_throw (_env, Value ());
30593085
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) {
30613092 // The environment must be terminating as we checked earlier and there
30623093 // was no pending exception. In this case continuing will result
30633094 // 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) {
44314462 napi_status status;
44324463 napi_ref ref;
44334464 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);
44354471 NAPI_THROW_IF_FAILED_VOID (env, status);
44364472
44374473 Reference<Object>* instanceRef = instance;
@@ -5327,19 +5363,21 @@ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
53275363 auto * finalizeData = new details::
53285364 ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
53295365 {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 =
53385367 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 );
53435381 if (status != napi_ok) {
53445382 delete finalizeData;
53455383 NAPI_THROW_IF_FAILED (
@@ -5371,19 +5409,21 @@ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
53715409 auto * finalizeData = new details::
53725410 ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
53735411 {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 =
53825413 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 );
53875427 if (status != napi_ok) {
53885428 delete finalizeData;
53895429 NAPI_THROW_IF_FAILED (
@@ -5487,19 +5527,21 @@ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
54875527 auto * finalizeData = new details::
54885528 ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
54895529 {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 =
54985531 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 );
55035545 if (status != napi_ok) {
55045546 delete finalizeData;
55055547 NAPI_THROW_IF_FAILED (
@@ -5533,6 +5575,9 @@ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
55335575 auto * finalizeData = new details::
55345576 ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
55355577 {data, finalizeCallback});
5578+ auto fini =
5579+ details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
5580+ FinalizeFinalizeWrapperWithDataAndContext;
55365581 napi_status status = napi_create_threadsafe_function (
55375582 env,
55385583 details::DefaultCallbackWrapper<
@@ -5544,8 +5589,7 @@ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
55445589 maxQueueSize,
55455590 initialThreadCount,
55465591 finalizeData,
5547- details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
5548- FinalizeFinalizeWrapperWithDataAndContext,
5592+ fini,
55495593 context,
55505594 CallJsInternal,
55515595 &tsfn._tsfn );
0 commit comments