From 1f1a2e028f479efb9597a3d7b414a50ed269253c Mon Sep 17 00:00:00 2001 From: "K.J. Valencik" Date: Sun, 29 Nov 2020 21:43:05 -0500 Subject: [PATCH] feature(neon-runtime): Dynamic module loading --- crates/neon-macros/src/napi.rs | 6 +- crates/neon-runtime/Cargo.toml | 7 +- crates/neon-runtime/src/lib.rs | 1 - crates/neon-runtime/src/napi/array.rs | 14 +- crates/neon-runtime/src/napi/arraybuffer.rs | 10 +- .../src/napi/bindings/functions.rs | 204 ++++++++++++++++++ crates/neon-runtime/src/napi/bindings/mod.rs | 80 +++++++ .../neon-runtime/src/napi/bindings/types.rs | 154 +++++++++++++ crates/neon-runtime/src/napi/buffer.rs | 10 +- crates/neon-runtime/src/napi/call.rs | 34 +-- crates/neon-runtime/src/napi/convert.rs | 11 +- crates/neon-runtime/src/napi/error.rs | 43 ++-- crates/neon-runtime/src/napi/external.rs | 35 ++- crates/neon-runtime/src/napi/fun.rs | 18 +- crates/neon-runtime/src/napi/mod.rs | 3 + crates/neon-runtime/src/napi/object.rs | 59 +++-- crates/neon-runtime/src/napi/primitive.rs | 15 +- crates/neon-runtime/src/napi/raw.rs | 12 +- crates/neon-runtime/src/napi/scope.rs | 29 ++- crates/neon-runtime/src/napi/string.rs | 15 +- crates/neon-runtime/src/napi/tag.rs | 33 ++- src/context/internal.rs | 1 + src/lib.rs | 6 +- 23 files changed, 618 insertions(+), 182 deletions(-) create mode 100644 crates/neon-runtime/src/napi/bindings/functions.rs create mode 100644 crates/neon-runtime/src/napi/bindings/mod.rs create mode 100644 crates/neon-runtime/src/napi/bindings/types.rs diff --git a/crates/neon-macros/src/napi.rs b/crates/neon-macros/src/napi.rs index 55ebed48a..0d69ae0ed 100644 --- a/crates/neon-macros/src/napi.rs +++ b/crates/neon-macros/src/napi.rs @@ -15,9 +15,9 @@ pub(crate) fn main( #vis #sig { #[no_mangle] unsafe extern "C" fn napi_register_module_v1( - env: ::neon::macro_internal::runtime::nodejs_sys::napi_env, - m: ::neon::macro_internal::runtime::nodejs_sys::napi_value, - ) -> ::neon::macro_internal::runtime::nodejs_sys::napi_value { + env: ::neon::macro_internal::runtime::raw::Env, + m: ::neon::macro_internal::runtime::raw::Local, + ) -> ::neon::macro_internal::runtime::raw::Local { ::neon::macro_internal::initialize_module( env, ::std::mem::transmute(m), diff --git a/crates/neon-runtime/Cargo.toml b/crates/neon-runtime/Cargo.toml index 386614582..4c1c797d2 100644 --- a/crates/neon-runtime/Cargo.toml +++ b/crates/neon-runtime/Cargo.toml @@ -9,13 +9,16 @@ edition = "2018" [dependencies] cfg-if = "0.1.9" +libloading = { version = "0.6.5", optional = true } neon-sys = { version = "=0.5.3", path = "../neon-sys", optional = true } -nodejs-sys = { version = "0.7.0", optional = true } smallvec = "1.4.2" +[dev-dependencies] +nodejs-sys = "0.7.0" # Dev dependency for easy copying + [features] default = [] -napi = ["nodejs-sys"] +napi = ["libloading"] docs-only = ["neon-sys/docs-only"] [package.metadata.docs.rs] diff --git a/crates/neon-runtime/src/lib.rs b/crates/neon-runtime/src/lib.rs index db37f7e05..33272fb0e 100644 --- a/crates/neon-runtime/src/lib.rs +++ b/crates/neon-runtime/src/lib.rs @@ -5,7 +5,6 @@ use cfg_if::cfg_if; cfg_if! { if #[cfg(feature = "napi")] { - pub use nodejs_sys; pub mod napi; } } diff --git a/crates/neon-runtime/src/napi/array.rs b/crates/neon-runtime/src/napi/array.rs index f2411f95e..56c73a755 100644 --- a/crates/neon-runtime/src/napi/array.rs +++ b/crates/neon-runtime/src/napi/array.rs @@ -1,17 +1,17 @@ -//! Facilities for working with Array `napi_value`s. +//! Facilities for working with Array `value`s. use crate::raw::{Env, Local}; -use nodejs_sys as napi; +use crate::napi::bindings as napi; pub unsafe extern "C" fn new(out: &mut Local, env: Env, length: u32) { assert_eq!( - napi::napi_create_array_with_length(env, length as usize, out as *mut _), - napi::napi_status::napi_ok, + napi::create_array_with_length(env, length as usize, out as *mut _), + napi::Status::Ok, ); } -/// Gets the length of a `napi_value` containing a JavaScript Array. +/// Gets the length of a `value` containing a JavaScript Array. /// /// # Panics /// This function panics if `array` is not an Array, or if a previous n-api call caused a pending @@ -19,8 +19,8 @@ pub unsafe extern "C" fn new(out: &mut Local, env: Env, length: u32) { pub unsafe extern "C" fn len(env: Env, array: Local) -> u32 { let mut len = 0; assert_eq!( - napi::napi_get_array_length(env, array, &mut len as *mut _), - napi::napi_status::napi_ok + napi::get_array_length(env, array, &mut len as *mut _), + napi::Status::Ok ); len } diff --git a/crates/neon-runtime/src/napi/arraybuffer.rs b/crates/neon-runtime/src/napi/arraybuffer.rs index b09352cbb..9cb7ab47f 100644 --- a/crates/neon-runtime/src/napi/arraybuffer.rs +++ b/crates/neon-runtime/src/napi/arraybuffer.rs @@ -2,19 +2,19 @@ use crate::raw::{Env, Local}; use std::os::raw::c_void; use std::ptr::null_mut; -use nodejs_sys as napi; +use crate::napi::bindings as napi; pub unsafe extern "C" fn new(out: &mut Local, env: Env, size: u32) -> bool { - let status = napi::napi_create_arraybuffer(env, size as usize, null_mut(), out as *mut _); + let status = napi::create_arraybuffer(env, size as usize, null_mut(), out as *mut _); - status == napi::napi_status::napi_ok + status == napi::Status::Ok } pub unsafe extern "C" fn data<'a, 'b>(env: Env, base_out: &'a mut *mut c_void, obj: Local) -> usize { let mut size = 0; assert_eq!( - napi::napi_get_arraybuffer_info(env, obj, base_out as *mut _, &mut size as *mut _), - napi::napi_status::napi_ok, + napi::get_arraybuffer_info(env, obj, base_out as *mut _, &mut size as *mut _), + napi::Status::Ok, ); size } diff --git a/crates/neon-runtime/src/napi/bindings/functions.rs b/crates/neon-runtime/src/napi/bindings/functions.rs new file mode 100644 index 000000000..86626dd05 --- /dev/null +++ b/crates/neon-runtime/src/napi/bindings/functions.rs @@ -0,0 +1,204 @@ +#[cfg(windows)] +use libloading::os::windows::Library; +#[cfg(not(windows))] +use libloading::os::unix::Library; + +use std::os::raw::{c_char, c_void}; +use super::types::*; + +generate!(extern "C" { + fn get_undefined(env: Env, result: *mut Value) -> Status; + + fn get_null(env: Env, result: *mut Value) -> Status; + + fn get_global(env: Env, result: *mut Value) -> Status; + + fn get_boolean(env: Env, value: bool, result: *mut Value) -> Status; + + fn create_double(env: Env, value: f64, result: *mut Value) -> Status; + + fn create_object(env: Env, result: *mut Value) -> Status; + + fn get_value_bool(env: Env, value: Value, result: *mut bool) -> Status; + + fn get_value_double(env: Env, value: Value, result: *mut f64) -> Status; + + fn create_array_with_length(env: Env, length: usize, result: *mut Value) -> Status; + + fn get_array_length(env: Env, value: Value, result: *mut u32)-> Status; + + fn get_new_target(env: Env, cbinfo: CallbackInfo, result: *mut Value) -> Status; + + fn coerce_to_object(env: Env, value: Value, result: *mut Value) -> Status; + + fn coerce_to_string(env: Env, value: Value, result: *mut Value) -> Status; + + fn throw(env: Env, error: Value) -> Status; + + fn create_error(env: Env, code: Value, msg: Value, result: *mut Value) -> Status; + + fn get_and_clear_last_exception(env: Env, result: *mut Value) -> Status; + + fn is_exception_pending(env: Env, result: *mut bool) -> Status; + + fn get_value_external(env: Env, value: Value, result: *mut *mut c_void) -> Status; + + fn typeof_value(env: Env, value: Value, result: *mut ValueType) -> Status; + + fn close_escapable_handle_scope(env: Env, scope: EscapableHandleScope) -> Status; + + fn open_escapable_handle_scope(env: Env, result: *mut EscapableHandleScope) -> Status; + + fn open_handle_scope(env: Env, result: *mut HandleScope) -> Status; + + fn close_handle_scope(env: Env, scope: HandleScope) -> Status; + + fn is_arraybuffer(env: Env, value: Value, result: *mut bool) -> Status; + fn is_buffer(env: Env, value: Value, result: *mut bool) -> Status; + fn is_error(env: Env, value: Value, result: *mut bool) -> Status; + fn is_array(env: Env, value: Value, result: *mut bool) -> Status; + + fn get_value_string_utf8( + env: Env, + value: Value, + buf: *mut c_char, + bufsize: usize, + result: *mut usize, + ) -> Status; + + fn create_type_error( + env: Env, + code: Value, + msg: Value, + result: *mut Value, + ) -> Status; + + fn create_range_error( + env: Env, + code: Value, + msg: Value, + result: *mut Value, + ) -> Status; + + fn create_string_utf8( + env: Env, + str: *const c_char, + length: usize, + result: *mut Value, + ) -> Status; + + fn create_arraybuffer( + env: Env, + byte_length: usize, + data: *mut *mut c_void, + result: *mut Value, + ) -> Status; + + fn get_arraybuffer_info( + env: Env, + arraybuffer: Value, + data: *mut *mut c_void, + byte_length: *mut usize, + ) -> Status; + + fn create_buffer( + env: Env, + length: usize, + data: *mut *mut c_void, + result: *mut Value, + ) -> Status; + + fn get_buffer_info( + env: Env, + value: Value, + data: *mut *mut c_void, + length: *mut usize, + ) -> Status; + + fn get_cb_info( + env: Env, + cbinfo: CallbackInfo, + argc: *mut usize, + argv: *mut Value, + this_arg: *mut Value, + data: *mut *mut c_void, + ) -> Status; + + fn create_external( + env: Env, + data: *mut c_void, + finalize_cb: Finalize, + finalize_hint: *mut c_void, + result: *mut Value, + ) -> Status; + + fn new_instance( + env: Env, + constructor: Value, + argc: usize, + argv: *const Value, + result: *mut Value, + ) -> Status; + + fn call_function( + env: Env, + recv: Value, + func: Value, + argc: usize, + argv: *const Value, + result: *mut Value, + ) -> Status; + + fn create_function( + env: Env, + utf8name: *const c_char, + length: usize, + cb: Callback, + data: *mut c_void, + result: *mut Value, + ) -> Status; + + fn set_property( + env: Env, + object: Value, + key: Value, + value: Value, + ) -> Status; + + fn get_property( + env: Env, + object: Value, + key: Value, + result: *mut Value, + ) -> Status; + + fn set_element( + env: Env, + object: Value, + index: u32, + value: Value, + ) -> Status; + + fn get_element( + env: Env, + object: Value, + index: u32, + result: *mut Value, + ) -> Status; + + fn get_all_property_names( + env: Env, + object: Value, + key_mode: KeyCollectionMode, + key_filter: KeyFilter, + key_conversion: KeyConversion, + result: *mut Value, + ) -> Status; + + fn escape_handle( + env: Env, + scope: EscapableHandleScope, + escapee: Value, + result: *mut Value, + ) -> Status; +}); diff --git a/crates/neon-runtime/src/napi/bindings/mod.rs b/crates/neon-runtime/src/napi/bindings/mod.rs new file mode 100644 index 000000000..aa46a4922 --- /dev/null +++ b/crates/neon-runtime/src/napi/bindings/mod.rs @@ -0,0 +1,80 @@ +macro_rules! napi_name { + (typeof_value) => { + "napi_typeof" + }; + ($name:ident) => { + concat!("napi_", stringify!($name)) + }; +} + +macro_rules! generate { + (extern "C" { + $(fn $name:ident($($param:ident: $ptype:ty$(,)?)*) -> $rtype:ty;)+ + }) => { + pub(crate) struct Napi { + $( + $name: unsafe extern "C" fn( + $($param: $ptype,)* + ) -> $rtype, + )* + } + + pub(crate) unsafe fn load() -> Result<(), libloading::Error> { + let host = Library::this(); + #[cfg(windows)] + let host = host?; + + NAPI = Napi { + $( + $name: *host.get(napi_name!($name).as_bytes())?, + )* + }; + + Ok(()) + } + + $( + #[inline] + pub(crate) unsafe fn $name($($param: $ptype,)*) -> $rtype { + (NAPI.$name)($($param,)*) + } + )* + + fn panic_load() -> T { + panic!("Must load N-API bindings") + } + + static mut NAPI: Napi = { + $( + unsafe extern "C" fn $name($(_: $ptype,)*) -> $rtype { + panic_load() + } + )* + + Napi { + $( + $name, + )* + } + }; + }; +} + +use std::sync::Once; + +pub(crate) use functions::*; +pub(crate) use types::*; + +mod types; +mod functions; + +static SETUP: Once = Once::new(); + +/// Loads N-API symbols from host process. +/// Must be called at least once before using any functions in `neon-runtime` or +/// they will panic. +pub fn setup() { + SETUP.call_once(|| unsafe { + load().expect("Failed to load N-API symbols"); + }); +} diff --git a/crates/neon-runtime/src/napi/bindings/types.rs b/crates/neon-runtime/src/napi/bindings/types.rs new file mode 100644 index 000000000..8b22248f0 --- /dev/null +++ b/crates/neon-runtime/src/napi/bindings/types.rs @@ -0,0 +1,154 @@ +use std::ffi::c_void; + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Env__ { + _unused: [u8; 0], +} + +pub type Env = *mut Env__; + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Value__ { + _unused: [u8; 0], +} + +pub type Value = *mut Value__; + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct CallbackInfo__ { + _unused: [u8; 0], +} + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct EscapableHandleScope__ { + _unused: [u8; 0], +} +pub type EscapableHandleScope = *mut EscapableHandleScope__; + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct HandleScope__ { + _unused: [u8; 0], +} +pub type HandleScope = *mut HandleScope__; + +pub type CallbackInfo = *mut CallbackInfo__; + +pub(crate) type Callback = Option< + unsafe extern "C" fn(env: Env, info: CallbackInfo) -> Value, +>; + +pub(crate) type Finalize = Option< + unsafe extern "C" fn( + env: Env, + finalize_data: *mut c_void, + finalize_hint: *mut c_void, + ), +>; + +#[allow(dead_code)] +#[repr(u32)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub(crate) enum Status { + Ok = 0, + InvalidArg = 1, + ObjectExpected = 2, + StringExpected = 3, + NameExpected = 4, + FunctionExpected = 5, + NumberExpected = 6, + BooleanExpected = 7, + ArrayExpected = 8, + GenericFailure = 9, + PendingException = 10, + Cancelled = 11, + EscapeCalledTwice = 12, + HandleScopeMismatch = 13, + CallbackScopeMismatch = 14, + QueueFull = 15, + Closing = 16, + BigintExpected = 17, + DateExpected = 18, + ArraybufferExpected = 19, + DetachableArraybufferExpected = 20, + WouldDeadlock = 21, +} + +#[allow(dead_code)] +#[repr(u32)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub(crate) enum ValueType { + Undefined = 0, + Null = 1, + Boolean = 2, + Number = 3, + String = 4, + Symbol = 5, + Object = 6, + Function = 7, + External = 8, + BigInt = 9, +} + +#[allow(dead_code)] +#[repr(u32)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum KeyCollectionMode { + IncludePrototypes = 0, + OwnOnly = 1, +} + +#[allow(dead_code)] +#[repr(u32)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum KeyConversion { + KeepNumbers = 0, + NumbersToStrings = 1, +} + +#[repr(transparent)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub(crate) struct KeyFilter(pub ::std::os::raw::c_uint); + +#[allow(dead_code)] +impl KeyFilter { + pub(crate) const ALL_PROPERTIES: KeyFilter = KeyFilter(0); + pub(crate) const WRITABLE: KeyFilter = KeyFilter(1); + pub(crate) const CONFIGURABLE: KeyFilter = KeyFilter(4); + pub(crate) const SKIP_STRINGS: KeyFilter = KeyFilter(8); + pub(crate) const SKIP_SYMBOLS: KeyFilter = KeyFilter(16); +} + +impl std::ops::BitOr for KeyFilter { + type Output = Self; + #[inline] + fn bitor(self, other: Self) -> Self { + KeyFilter(self.0 | other.0) + } +} + +impl std::ops::BitOrAssign for KeyFilter { + #[inline] + fn bitor_assign(&mut self, rhs: KeyFilter) { + self.0 |= rhs.0; + } +} + +impl std::ops::BitAnd for KeyFilter { + type Output = Self; + #[inline] + fn bitand(self, other: Self) -> Self { + KeyFilter(self.0 & other.0) + } +} + +impl std::ops::BitAndAssign for KeyFilter { + #[inline] + fn bitand_assign(&mut self, rhs: KeyFilter) { + self.0 &= rhs.0; + } +} diff --git a/crates/neon-runtime/src/napi/buffer.rs b/crates/neon-runtime/src/napi/buffer.rs index 29f660789..3e033da60 100644 --- a/crates/neon-runtime/src/napi/buffer.rs +++ b/crates/neon-runtime/src/napi/buffer.rs @@ -2,12 +2,12 @@ use crate::raw::{Env, Local}; use std::os::raw::c_void; use std::ptr::null_mut; -use nodejs_sys as napi; +use crate::napi::bindings as napi; pub unsafe extern "C" fn new(env: Env, out: &mut Local, size: u32) -> bool { let mut bytes = null_mut(); - let status = napi::napi_create_buffer(env, size as usize, &mut bytes as *mut _, out as *mut _); - if status == napi::napi_status::napi_ok { + let status = napi::create_buffer(env, size as usize, &mut bytes as *mut _, out as *mut _); + if status == napi::Status::Ok { // zero-initialize it. If performance is critical, JsBuffer::uninitialized can be used // instead. std::ptr::write_bytes(bytes, 0, size as usize); @@ -22,8 +22,8 @@ pub unsafe extern "C" fn uninitialized(_out: &mut Local, _size: u32) -> bool { u pub unsafe extern "C" fn data<'a, 'b>(env: Env, base_out: &'a mut *mut c_void, obj: Local) -> usize { let mut size = 0; assert_eq!( - napi::napi_get_buffer_info(env, obj, base_out as *mut _, &mut size as *mut _), - napi::napi_status::napi_ok, + napi::get_buffer_info(env, obj, base_out as *mut _, &mut size as *mut _), + napi::Status::Ok, ); size } diff --git a/crates/neon-runtime/src/napi/call.rs b/crates/neon-runtime/src/napi/call.rs index 8007178b6..c4aee11e9 100644 --- a/crates/neon-runtime/src/napi/call.rs +++ b/crates/neon-runtime/src/napi/call.rs @@ -1,9 +1,11 @@ use std::mem::MaybeUninit; use std::os::raw::c_void; use std::ptr::null_mut; -use crate::raw::{FunctionCallbackInfo, Env, Local}; + use smallvec::{smallvec, SmallVec}; -use nodejs_sys as napi; + +use crate::raw::{FunctionCallbackInfo, Env, Local}; +use crate::napi::bindings as napi; #[repr(C)] pub struct CCallback { @@ -32,25 +34,25 @@ pub unsafe extern "C" fn current_isolate() -> Env { panic!("current_isolate won' pub unsafe extern "C" fn is_construct(env: Env, info: FunctionCallbackInfo) -> bool { let mut target: MaybeUninit = MaybeUninit::zeroed(); - let status = napi::napi_get_new_target( + let status = napi::get_new_target( env, info, target.as_mut_ptr() ); - assert_eq!(status, napi::napi_status::napi_ok); + assert_eq!(status, napi::Status::Ok); - // napi_get_new_target is guaranteed to assign to target, so it's initialized. + // get_new_target is guaranteed to assign to target, so it's initialized. let target: Local = target.assume_init(); - // By the napi_get_new_target contract, target will either be NULL if the current - // function was called without `new`, or a valid napi_value handle if the current + // By the get_new_target contract, target will either be NULL if the current + // function was called without `new`, or a valid value handle if the current // function was called with `new`. !target.is_null() } pub unsafe extern "C" fn this(env: Env, info: FunctionCallbackInfo, out: &mut Local) { - let status = napi::napi_get_cb_info( + let status = napi::get_cb_info( env, info, null_mut(), @@ -58,14 +60,14 @@ pub unsafe extern "C" fn this(env: Env, info: FunctionCallbackInfo, out: &mut Lo out as *mut _, null_mut(), ); - assert_eq!(status, napi::napi_status::napi_ok); + assert_eq!(status, napi::Status::Ok); } /// Mutates the `out` argument provided to refer to the associated data value of the -/// `napi_callback_info`. +/// `callback_info`. pub unsafe extern "C" fn data(env: Env, info: FunctionCallbackInfo, out: &mut *mut c_void) { let mut data = null_mut(); - let status = napi::napi_get_cb_info( + let status = napi::get_cb_info( env, info, null_mut(), @@ -73,7 +75,7 @@ pub unsafe extern "C" fn data(env: Env, info: FunctionCallbackInfo, out: &mut *m null_mut(), &mut data as *mut _, ); - if status == napi::napi_status::napi_ok { + if status == napi::Status::Ok { *out = data; } } @@ -81,7 +83,7 @@ pub unsafe extern "C" fn data(env: Env, info: FunctionCallbackInfo, out: &mut *m /// Gets the number of arguments passed to the function. pub unsafe extern "C" fn len(env: Env, info: FunctionCallbackInfo) -> i32 { let mut argc = 0usize; - let status = napi::napi_get_cb_info( + let status = napi::get_cb_info( env, info, &mut argc as *mut _, @@ -89,7 +91,7 @@ pub unsafe extern "C" fn len(env: Env, info: FunctionCallbackInfo) -> i32 { null_mut(), null_mut(), ); - assert_eq!(status, napi::napi_status::napi_ok); + assert_eq!(status, napi::Status::Ok); argc as i32 } @@ -98,7 +100,7 @@ pub unsafe extern "C" fn argv(env: Env, info: FunctionCallbackInfo) -> SmallVec< let len = len(env, info); let mut args = smallvec![null_mut(); len as usize]; let mut num_args = args.len(); - let status = napi::napi_get_cb_info( + let status = napi::get_cb_info( env, info, &mut num_args as *mut _, @@ -106,6 +108,6 @@ pub unsafe extern "C" fn argv(env: Env, info: FunctionCallbackInfo) -> SmallVec< null_mut(), null_mut(), ); - assert_eq!(status, napi::napi_status::napi_ok); + assert_eq!(status, napi::Status::Ok); args } diff --git a/crates/neon-runtime/src/napi/convert.rs b/crates/neon-runtime/src/napi/convert.rs index 585a1ee42..cecfbd20d 100644 --- a/crates/neon-runtime/src/napi/convert.rs +++ b/crates/neon-runtime/src/napi/convert.rs @@ -1,16 +1,15 @@ -use nodejs_sys as napi; - +use crate::napi::bindings as napi; use crate::raw::{Env, Local}; /// This API is currently unused, see https://github.com/neon-bindings/neon/issues/572 pub unsafe extern "C" fn to_object(out: &mut Local, env: Env, value: Local) -> bool { - let status = napi::napi_coerce_to_object(env, value, out as *mut _); + let status = napi::coerce_to_object(env, value, out as *mut _); - status == napi::napi_status::napi_ok + status == napi::Status::Ok } pub unsafe extern "C" fn to_string(out: &mut Local, env: Env, value: Local) -> bool { - let status = napi::napi_coerce_to_string(env, value, out as *mut _); + let status = napi::coerce_to_string(env, value, out as *mut _); - status == napi::napi_status::napi_ok + status == napi::Status::Ok } diff --git a/crates/neon-runtime/src/napi/error.rs b/crates/neon-runtime/src/napi/error.rs index dd95a592d..75dbc541c 100644 --- a/crates/neon-runtime/src/napi/error.rs +++ b/crates/neon-runtime/src/napi/error.rs @@ -1,16 +1,15 @@ use std::mem::MaybeUninit; use std::ptr; -use nodejs_sys as napi; - +use crate::napi::bindings as napi; use crate::raw::{Env, Local}; pub unsafe fn is_throwing(env: Env) -> bool { let mut b: MaybeUninit = MaybeUninit::zeroed(); - let status = napi::napi_is_exception_pending(env, b.as_mut_ptr()); + let status = napi::is_exception_pending(env, b.as_mut_ptr()); - assert_eq!(status, napi::napi_status::napi_ok); + assert_eq!(status, napi::Status::Ok); b.assume_init() } @@ -20,97 +19,97 @@ pub unsafe fn catch_error(env: Env, error: *mut Local) -> bool { return false; } - let status = napi::napi_get_and_clear_last_exception(env, error); + let status = napi::get_and_clear_last_exception(env, error); - assert_eq!(status, napi::napi_status::napi_ok); + assert_eq!(status, napi::Status::Ok); true } pub unsafe fn clear_exception(env: Env) { let mut result = MaybeUninit::uninit(); - let status = napi::napi_is_exception_pending(env, result.as_mut_ptr()); + let status = napi::is_exception_pending(env, result.as_mut_ptr()); - assert_eq!(status, napi::napi_status::napi_ok); + assert_eq!(status, napi::Status::Ok); if !result.assume_init() { return; } let mut result = MaybeUninit::uninit(); - let status = napi::napi_get_and_clear_last_exception(env, result.as_mut_ptr()); + let status = napi::get_and_clear_last_exception(env, result.as_mut_ptr()); - assert_eq!(status, napi::napi_status::napi_ok); + assert_eq!(status, napi::Status::Ok); } pub unsafe fn throw(env: Env, val: Local) { - let status = napi::napi_throw(env, val); + let status = napi::throw(env, val); - assert_eq!(status, napi::napi_status::napi_ok); + assert_eq!(status, napi::Status::Ok); } pub unsafe fn new_error(env: Env, out: &mut Local, msg: Local) { let mut result = MaybeUninit::uninit(); - let status = napi::napi_create_error( + let status = napi::create_error( env, ptr::null_mut(), msg, result.as_mut_ptr(), ); - assert_eq!(status, napi::napi_status::napi_ok); + assert_eq!(status, napi::Status::Ok); *out = result.assume_init(); } pub unsafe fn new_type_error(env: Env, out: &mut Local, msg: Local) { let mut result = MaybeUninit::uninit(); - let status = napi::napi_create_type_error( + let status = napi::create_type_error( env, ptr::null_mut(), msg, result.as_mut_ptr(), ); - assert_eq!(status, napi::napi_status::napi_ok); + assert_eq!(status, napi::Status::Ok); *out = result.assume_init(); } pub unsafe fn new_range_error(env: Env, out: &mut Local, msg: Local) { let mut result = MaybeUninit::uninit(); - let status = napi::napi_create_range_error( + let status = napi::create_range_error( env, ptr::null_mut(), msg, result.as_mut_ptr(), ); - assert_eq!(status, napi::napi_status::napi_ok); + assert_eq!(status, napi::Status::Ok); *out = result.assume_init(); } pub unsafe fn throw_error_from_utf8(env: Env, msg: *const u8, len: i32) { let mut out = MaybeUninit::uninit(); - let status = napi::napi_create_string_utf8( + let status = napi::create_string_utf8( env, msg as *const i8, len as usize, out.as_mut_ptr(), ); - assert_eq!(status, napi::napi_status::napi_ok); + assert_eq!(status, napi::Status::Ok); let mut err = MaybeUninit::uninit(); - let status = napi::napi_create_error( + let status = napi::create_error( env, ptr::null_mut(), out.assume_init(), err.as_mut_ptr(), ); - assert_eq!(status, napi::napi_status::napi_ok); + assert_eq!(status, napi::Status::Ok); throw(env, err.assume_init()); } diff --git a/crates/neon-runtime/src/napi/external.rs b/crates/neon-runtime/src/napi/external.rs index 1882a3771..0c1b6404f 100644 --- a/crates/neon-runtime/src/napi/external.rs +++ b/crates/neon-runtime/src/napi/external.rs @@ -1,15 +1,14 @@ use std::mem::MaybeUninit; use crate::raw::{Env, Local}; +use crate::napi::bindings as napi; -use nodejs_sys as napi; - -/// `finalize_external` is invoked immediately before a `napi_external` is garbage collected +/// `finalize_external` is invoked immediately before a `External` is garbage collected extern "C" fn finalize_external( - env: napi::napi_env, - // Raw pointer to a `Box` stored by a `napi_external` + env: Env, + // Raw pointer to a `Box` stored by a `External` data: *mut std::ffi::c_void, - // Pointer to a Rust `fn` stored in the `hint` parameter of a `napi_external` called + // Pointer to a Rust `fn` stored in the `hint` parameter of a `External` called // with the contents of `data` immediately before the value is garbage collected. hint: *mut std::ffi::c_void, ) { @@ -21,8 +20,8 @@ extern "C" fn finalize_external( } } -/// Returns a pointer to data stored in a `napi_external` -/// Safety: `deref` must only be called with `napi_external` created by that +/// Returns a pointer to data stored in a `External` +/// Safety: `deref` must only be called with `External` created by that /// module. Calling `deref` with an external created by another native module, /// even another neon module, is undefined behavior. /// https://github.com/neon-bindings/neon/issues/591 @@ -31,37 +30,37 @@ pub unsafe fn deref( local: Local, ) -> Option<*const T> { let mut result = MaybeUninit::uninit(); - let status = napi::napi_typeof( + let status = napi::typeof_value( env, local, result.as_mut_ptr(), ); - assert_eq!(status, napi::napi_status::napi_ok); + assert_eq!(status, napi::Status::Ok); let result = result.assume_init(); // Note: This only validates it is an external, not that it was created by // this module. In this future, this can be improved with type tagging: - // https://nodejs.org/api/n-api.html#n_api_napi_type_tag + // https://nodejs.org/api/n-api.html#n_api_type_tag // https://github.com/neon-bindings/neon/issues/591 - if result != napi::napi_valuetype::napi_external { + if result != napi::ValueType::External { return None; } let mut result = MaybeUninit::uninit(); - let status = napi::napi_get_value_external( + let status = napi::get_value_external( env, local, result.as_mut_ptr(), ); - assert_eq!(status, napi::napi_status::napi_ok); + assert_eq!(status, napi::Status::Ok); Some(result.assume_init() as *const _) } -/// Creates a `napi_external` from a Rust type +/// Creates a `External` from a Rust type pub unsafe fn create( env: Env, v: T, @@ -70,7 +69,7 @@ pub unsafe fn create( let v = Box::new(v); let mut result = MaybeUninit::uninit(); - let status = napi::napi_create_external( + let status = napi::create_external( env, Box::into_raw(v) as *mut _, Some(finalize_external::), @@ -80,9 +79,9 @@ pub unsafe fn create( result.as_mut_ptr(), ); - // `napi_create_external` will only fail if the VM is in a throwing state + // `create_external` will only fail if the VM is in a throwing state // or shutting down. - assert_eq!(status, napi::napi_status::napi_ok); + assert_eq!(status, napi::Status::Ok); result.assume_init() } diff --git a/crates/neon-runtime/src/napi/fun.rs b/crates/neon-runtime/src/napi/fun.rs index bdce0c012..1f6af65a9 100644 --- a/crates/neon-runtime/src/napi/fun.rs +++ b/crates/neon-runtime/src/napi/fun.rs @@ -1,16 +1,16 @@ //! Facilities for working with JS functions. -use crate::call::CCallback; -use crate::raw::{Env, Local}; use std::os::raw::c_void; use std::ptr::null; -use nodejs_sys as napi; +use crate::call::CCallback; +use crate::raw::{Env, Local}; +use crate::napi::bindings as napi; /// Mutates the `out` argument provided to refer to a newly created `v8::Function`. Returns /// `false` if the value couldn't be created. pub unsafe extern "C" fn new(out: &mut Local, env: Env, callback: CCallback) -> bool { - let status = napi::napi_create_function( + let status = napi::create_function( env, null(), 0, @@ -19,7 +19,7 @@ pub unsafe extern "C" fn new(out: &mut Local, env: Env, callback: CCallback) -> out as *mut Local, ); - status == napi::napi_status::napi_ok + status == napi::Status::Ok } pub unsafe extern "C" fn new_template(_out: &mut Local, _env: Env, _callback: CCallback) -> bool { @@ -31,13 +31,13 @@ pub unsafe extern "C" fn get_dynamic_callback(_env: Env, data: *mut c_void) -> * } pub unsafe extern "C" fn call(out: &mut Local, env: Env, fun: Local, this: Local, argc: i32, argv: *mut c_void) -> bool { - let status = napi::napi_call_function(env, this, fun, argc as usize, argv as *const _, out as *mut _); + let status = napi::call_function(env, this, fun, argc as usize, argv as *const _, out as *mut _); - status == napi::napi_status::napi_ok + status == napi::Status::Ok } pub unsafe extern "C" fn construct(out: &mut Local, env: Env, fun: Local, argc: i32, argv: *mut c_void) -> bool { - let status = napi::napi_new_instance(env, fun, argc as usize, argv as *const _, out as *mut _); + let status = napi::new_instance(env, fun, argc as usize, argv as *const _, out as *mut _); - status == napi::napi_status::napi_ok + status == napi::Status::Ok } diff --git a/crates/neon-runtime/src/napi/mod.rs b/crates/neon-runtime/src/napi/mod.rs index 70b42b931..6f2921010 100644 --- a/crates/neon-runtime/src/napi/mod.rs +++ b/crates/neon-runtime/src/napi/mod.rs @@ -16,3 +16,6 @@ pub mod string; pub mod tag; pub mod task; pub mod handler; + +mod bindings; +pub use bindings::*; diff --git a/crates/neon-runtime/src/napi/object.rs b/crates/neon-runtime/src/napi/object.rs index 171a5493d..55a4184f8 100644 --- a/crates/neon-runtime/src/napi/object.rs +++ b/crates/neon-runtime/src/napi/object.rs @@ -1,27 +1,26 @@ use std::mem::MaybeUninit; -use nodejs_sys as napi; - +use crate::napi::bindings as napi; use crate::raw::{Env, Local}; -/// Mutates the `out` argument to refer to a `napi_value` containing a newly created JavaScript Object. +/// Mutates the `out` argument to refer to a `value` containing a newly created JavaScript Object. pub unsafe extern "C" fn new(out: &mut Local, env: Env) { - napi::napi_create_object(env, out as *mut _); + napi::create_object(env, out as *mut _); } -/// Mutates the `out` argument to refer to a `napi_value` containing the own property names of the +/// Mutates the `out` argument to refer to a `value` containing the own property names of the /// `object` as a JavaScript Array. pub unsafe extern "C" fn get_own_property_names(out: &mut Local, env: Env, object: Local) -> bool { let mut property_names = MaybeUninit::uninit(); - if napi::napi_get_all_property_names( + if napi::get_all_property_names( env, object, - napi::napi_key_collection_mode::napi_key_own_only, - napi::napi_key_filter::napi_key_all_properties | napi::napi_key_filter::napi_key_skip_symbols, - napi::napi_key_conversion::napi_key_numbers_to_strings, + napi::KeyCollectionMode::OwnOnly, + napi::KeyFilter::ALL_PROPERTIES | napi::KeyFilter::SKIP_SYMBOLS, + napi::KeyConversion::NumbersToStrings, property_names.as_mut_ptr(), - ) != napi::napi_status::napi_ok { + ) != napi::Status::Ok { return false; } @@ -37,12 +36,12 @@ pub unsafe extern "C" fn get_isolate(_obj: Local) -> Env { /// Mutate the `out` argument to refer to the value at `index` in the given `object`. Returns `false` if the value couldn't be retrieved. pub unsafe extern "C" fn get_index(out: &mut Local, env: Env, object: Local, index: u32) -> bool { - let status = napi::napi_get_element(env, object, index, out as *mut _); + let status = napi::get_element(env, object, index, out as *mut _); - status == napi::napi_status::napi_ok + status == napi::Status::Ok } -/// Sets the key value of a `napi_value` at the `index` provided. Returns `true` if the set +/// Sets the key value of a `value` at the `index` provided. Returns `true` if the set /// succeeded. /// /// The `out` parameter and the return value contain the same information for historical reasons, @@ -50,8 +49,8 @@ pub unsafe extern "C" fn get_index(out: &mut Local, env: Env, object: Local, ind /// /// [discussion]: https://github.com/neon-bindings/neon/pull/458#discussion_r344827965 pub unsafe extern "C" fn set_index(out: &mut bool, env: Env, object: Local, index: u32, val: Local) -> bool { - let status = napi::napi_set_element(env, object, index, val); - *out = status == napi::napi_status::napi_ok; + let status = napi::set_element(env, object, index, val); + *out = status == napi::Status::Ok; *out } @@ -62,15 +61,15 @@ pub unsafe extern "C" fn get_string(env: Env, out: &mut Local, object: Local, ke // Not using `crate::string::new()` because it requires a _reference_ to a Local, // while we only have uninitialized memory. - if napi::napi_create_string_utf8(env, key as *const i8, len as usize, key_val.as_mut_ptr()) - != napi::napi_status::napi_ok + if napi::create_string_utf8(env, key as *const i8, len as usize, key_val.as_mut_ptr()) + != napi::Status::Ok { return false; } - // Not using napi_get_named_property() because the `key` may not be null terminated. - if napi::napi_get_property(env, object, key_val.assume_init(), out as *mut _) - != napi::napi_status::napi_ok + // Not using get_named_property() because the `key` may not be null terminated. + if napi::get_property(env, object, key_val.assume_init(), out as *mut _) + != napi::Status::Ok { return false; } @@ -78,7 +77,7 @@ pub unsafe extern "C" fn get_string(env: Env, out: &mut Local, object: Local, ke true } -/// Sets the key value of a `napi_value` at a named key. Returns `true` if the set succeeded. +/// Sets the key value of a `value` at a named key. Returns `true` if the set succeeded. /// /// The `out` parameter and the return value contain the same information for historical reasons, /// see [discussion]. @@ -89,15 +88,15 @@ pub unsafe extern "C" fn set_string(env: Env, out: &mut bool, object: Local, key *out = true; - if napi::napi_create_string_utf8(env, key as *const i8, len as usize, key_val.as_mut_ptr()) - != napi::napi_status::napi_ok + if napi::create_string_utf8(env, key as *const i8, len as usize, key_val.as_mut_ptr()) + != napi::Status::Ok { *out = false; return false; } - if napi::napi_set_property(env, object, key_val.assume_init(), val) - != napi::napi_status::napi_ok + if napi::set_property(env, object, key_val.assume_init(), val) + != napi::Status::Ok { *out = false; return false; @@ -109,20 +108,20 @@ pub unsafe extern "C" fn set_string(env: Env, out: &mut bool, object: Local, key /// Mutates `out` to refer to the value of the property of `object` named by the `key` value. /// Returns false if the value couldn't be retrieved. pub unsafe extern "C" fn get(out: &mut Local, env: Env, object: Local, key: Local) -> bool { - let status = napi::napi_get_property(env, object, key, out as *mut _); + let status = napi::get_property(env, object, key, out as *mut _); - status == napi::napi_status::napi_ok + status == napi::Status::Ok } -/// Sets the property value of an `napi_value` object, named by another `napi_value` `key`. Returns `true` if the set succeeded. +/// Sets the property value of an `value` object, named by another `value` `key`. Returns `true` if the set succeeded. /// /// The `out` parameter and the return value contain the same information for historical reasons, /// see [discussion]. /// /// [discussion]: https://github.com/neon-bindings/neon/pull/458#discussion_r344827965 pub unsafe extern "C" fn set(out: &mut bool, env: Env, object: Local, key: Local, val: Local) -> bool { - let status = napi::napi_set_property(env, object, key, val); - *out = status == napi::napi_status::napi_ok; + let status = napi::set_property(env, object, key, val); + *out = status == napi::Status::Ok; *out } diff --git a/crates/neon-runtime/src/napi/primitive.rs b/crates/neon-runtime/src/napi/primitive.rs index 904d47ac5..74e591e33 100644 --- a/crates/neon-runtime/src/napi/primitive.rs +++ b/crates/neon-runtime/src/napi/primitive.rs @@ -1,27 +1,26 @@ use crate::raw::{Local, Env}; - -use nodejs_sys as napi; +use crate::napi::bindings as napi; /// Mutates the `out` argument provided to refer to the global `undefined` object. pub unsafe extern "C" fn undefined(out: &mut Local, env: Env) { - napi::napi_get_undefined(env, out as *mut Local); + napi::get_undefined(env, out as *mut Local); } /// Mutates the `out` argument provided to refer to the global `null` object. pub unsafe extern "C" fn null(out: &mut Local, env: Env) { - napi::napi_get_null(env, out as *mut Local); + napi::get_null(env, out as *mut Local); } /// Mutates the `out` argument provided to refer to one of the global `true` or `false` objects. pub unsafe extern "C" fn boolean(out: &mut Local, env: Env, b: bool) { - napi::napi_get_boolean(env, b, out as *mut Local); + napi::get_boolean(env, b, out as *mut Local); } /// Get the boolean value out of a `Local` object. If the `Local` object does not contain a /// boolean, this function panics. pub unsafe extern "C" fn boolean_value(env: Env, p: Local) -> bool { let mut value = false; - assert_eq!(napi::napi_get_value_bool(env, p, &mut value as *mut bool), napi::napi_status::napi_ok); + assert_eq!(napi::get_value_bool(env, p, &mut value as *mut bool), napi::Status::Ok); value } @@ -38,13 +37,13 @@ pub unsafe extern "C" fn integer_value(_p: Local) -> i64 { unimplemented!() } /// Mutates the `out` argument provided to refer to a newly created `Local` containing a /// JavaScript number. pub unsafe extern "C" fn number(out: &mut Local, env: Env, v: f64) { - napi::napi_create_double(env, v, out as *mut Local); + napi::create_double(env, v, out as *mut Local); } /// Gets the underlying value of an `Local` object containing a JavaScript number. Panics if /// the given `Local` is not a number. pub unsafe extern "C" fn number_value(env: Env, p: Local) -> f64 { let mut value = 0.0; - assert_eq!(napi::napi_get_value_double(env, p, &mut value as *mut f64), napi::napi_status::napi_ok); + assert_eq!(napi::get_value_double(env, p, &mut value as *mut f64), napi::Status::Ok); return value; } diff --git a/crates/neon-runtime/src/napi/raw.rs b/crates/neon-runtime/src/napi/raw.rs index c0815244e..e16e3aee4 100644 --- a/crates/neon-runtime/src/napi/raw.rs +++ b/crates/neon-runtime/src/napi/raw.rs @@ -1,17 +1,17 @@ use std::ptr; -use nodejs_sys as napi; +use crate::napi::bindings as napi; -pub type Local = napi::napi_value; +pub type Local = napi::Value; -pub type FunctionCallbackInfo = napi::napi_callback_info; +pub type FunctionCallbackInfo = napi::CallbackInfo; -pub type Env = napi::napi_env; +pub type Env = napi::Env; #[repr(C)] #[derive(Clone, Copy)] pub struct HandleScope { - pub word: napi::napi_handle_scope + pub word: napi::HandleScope } impl HandleScope { @@ -21,7 +21,7 @@ impl HandleScope { #[repr(C)] #[derive(Clone, Copy)] pub struct EscapableHandleScope { - pub word: napi::napi_escapable_handle_scope + pub word: napi::EscapableHandleScope } impl EscapableHandleScope { diff --git a/crates/neon-runtime/src/napi/scope.rs b/crates/neon-runtime/src/napi/scope.rs index 663e79d28..ae2ce617c 100644 --- a/crates/neon-runtime/src/napi/scope.rs +++ b/crates/neon-runtime/src/napi/scope.rs @@ -1,11 +1,8 @@ use std::mem::MaybeUninit; -use nodejs_sys as napi; - -use crate::raw::{Env, HandleScope, EscapableHandleScope, InheritedHandleScope}; - -type Local = napi::napi_value; +use crate::raw::{Env, HandleScope, EscapableHandleScope, InheritedHandleScope, Local}; +use crate::napi::bindings as napi; // TODO: This leaves a lot of room for UB; we can have a cleaner // implementation for N-API. @@ -19,16 +16,16 @@ impl Root for HandleScope { unsafe fn allocate() -> Self { HandleScope::new() } unsafe fn enter(&mut self, env: Env) { let mut scope = MaybeUninit::uninit(); - let status = napi::napi_open_handle_scope(env, scope.as_mut_ptr()); + let status = napi::open_handle_scope(env, scope.as_mut_ptr()); - assert_eq!(status, napi::napi_status::napi_ok); + assert_eq!(status, napi::Status::Ok); self.word = scope.assume_init(); } unsafe fn exit(&mut self, env: Env) { - let status = napi::napi_close_handle_scope(env, self.word); + let status = napi::close_handle_scope(env, self.word); - assert_eq!(status, napi::napi_status::napi_ok); + assert_eq!(status, napi::Status::Ok); } } @@ -36,16 +33,16 @@ impl Root for EscapableHandleScope { unsafe fn allocate() -> Self { EscapableHandleScope::new() } unsafe fn enter(&mut self, env: Env) { let mut scope = MaybeUninit::uninit(); - let status = napi::napi_open_escapable_handle_scope(env, scope.as_mut_ptr()); + let status = napi::open_escapable_handle_scope(env, scope.as_mut_ptr()); - assert_eq!(status, napi::napi_status::napi_ok); + assert_eq!(status, napi::Status::Ok); self.word = scope.assume_init(); } unsafe fn exit(&mut self, env: Env) { - let status = napi::napi_close_escapable_handle_scope(env, self.word); + let status = napi::close_escapable_handle_scope(env, self.word); - assert_eq!(status, napi::napi_status::napi_ok); + assert_eq!(status, napi::Status::Ok); } } @@ -56,11 +53,11 @@ impl Root for InheritedHandleScope { } pub unsafe extern "C" fn escape(env: Env, out: &mut Local, scope: *mut EscapableHandleScope, value: Local) { - let status = napi::napi_escape_handle(env, (*scope).word, value, out as *mut _); + let status = napi::escape_handle(env, (*scope).word, value, out as *mut _); - assert_eq!(status, napi::napi_status::napi_ok); + assert_eq!(status, napi::Status::Ok); } pub unsafe extern "C" fn get_global(env: Env, out: &mut Local) { - assert_eq!(napi::napi_get_global(env, out as *mut _), napi::napi_status::napi_ok); + assert_eq!(crate::napi::bindings::get_global(env, out as *mut _), napi::Status::Ok); } diff --git a/crates/neon-runtime/src/napi/string.rs b/crates/neon-runtime/src/napi/string.rs index 2f496c4a4..15b449dc4 100644 --- a/crates/neon-runtime/src/napi/string.rs +++ b/crates/neon-runtime/src/napi/string.rs @@ -1,24 +1,23 @@ use std::mem::MaybeUninit; use std::ptr; -use nodejs_sys as napi; - use crate::raw::{Env, Local}; +use crate::napi::bindings as napi; pub unsafe fn new(out: &mut Local, env: Env, data: *const u8, len: i32) -> bool { - let status = napi::napi_create_string_utf8( + let status = napi::create_string_utf8( env, data as *const i8, len as usize, out, ); - status == napi::napi_status::napi_ok + status == napi::Status::Ok } pub unsafe extern "C" fn utf8_len(env: Env, value: Local) -> isize { let mut len = MaybeUninit::uninit(); - let status = napi::napi_get_value_string_utf8( + let status = napi::get_value_string_utf8( env, value, ptr::null_mut(), @@ -26,14 +25,14 @@ pub unsafe extern "C" fn utf8_len(env: Env, value: Local) -> isize { len.as_mut_ptr(), ); - assert_eq!(status, napi::napi_status::napi_ok); + assert_eq!(status, napi::Status::Ok); len.assume_init() as isize } pub unsafe extern "C" fn data(env: Env, out: *mut u8, len: isize, value: Local) -> isize { let mut read = MaybeUninit::uninit(); - let status = napi::napi_get_value_string_utf8( + let status = napi::get_value_string_utf8( env, value, out as *mut i8, @@ -41,7 +40,7 @@ pub unsafe extern "C" fn data(env: Env, out: *mut u8, len: isize, value: Local) read.as_mut_ptr(), ); - assert_eq!(status, napi::napi_status::napi_ok); + assert_eq!(status, napi::Status::Ok); read.assume_init() as isize } diff --git a/crates/neon-runtime/src/napi/tag.rs b/crates/neon-runtime/src/napi/tag.rs index fd2e6bd41..690fb35ee 100644 --- a/crates/neon-runtime/src/napi/tag.rs +++ b/crates/neon-runtime/src/napi/tag.rs @@ -1,67 +1,66 @@ use crate::raw::{Env, Local}; +use crate::napi::bindings as napi; -use nodejs_sys as napi; - -/// Return true if an `napi_value` `val` has the expected value type. -unsafe fn is_type(env: Env, val: Local, expect: napi::napi_valuetype) -> bool { - let mut actual = napi::napi_valuetype::napi_undefined; - assert_eq!(napi::napi_typeof(env, val, &mut actual as *mut _), napi::napi_status::napi_ok); +/// Return true if an `value` `val` has the expected value type. +unsafe fn is_type(env: Env, val: Local, expect: napi::ValueType) -> bool { + let mut actual = napi::ValueType::Undefined; + assert_eq!(napi::typeof_value(env, val, &mut actual as *mut _), napi::Status::Ok); actual == expect } pub unsafe extern "C" fn is_undefined(env: Env, val: Local) -> bool { - is_type(env, val, napi::napi_valuetype::napi_undefined) + is_type(env, val, napi::ValueType::Undefined) } pub unsafe extern "C" fn is_null(env: Env, val: Local) -> bool { - is_type(env, val, napi::napi_valuetype::napi_null) + is_type(env, val, napi::ValueType::Null) } /// Is `val` a JavaScript number? pub unsafe extern "C" fn is_number(env: Env, val: Local) -> bool { - is_type(env, val, napi::napi_valuetype::napi_number) + is_type(env, val, napi::ValueType::Number) } /// Is `val` a JavaScript boolean? pub unsafe extern "C" fn is_boolean(env: Env, val: Local) -> bool { - is_type(env, val, napi::napi_valuetype::napi_boolean) + is_type(env, val, napi::ValueType::Boolean) } /// Is `val` a JavaScript string? pub unsafe extern "C" fn is_string(env: Env, val: Local) -> bool { - is_type(env, val, napi::napi_valuetype::napi_string) + is_type(env, val, napi::ValueType::String) } pub unsafe extern "C" fn is_object(env: Env, val: Local) -> bool { - is_type(env, val, napi::napi_valuetype::napi_object) + is_type(env, val, napi::ValueType::Object) } pub unsafe extern "C" fn is_array(env: Env, val: Local) -> bool { let mut result = false; - assert_eq!(napi::napi_is_array(env, val, &mut result as *mut _), napi::napi_status::napi_ok); + assert_eq!(napi::is_array(env, val, &mut result as *mut _), napi::Status::Ok); result } pub unsafe extern "C" fn is_function(env: Env, val: Local) -> bool { - is_type(env, val, napi::napi_valuetype::napi_function) + is_type(env, val, napi::ValueType::Function) } pub unsafe extern "C" fn is_error(env: Env, val: Local) -> bool { let mut result = false; - assert_eq!(napi::napi_is_error(env, val, &mut result as *mut _), napi::napi_status::napi_ok); + assert_eq!(napi::is_error(env, val, &mut result as *mut _), napi::Status::Ok); result } /// Is `val` a Node.js Buffer instance? pub unsafe extern "C" fn is_buffer(env: Env, val: Local) -> bool { let mut result = false; - assert_eq!(napi::napi_is_buffer(env, val, &mut result as *mut _), napi::napi_status::napi_ok); + assert_eq!(napi::is_buffer(env, val, &mut result as *mut _), napi::Status::Ok); result } /// Is `val` an ArrayBuffer instance? pub unsafe extern "C" fn is_arraybuffer(env: Env, val: Local) -> bool { let mut result = false; - assert_eq!(napi::napi_is_arraybuffer(env, val, &mut result as *mut _), napi::napi_status::napi_ok); + assert_eq!(napi::is_arraybuffer(env, val, &mut result as *mut _), napi::Status::Ok); result } diff --git a/src/context/internal.rs b/src/context/internal.rs index 602394357..3788bc5f4 100644 --- a/src/context/internal.rs +++ b/src/context/internal.rs @@ -233,6 +233,7 @@ pub fn initialize_module(exports: Handle, init: fn(ModuleContext) -> N #[cfg(feature = "napi-runtime")] pub fn initialize_module(env: raw::Env, exports: Handle, init: fn(ModuleContext) -> NeonResult<()>) { + neon_runtime::setup(); ModuleContext::with(Env(env), exports, |cx| { let _ = init(cx); }); diff --git a/src/lib.rs b/src/lib.rs index f62118f99..053a405d8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -67,9 +67,9 @@ macro_rules! register_module { (|$module:pat| $init:block) => { #[no_mangle] pub unsafe extern "C" fn napi_register_module_v1( - env: $crate::macro_internal::runtime::nodejs_sys::napi_env, - m: $crate::macro_internal::runtime::nodejs_sys::napi_value - ) -> $crate::macro_internal::runtime::nodejs_sys::napi_value + env: $crate::macro_internal::runtime::raw::Env, + m: $crate::macro_internal::runtime::raw::Local + ) -> $crate::macro_internal::runtime::raw::Local { // Suppress the default Rust panic hook, which prints diagnostics to stderr. #[cfg(not(feature = "default-panic-hook"))]