@@ -2920,16 +2920,25 @@ inline ObjectWrap<T>::ObjectWrap(const Napi::CallbackInfo& callbackInfo) {
29202920 napi_value wrapper = callbackInfo.This ();
29212921 napi_status status;
29222922 napi_ref ref;
2923- T* instance = static_cast <T*>(this );
2924- status = napi_wrap (env, wrapper, instance, FinalizeCallback, nullptr , &ref);
2923+ status = napi_wrap (env, wrapper, this , FinalizeCallback, nullptr , &ref);
29252924 NAPI_THROW_IF_FAILED_VOID (env, status);
29262925
2927- Reference<Object>* instanceRef = instance ;
2926+ Reference<Object>* instanceRef = this ;
29282927 *instanceRef = Reference<Object>(env, ref);
29292928}
29302929
2931- template <typename T>
2932- inline ObjectWrap<T>::~ObjectWrap () {}
2930+ template <typename T>
2931+ inline ObjectWrap<T>::~ObjectWrap () {
2932+ // If the JS object still exists at this point, remove the finalizer added
2933+ // through `napi_wrap()`.
2934+ if (!IsEmpty ()) {
2935+ Object object = Value ();
2936+ // It is not valid to call `napi_remove_wrap()` with an empty `object`.
2937+ // This happens e.g. during garbage collection.
2938+ if (!object.IsEmpty ())
2939+ napi_remove_wrap (Env (), object, nullptr );
2940+ }
2941+ }
29332942
29342943template <typename T>
29352944inline T* ObjectWrap<T>::Unwrap(Object wrapper) {
@@ -3449,7 +3458,7 @@ inline napi_value ObjectWrap<T>::InstanceSetterCallbackWrapper(
34493458
34503459template <typename T>
34513460inline void ObjectWrap<T>::FinalizeCallback(napi_env env, void * data, void * /* hint*/ ) {
3452- T * instance = reinterpret_cast <T *>(data);
3461+ ObjectWrap<T> * instance = static_cast <ObjectWrap<T> *>(data);
34533462 instance->Finalize (Napi::Env (env));
34543463 delete instance;
34553464}
0 commit comments