summaryrefslogtreecommitdiff
path: root/ext/napi/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ext/napi/lib.rs')
-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>,