/
githubmirror
/
deno
Обзор
Документация
Войти
/
githubmirror
/
deno
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
tests/napi/src/lib.rs
213 строк
5 KB
Bartek Iwańczuk
test: add edge case and worker termination tests for Node-API (#32986)
25 мар 2026, 19:26
Не верифицирован
25 мар 2026, 19:26
bf581bc
Код
Авторство
О чём код?
// Copyright 2018-2026 the Deno authors. MIT license. #![allow(clippy::all, reason = "test napi code")] #![allow(clippy::print_stdout, reason = "test napi code")] #![allow(clippy::print_stderr, reason = "test napi code")] #![allow(clippy::undocumented_unsafe_blocks, reason = "test napi code")] // napi_sys declares functions as `pub safe fn` inside `unsafe extern "C"` blocks // on non-windows, so `unsafe { napi_call(...) }` wrappers become redundant. #![allow(unused_unsafe, reason = "napi_sys safe fn in unsafe extern blocks")] use std::ffi::c_void; use napi_sys::*; pub mod array; pub mod arraybuffer; pub mod r#async; pub mod bigint; pub mod buffer; pub mod callback; pub mod callback_scope; pub mod cleanup_hook_async; pub mod coerce; pub mod dataview; pub mod date; pub mod env; pub mod error; pub mod exception; pub mod fatal; pub mod finalizer; pub mod general; pub mod handle_scope; pub mod instance_data; pub mod make_callback; pub mod mem; pub mod numbers; pub mod object; pub mod object_wrap; pub mod primitives; pub mod promise; pub mod properties; pub mod reference; pub mod strings; pub mod symbol; pub mod tsfn; pub mod typedarray; pub mod uv; #[macro_export] macro_rules! cstr { ($s: literal) => {{ std::ffi::CString::new($s).unwrap().into_raw() }}; } #[macro_export] macro_rules! assert_napi_ok { ($call: expr) => {{ assert_eq!( { #[allow( unused_unsafe, reason = "napi_sys safe fn in unsafe extern blocks" )] unsafe { $call } }, napi_sys::Status::napi_ok ); }}; } #[macro_export] macro_rules! napi_get_callback_info { ($env: expr, $callback_info: expr, $size: literal) => {{ let mut args = [std::ptr::null_mut(); $size]; let mut argc = $size; let mut this = std::ptr::null_mut(); crate::assert_napi_ok!(napi_get_cb_info( $env, $callback_info, &mut argc, args.as_mut_ptr(), &mut this, std::ptr::null_mut(), )); (args, argc, this) }}; } #[macro_export] macro_rules! napi_new_property { ($env: expr, $name: expr, $value: expr) => { napi_property_descriptor { utf8name: concat!($name, "\0").as_ptr() as *const std::os::raw::c_char, name: std::ptr::null_mut(), method: Some($value), getter: None, setter: None, data: std::ptr::null_mut(), attributes: 0, value: std::ptr::null_mut(), } }; } extern "C" fn cleanup(arg: *mut c_void) { println!("cleanup({})", arg as i64); } extern "C" fn remove_this_hook(arg: *mut c_void) { let env = arg as napi_env; unsafe { napi_remove_env_cleanup_hook(env, Some(remove_this_hook), arg) }; } static SECRET: i64 = 42; static WRONG_SECRET: i64 = 17; static THIRD_SECRET: i64 = 18; extern "C" fn install_cleanup_hook( env: napi_env, info: napi_callback_info, ) -> napi_value { let (_args, argc, _) = napi_get_callback_info!(env, info, 1); assert_eq!(argc, 0); unsafe { napi_add_env_cleanup_hook(env, Some(cleanup), WRONG_SECRET as *mut c_void); napi_add_env_cleanup_hook(env, Some(cleanup), SECRET as *mut c_void); napi_add_env_cleanup_hook(env, Some(cleanup), THIRD_SECRET as *mut c_void); napi_add_env_cleanup_hook(env, Some(remove_this_hook), env as *mut c_void); napi_remove_env_cleanup_hook( env, Some(cleanup), WRONG_SECRET as *mut c_void, ); } std::ptr::null_mut() } pub fn init_cleanup_hook(env: napi_env, exports: napi_value) { let properties = &[napi_new_property!( env, "installCleanupHook", install_cleanup_hook )]; assert_napi_ok!(napi_define_properties( env, exports, properties.len(), properties.as_ptr() )); } #[unsafe(no_mangle)] unsafe extern "C" fn napi_register_module_v1( env: napi_env, _: napi_value, ) -> napi_value { unsafe { #[cfg(windows)] napi_sys::setup(); libuv_sys_lite::setup(); } // We create a fresh exports object and leave the passed // exports object empty. // // https://github.com/denoland/deno/issues/17349 let mut exports = std::ptr::null_mut(); assert_napi_ok!(napi_create_object(env, &mut exports)); strings::init(env, exports); numbers::init(env, exports); typedarray::init(env, exports); arraybuffer::init(env, exports); array::init(env, exports); env::init(env, exports); error::init(env, exports); finalizer::init(env, exports); primitives::init(env, exports); properties::init(env, exports); promise::init(env, exports); coerce::init(env, exports); object_wrap::init(env, exports); callback::init(env, exports); r#async::init(env, exports); date::init(env, exports); tsfn::init(env, exports); mem::init(env, exports); bigint::init(env, exports); symbol::init(env, exports); make_callback::init(env, exports); object::init(env, exports); uv::init(env, exports); instance_data::init(env, exports); buffer::init(env, exports); dataview::init(env, exports); general::init(env, exports); handle_scope::init(env, exports); reference::init(env, exports); exception::init(env, exports); callback_scope::init(env, exports); fatal::init(env, exports); cleanup_hook_async::init(env, exports); init_cleanup_hook(env, exports); exports }