From 3c3af1011a582398e4e9cadf705f06b4e9cfa69b Mon Sep 17 00:00:00 2001 From: LongYinan Date: Thu, 12 Jun 2025 06:05:08 -0700 Subject: [PATCH] fix(ext/napi): ensure the finalizer callback will be called (#29710) See https://github.com/napi-rs/napi-rs/issues/2708#issuecomment-2963957944 for the context. In current implementation, the Weak `Reference` is created with `v8::Weak::with_finalizer`, but there is no guarantee as to *when* or even *if* the finalization callback: https://github.com/denoland/rusty_v8/blob/v137.2.0/src/handle.rs#L623-L627. It may cause the memory leak if Node-API caller want to do some cleanup jobs in the finalization callback. --- ext/napi/js_native_api.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/ext/napi/js_native_api.rs b/ext/napi/js_native_api.rs index 7efbcf81e2..4c2128886d 100644 --- a/ext/napi/js_native_api.rs +++ b/ext/napi/js_native_api.rs @@ -111,12 +111,11 @@ impl Reference { fn set_weak(&mut self) { let reference = self as *mut Reference; if let ReferenceState::Strong(g) = &self.state { - let cb = Box::new(move |_: &mut v8::Isolate| { - Reference::weak_callback(reference) - }); + let cb = Box::new(move || Reference::weak_callback(reference)); let isolate = unsafe { (*self.env).isolate() }; - self.state = - ReferenceState::Weak(v8::Weak::with_finalizer(isolate, g, cb)); + self.state = ReferenceState::Weak(v8::Weak::with_guaranteed_finalizer( + isolate, g, cb, + )); } }