@@ -426,6 +426,34 @@ inline std::string StringFormat(const char* format, ...) {
426
426
return result;
427
427
}
428
428
429
+ template <typename T>
430
+ class HasGcFinalize {
431
+ private:
432
+ template <typename U, void (U::*)(Napi::Env)>
433
+ struct SFINAE {};
434
+ template <typename U>
435
+ static char test (SFINAE<U, &U::Finalize>*);
436
+ template <typename U>
437
+ static int test (...);
438
+
439
+ public:
440
+ static constexpr bool value = sizeof (test<T>(0 )) == sizeof (char );
441
+ };
442
+
443
+ template <typename T>
444
+ class HasNogcFinalize {
445
+ private:
446
+ template <typename U, void (U::*)(Napi::NogcEnv)>
447
+ struct SFINAE {};
448
+ template <typename U>
449
+ static char test (SFINAE<U, &U::Finalize>*);
450
+ template <typename U>
451
+ static int test (...);
452
+
453
+ public:
454
+ static constexpr bool value = sizeof (test<T>(0 )) == sizeof (char );
455
+ };
456
+
429
457
} // namespace details
430
458
431
459
#ifndef NODE_ADDON_API_DISABLE_DEPRECATED
@@ -2821,7 +2849,7 @@ inline Buffer<T> Buffer<T>::NewOrCopy(napi_env env,
2821
2849
#endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
2822
2850
// If we can't create an external buffer, we'll just copy the data.
2823
2851
Buffer<T> ret = Buffer<T>::Copy (env, data, length);
2824
- details::FinalizeData<T, Finalizer>::Wrapper (env, data, finalizeData);
2852
+ details::FinalizeData<T, Finalizer>::WrapperGC (env, data, finalizeData);
2825
2853
return ret;
2826
2854
#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
2827
2855
}
@@ -2856,7 +2884,7 @@ inline Buffer<T> Buffer<T>::NewOrCopy(napi_env env,
2856
2884
#endif
2857
2885
// If we can't create an external buffer, we'll just copy the data.
2858
2886
Buffer<T> ret = Buffer<T>::Copy (env, data, length);
2859
- details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint (
2887
+ details::FinalizeData<T, Finalizer, Hint>::WrapperGCWithHint (
2860
2888
env, data, finalizeData);
2861
2889
return ret;
2862
2890
#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
@@ -4890,7 +4918,10 @@ inline Value ObjectWrap<T>::OnCalledAsFunction(
4890
4918
}
4891
4919
4892
4920
template <typename T>
4893
- inline void ObjectWrap<T>::Finalize (NODE_ADDON_API_NOGC_ENV_CLASS /* env*/ ) {}
4921
+ inline void ObjectWrap<T>::Finalize (Napi::Env /* env*/ ) {}
4922
+
4923
+ template <typename T>
4924
+ inline void ObjectWrap<T>::Finalize (NogcEnv /* env*/ ) {}
4894
4925
4895
4926
template <typename T>
4896
4927
inline napi_value ObjectWrap<T>::ConstructorCallbackWrapper (
@@ -4980,16 +5011,41 @@ template <typename T>
4980
5011
inline void ObjectWrap<T>::FinalizeCallback (NODE_ADDON_API_NOGC_ENV env,
4981
5012
void * data,
4982
5013
void * /* hint*/ ) {
4983
- #ifndef NODE_API_EXPERIMENTAL_HAS_POST_FINALIZER
4984
- HandleScope scope (env);
4985
- #endif
4986
-
4987
5014
T* instance = static_cast <T*>(data);
4988
- instance->Finalize (env);
4989
5015
4990
5016
// Prevent ~ObjectWrap from calling napi_remove_wrap
4991
5017
instance->_ref = nullptr ;
4992
5018
5019
+ if constexpr (details::HasNogcFinalize<T>::value) {
5020
+ #ifndef NODE_API_EXPERIMENTAL_HAS_POST_FINALIZER
5021
+ HandleScope scope (env);
5022
+ #endif
5023
+
5024
+ instance->Finalize (Napi::NogcEnv (env));
5025
+ }
5026
+
5027
+ if constexpr (details::HasGcFinalize<T>::value) {
5028
+ #ifdef NODE_API_EXPERIMENTAL_HAS_POST_FINALIZER
5029
+ napi_status status =
5030
+ node_api_post_finalizer (env, PostFinalizeCallback, data, nullptr );
5031
+ NAPI_FATAL_IF_FAILED (status,
5032
+ " ObjectWrap<T>::FinalizeCallback" ,
5033
+ " node_api_post_finalizer failed" );
5034
+ #else
5035
+ HandleScope scope (env);
5036
+ PostFinalizeCallback (env, data, static_cast <void *>(nullptr ));
5037
+ #endif
5038
+ } else {
5039
+ delete instance;
5040
+ }
5041
+ }
5042
+
5043
+ template <typename T>
5044
+ inline void ObjectWrap<T>::PostFinalizeCallback (napi_env env,
5045
+ void * data,
5046
+ void * /* hint*/ ) {
5047
+ T* instance = static_cast <T*>(data);
5048
+ instance->Finalize (Napi::Env (env));
4993
5049
delete instance;
4994
5050
}
4995
5051
0 commit comments