feat(napi): implement add_finalizer for JsObject
This commit is contained in:
parent
74256bcae7
commit
c621986ce5
1 changed files with 78 additions and 5 deletions
|
@ -1,13 +1,86 @@
|
||||||
use super::Value;
|
|
||||||
#[cfg(feature = "napi6")]
|
|
||||||
use crate::sys;
|
|
||||||
#[cfg(feature = "napi6")]
|
|
||||||
use crate::{Error, Result};
|
|
||||||
#[cfg(feature = "napi6")]
|
#[cfg(feature = "napi6")]
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
#[cfg(feature = "napi5")]
|
||||||
|
use std::ffi::c_void;
|
||||||
|
#[cfg(feature = "napi5")]
|
||||||
|
use std::ptr;
|
||||||
|
|
||||||
|
#[cfg(feature = "napi5")]
|
||||||
|
use super::check_status;
|
||||||
|
use super::Value;
|
||||||
|
#[cfg(feature = "napi5")]
|
||||||
|
use crate::sys;
|
||||||
|
#[cfg(feature = "napi5")]
|
||||||
|
use crate::Env;
|
||||||
|
#[cfg(feature = "napi6")]
|
||||||
|
use crate::{Error, Result};
|
||||||
|
|
||||||
pub struct JsObject(pub(crate) Value);
|
pub struct JsObject(pub(crate) Value);
|
||||||
|
|
||||||
|
#[cfg(feature = "napi5")]
|
||||||
|
pub struct FinalizeContext<T: 'static, Hint: 'static> {
|
||||||
|
pub env: Env,
|
||||||
|
pub value: T,
|
||||||
|
pub hint: Hint,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "napi5")]
|
||||||
|
impl JsObject {
|
||||||
|
pub fn add_finalizer<T, Hint, F>(
|
||||||
|
&mut self,
|
||||||
|
native: T,
|
||||||
|
finalize_hint: Hint,
|
||||||
|
finalize_cb: F,
|
||||||
|
) -> Result<()>
|
||||||
|
where
|
||||||
|
T: 'static,
|
||||||
|
Hint: 'static,
|
||||||
|
F: FnOnce(FinalizeContext<T, Hint>),
|
||||||
|
{
|
||||||
|
let mut maybe_ref = ptr::null_mut();
|
||||||
|
check_status!(unsafe {
|
||||||
|
sys::napi_add_finalizer(
|
||||||
|
self.0.env,
|
||||||
|
self.0.value,
|
||||||
|
Box::leak(Box::new((native, finalize_cb, maybe_ref))) as *mut _ as *mut c_void,
|
||||||
|
Some(
|
||||||
|
finalize_callback::<T, Hint, F>
|
||||||
|
as unsafe extern "C" fn(
|
||||||
|
env: sys::napi_env,
|
||||||
|
finalize_data: *mut c_void,
|
||||||
|
finalize_hint: *mut c_void,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Box::leak(Box::new(finalize_hint)) as *mut _ as *mut c_void,
|
||||||
|
&mut maybe_ref,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "napi5")]
|
||||||
|
unsafe extern "C" fn finalize_callback<T, Hint, F>(
|
||||||
|
raw_env: sys::napi_env,
|
||||||
|
finalize_data: *mut c_void,
|
||||||
|
finalize_hint: *mut c_void,
|
||||||
|
) where
|
||||||
|
T: 'static,
|
||||||
|
Hint: 'static,
|
||||||
|
F: FnOnce(FinalizeContext<T, Hint>),
|
||||||
|
{
|
||||||
|
let (value, callback, raw_ref) = *Box::from_raw(finalize_data as *mut (T, F, sys::napi_ref));
|
||||||
|
let hint = *Box::from_raw(finalize_hint as *mut Hint);
|
||||||
|
let env = Env::from_raw(raw_env);
|
||||||
|
callback(FinalizeContext { value, hint, env });
|
||||||
|
if !raw_ref.is_null() {
|
||||||
|
let status = sys::napi_delete_reference(raw_env, raw_ref);
|
||||||
|
debug_assert!(
|
||||||
|
status == sys::Status::napi_ok,
|
||||||
|
"Delete reference in finalize callback failed"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "napi6")]
|
#[cfg(feature = "napi6")]
|
||||||
pub enum KeyCollectionMode {
|
pub enum KeyCollectionMode {
|
||||||
IncludePrototypes,
|
IncludePrototypes,
|
||||||
|
|
Loading…
Reference in a new issue