From 50ac391981ceb150ffdef16080b95e1ec0b07c3b Mon Sep 17 00:00:00 2001 From: Sadhbh Code Date: Tue, 2 Jun 2026 00:42:33 +0100 Subject: [PATCH 1/2] Flag to require that wrapped object has some finalizer --- src/guest/napi.rs | 17 ++++++++++++++--- src/napi_bridge_init.cc | 14 +++++++++----- src/snapi.rs | 2 ++ 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/guest/napi.rs b/src/guest/napi.rs index 3baeeaf..7d59e19 100644 --- a/src/guest/napi.rs +++ b/src/guest/napi.rs @@ -4746,17 +4746,19 @@ fn guest_napi_wrap( e: i32, obj: i32, native_data: i32, - _finalize_cb: i32, + finalize_cb: i32, _finalize_hint: i32, ref_ptr: i32, ) -> i32 { let mut ref_out: u32 = 0; + let has_finalize_cb = if finalize_cb != 0 { 1 } else { 0 }; let s = if ref_ptr > 0 { unsafe { snapi_bridge_wrap( snapi_env(&env, e), obj as u32, native_data as u64, + has_finalize_cb, &mut ref_out, ) } @@ -4766,6 +4768,7 @@ fn guest_napi_wrap( snapi_env(&env, e), obj as u32, native_data as u64, + has_finalize_cb, std::ptr::null_mut(), ) } @@ -4799,14 +4802,21 @@ fn guest_napi_add_finalizer( e: i32, obj: i32, data: i32, - _finalize_cb: i32, + finalize_cb: i32, _finalize_hint: i32, ref_ptr: i32, ) -> i32 { let mut ref_out: u32 = 0; + let has_finalize_cb = if finalize_cb != 0 { 1 } else { 0 }; let s = if ref_ptr > 0 { unsafe { - snapi_bridge_add_finalizer(snapi_env(&env, e), obj as u32, data as u64, &mut ref_out) + snapi_bridge_add_finalizer( + snapi_env(&env, e), + obj as u32, + data as u64, + has_finalize_cb, + &mut ref_out, + ) } } else { unsafe { @@ -4814,6 +4824,7 @@ fn guest_napi_add_finalizer( snapi_env(&env, e), obj as u32, data as u64, + has_finalize_cb, std::ptr::null_mut(), ) } diff --git a/src/napi_bridge_init.cc b/src/napi_bridge_init.cc index f147722..ae8462b 100644 --- a/src/napi_bridge_init.cc +++ b/src/napi_bridge_init.cc @@ -2044,16 +2044,20 @@ extern "C" int snapi_bridge_get_node_version(SnapiEnvState* env_state, uint32_t* // Object wrapping // ============================================================ +void NAPI_CDECL NoopGuestFinalizer(node_api_nogc_env /*env*/, void* /*data*/, void* /*hint*/) {} + extern "C" int snapi_bridge_wrap(SnapiEnvState* env_state, uint32_t obj_id, uint64_t native_data, - uint32_t* ref_out) { + int has_finalize_cb, uint32_t* ref_out) { auto* bridge_state = RequireEnvState(env_state); if (bridge_state == nullptr) return napi_invalid_arg; napi_env env = bridge_state->env; napi_value obj = LoadValue(*bridge_state, obj_id); if (!obj) return napi_invalid_arg; + node_api_basic_finalize finalize_cb = + has_finalize_cb ? NoopGuestFinalizer : nullptr; napi_ref ref = nullptr; napi_status s = napi_wrap(env, obj, (void*)(uintptr_t)native_data, - nullptr, nullptr, ref_out ? &ref : nullptr); + finalize_cb, nullptr, ref_out ? &ref : nullptr); if (s != napi_ok) return s; if (ref_out) *ref_out = StoreRef(*bridge_state, ref); return napi_ok; @@ -2086,16 +2090,16 @@ extern "C" int snapi_bridge_remove_wrap(SnapiEnvState* env_state, uint32_t obj_i } extern "C" int snapi_bridge_add_finalizer(SnapiEnvState* env_state, uint32_t obj_id, uint64_t data_val, - uint32_t* ref_out) { + int has_finalize_cb, uint32_t* ref_out) { auto* bridge_state = RequireEnvState(env_state); if (bridge_state == nullptr) return napi_invalid_arg; napi_env env = bridge_state->env; napi_value obj = LoadValue(*bridge_state, obj_id); if (!obj) return napi_invalid_arg; - // No actual WASM callback for finalizer; just register with nullptr callback + if (!has_finalize_cb) return napi_invalid_arg; napi_ref ref = nullptr; napi_status s = napi_add_finalizer(env, obj, (void*)(uintptr_t)data_val, - nullptr, nullptr, ref_out ? &ref : nullptr); + NoopGuestFinalizer, nullptr, ref_out ? &ref : nullptr); if (s != napi_ok) return s; if (ref_out) *ref_out = StoreRef(*bridge_state, ref); return napi_ok; diff --git a/src/snapi.rs b/src/snapi.rs index 373d4ef..2721c51 100644 --- a/src/snapi.rs +++ b/src/snapi.rs @@ -876,6 +876,7 @@ unsafe extern "C" { env: SnapiEnv, obj_id: u32, native_data: u64, + has_finalize_cb: i32, ref_out: *mut u32, ) -> i32; pub fn snapi_bridge_unwrap(env: SnapiEnv, obj_id: u32, data_out: *mut u64) -> i32; @@ -884,6 +885,7 @@ unsafe extern "C" { env: SnapiEnv, obj_id: u32, data_val: u64, + has_finalize_cb: i32, ref_out: *mut u32, ) -> i32; // Constructor From 0724abbb49c8e7fa5c2036e4a9f3fa0b2a6066d1 Mon Sep 17 00:00:00 2001 From: Sadhbh Code <80485211+sadhbh-c0d3@users.noreply.github.com> Date: Mon, 15 Jun 2026 18:59:22 +0100 Subject: [PATCH 2/2] Update src/guest/napi.rs Co-authored-by: Syrus Akbary --- src/guest/napi.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/guest/napi.rs b/src/guest/napi.rs index 7d59e19..3d18e28 100644 --- a/src/guest/napi.rs +++ b/src/guest/napi.rs @@ -4751,7 +4751,7 @@ fn guest_napi_wrap( ref_ptr: i32, ) -> i32 { let mut ref_out: u32 = 0; - let has_finalize_cb = if finalize_cb != 0 { 1 } else { 0 }; + let has_finalize_cb = (finalize_cb != 0) as i32; let s = if ref_ptr > 0 { unsafe { snapi_bridge_wrap(