@@ -180,11 +180,36 @@ napi_value TemplatedInstanceVoidCallback(napi_env env, napi_callback_info info)
180
180
});
181
181
}
182
182
183
+ inline void DeferredCallback (const char * placeOfFailure,
184
+ napi_env env,
185
+ void * data,
186
+ void * hint,
187
+ napi_finalize fini) {
188
+ #ifdef NAPI_EXPERIMENTAL
189
+ napi_status status = node_api_post_finalizer (env, fini, data, hint);
190
+ NAPI_FATAL_IF_FAILED (
191
+ status, placeOfFailure, " DeferredCallback -> node_api_post_finalizer" );
192
+ #else
193
+ (void )placeOfFailure;
194
+ fini (env, data, hint);
195
+ #endif
196
+ }
197
+
183
198
template <typename T, typename Finalizer, typename Hint = void >
184
199
struct FinalizeData {
185
200
static inline void Wrapper (napi_env env,
186
201
void * data,
187
202
void * finalizeHint) NAPI_NOEXCEPT {
203
+ DeferredCallback (" FinalizeData::Wrapper" ,
204
+ env,
205
+ data,
206
+ finalizeHint,
207
+ FinalizeData<T, Finalizer>::SyncWrapper);
208
+ }
209
+
210
+ static inline void SyncWrapper (napi_env env,
211
+ void * data,
212
+ void * finalizeHint) NAPI_NOEXCEPT {
188
213
WrapVoidCallback ([&] {
189
214
FinalizeData* finalizeData = static_cast <FinalizeData*>(finalizeHint);
190
215
finalizeData->callback (Env (env), static_cast <T*>(data));
@@ -195,6 +220,16 @@ struct FinalizeData {
195
220
static inline void WrapperWithHint (napi_env env,
196
221
void * data,
197
222
void * finalizeHint) NAPI_NOEXCEPT {
223
+ DeferredCallback (" FinalizeData::WrapperWithHint" ,
224
+ env,
225
+ data,
226
+ finalizeHint,
227
+ FinalizeData<T, Finalizer, Hint>::SyncWrapperWithHint);
228
+ }
229
+
230
+ static inline void SyncWrapperWithHint (napi_env env,
231
+ void * data,
232
+ void * finalizeHint) NAPI_NOEXCEPT {
198
233
WrapVoidCallback ([&] {
199
234
FinalizeData* finalizeData = static_cast <FinalizeData*>(finalizeHint);
200
235
finalizeData->callback (
@@ -2731,7 +2766,7 @@ inline Buffer<T> Buffer<T>::NewOrCopy(napi_env env,
2731
2766
#endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
2732
2767
// If we can't create an external buffer, we'll just copy the data.
2733
2768
Buffer<T> ret = Buffer<T>::Copy (env, data, length);
2734
- details::FinalizeData<T, Finalizer>::Wrapper (env, data, finalizeData);
2769
+ details::FinalizeData<T, Finalizer>::SyncWrapper (env, data, finalizeData);
2735
2770
return ret;
2736
2771
#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
2737
2772
}
@@ -2766,7 +2801,7 @@ inline Buffer<T> Buffer<T>::NewOrCopy(napi_env env,
2766
2801
#endif
2767
2802
// If we can't create an external buffer, we'll just copy the data.
2768
2803
Buffer<T> ret = Buffer<T>::Copy (env, data, length);
2769
- details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint (
2804
+ details::FinalizeData<T, Finalizer, Hint>::SyncWrapperWithHint (
2770
2805
env, data, finalizeData);
2771
2806
return ret;
2772
2807
#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
@@ -3054,7 +3089,13 @@ inline void Error::ThrowAsJavaScriptException() const {
3054
3089
3055
3090
status = napi_throw (_env, Value ());
3056
3091
3057
- if (status == napi_pending_exception) {
3092
+ #ifdef NAPI_EXPERIMENTAL
3093
+ napi_status expected_failure_mode = napi_cannot_run_js;
3094
+ #else
3095
+ napi_status expected_failure_mode = napi_pending_exception;
3096
+ #endif
3097
+
3098
+ if (status == expected_failure_mode) {
3058
3099
// The environment must be terminating as we checked earlier and there
3059
3100
// was no pending exception. In this case continuing will result
3060
3101
// in a fatal error and there is nothing the author has done incorrectly
@@ -4879,10 +4920,16 @@ template <typename T>
4879
4920
inline void ObjectWrap<T>::FinalizeCallback (napi_env env,
4880
4921
void * data,
4881
4922
void * /* hint*/ ) {
4882
- HandleScope scope (env);
4883
- T* instance = static_cast <T*>(data);
4884
- instance->Finalize (Napi::Env (env));
4885
- delete instance;
4923
+ details::DeferredCallback (" ObjectWrap<T>::FinalizeCallback" ,
4924
+ env,
4925
+ data,
4926
+ nullptr ,
4927
+ [](napi_env env, void * data, void * /* hint*/ ) {
4928
+ HandleScope scope (env);
4929
+ T* instance = static_cast <T*>(data);
4930
+ instance->Finalize (Napi::Env (env));
4931
+ delete instance;
4932
+ });
4886
4933
}
4887
4934
4888
4935
template <typename T>
0 commit comments