summaryrefslogtreecommitdiff
path: root/ext/napi
diff options
context:
space:
mode:
authorDivy Srivastava <dj.srivastava23@gmail.com>2023-05-18 19:15:47 +0530
committerGitHub <noreply@github.com>2023-05-18 19:15:47 +0530
commitc3f7e6ed6ea2da6b8be5c7b29619eb51e0c9a6e3 (patch)
treedee07dbadf9dfe69bbfac707dde344f9528ef05a /ext/napi
parent695b5de6cb0cb4a10b95cbae99f2f19e5621a9eb (diff)
fix(cli/napi): handle finalizers (#19168)
Fixes https://github.com/denoland/deno/issues/17325
Diffstat (limited to 'ext/napi')
-rw-r--r--ext/napi/lib.rs44
1 files changed, 44 insertions, 0 deletions
diff --git a/ext/napi/lib.rs b/ext/napi/lib.rs
index 2e7ceed67..8365a5692 100644
--- a/ext/napi/lib.rs
+++ b/ext/napi/lib.rs
@@ -592,6 +592,50 @@ pub trait NapiPermissions {
-> std::result::Result<(), AnyError>;
}
+/// # Safety
+///
+/// This function is unsafe because it dereferences raw pointer Env.
+/// - The caller must ensure that the pointer is valid.
+/// - The caller must ensure that the pointer is not freed.
+pub unsafe fn weak_local(
+ env_ptr: *mut Env,
+ value: v8::Local<v8::Value>,
+ data: *mut c_void,
+ finalize_cb: napi_finalize,
+ finalize_hint: *mut c_void,
+) -> Option<v8::Local<v8::Value>> {
+ use std::cell::Cell;
+
+ let env = &mut *env_ptr;
+
+ let weak_ptr = Rc::new(Cell::new(None));
+ let scope = &mut env.scope();
+
+ let weak = v8::Weak::with_finalizer(
+ scope,
+ value,
+ Box::new({
+ let weak_ptr = weak_ptr.clone();
+ move |isolate| {
+ finalize_cb(env_ptr as _, data as _, finalize_hint as _);
+
+ // Self-deleting weak.
+ if let Some(weak_ptr) = weak_ptr.get() {
+ let weak: v8::Weak<v8::Value> =
+ unsafe { v8::Weak::from_raw(isolate, Some(weak_ptr)) };
+ drop(weak);
+ }
+ }
+ }),
+ );
+
+ let value = weak.to_local(scope);
+ let raw = weak.into_raw();
+ weak_ptr.set(raw);
+
+ value
+}
+
#[op(v8)]
fn op_napi_open<NP, 'scope>(
scope: &mut v8::HandleScope<'scope>,