diff --git a/napi-derive/src/lib.rs b/napi-derive/src/lib.rs index afd9d3c6..cda575d5 100644 --- a/napi-derive/src/lib.rs +++ b/napi-derive/src/lib.rs @@ -108,42 +108,33 @@ pub fn js_function(attr: TokenStream, input: TokenStream) -> TokenStream { &mut raw_this, ptr::null_mut(), ); - has_error = has_error && (Status::from(status) == Status::Ok); + debug_assert!(Status::from(status) == Status::Ok, "napi_get_cb_info failed"); } let mut env = Env::from_raw(raw_env); - let call_ctx = CallContext::new(&mut env, cb_info, raw_this, &raw_args, #arg_len_span, argc as usize); - let result = call_ctx.and_then(|ctx| { - match panic::catch_unwind(AssertUnwindSafe(move || #new_fn_name(ctx))) { - Ok(result) => result, + match CallContext::new(&mut env, cb_info, raw_this, &raw_args, #arg_len_span, argc as usize) + .and_then(|ctx| panic::catch_unwind(AssertUnwindSafe(move || #new_fn_name(ctx))).map_err(|e| { + let message = { + if let Some(string) = e.downcast_ref::() { + string.clone() + } else if let Some(string) = e.downcast_ref::<&str>() { + string.to_string() + } else { + format!("panic from Rust code: {:?}", e) + } + }; + Error::from_reason(message) + }).and_then(|v| v)) + { + Ok(v) => v.raw_value(), Err(e) => { - let message = { - if let Some(string) = e.downcast_ref::() { - string.clone() - } else if let Some(string) = e.downcast_ref::<&str>() { - string.to_string() - } else { - format!("panic from Rust code: {:?}", e) - } - }; - Err(Error { status: Status::GenericFailure, reason: message }) + let message = format!("{}", e); + unsafe { + napi::sys::napi_throw_error(raw_env, ptr::null(), CString::from_vec_unchecked(message.into()).as_ptr() as *const c_char); + } + ptr::null_mut() } } - }); - has_error = has_error && result.is_err(); - - match result { - Ok(result) => result.raw_value(), - Err(e) => { - let message = format!("{}", e); - unsafe { - napi::sys::napi_throw_error(raw_env, ptr::null(), CString::from_vec_unchecked(message.into()).as_ptr() as *const c_char); - } - let mut undefined = ptr::null_mut(); - unsafe { napi::sys::napi_get_undefined(raw_env, &mut undefined) }; - undefined - } - } } }; // Hand the output tokens back to the compiler diff --git a/napi/src/async_work.rs b/napi/src/async_work.rs index c4d98ccb..d65fdf7f 100644 --- a/napi/src/async_work.rs +++ b/napi/src/async_work.rs @@ -13,7 +13,6 @@ pub struct AsyncWork { } impl AsyncWork { - #[inline] pub fn run(env: sys::napi_env, task: T, deferred: sys::napi_deferred) -> Result<()> { let mut raw_resource = ptr::null_mut(); check_status(unsafe { sys::napi_create_object(env, &mut raw_resource) })?; diff --git a/napi/src/call_context.rs b/napi/src/call_context.rs index 1f10f99f..d75a7164 100644 --- a/napi/src/call_context.rs +++ b/napi/src/call_context.rs @@ -13,7 +13,6 @@ pub struct CallContext<'env, T: NapiValue = JsUnknown> { } impl<'env, T: NapiValue> CallContext<'env, T> { - #[inline] pub fn new( env: &'env Env, callback_info: sys::napi_callback_info, @@ -32,7 +31,6 @@ impl<'env, T: NapiValue> CallContext<'env, T> { }) } - #[inline] pub fn get(&self, index: usize) -> Result { if index + 1 > self.arg_len { Err(Error { @@ -40,11 +38,13 @@ impl<'env, T: NapiValue> CallContext<'env, T> { reason: "Arguments index out of range".to_owned(), }) } else { - ArgType::from_raw(self.env.0, self.args[index]) + Ok(ArgType::from_raw_without_typecheck( + self.env.0, + self.args[index], + )) } } - #[inline] pub fn try_get(&self, index: usize) -> Result> { if index + 1 > self.arg_len { Err(Error { diff --git a/napi/src/env.rs b/napi/src/env.rs index 5220c4f1..c470bb68 100644 --- a/napi/src/env.rs +++ b/napi/src/env.rs @@ -34,12 +34,10 @@ pub type Callback = extern "C" fn(sys::napi_env, sys::napi_callback_info) -> sys pub struct Env(pub(crate) sys::napi_env); impl Env { - #[inline] pub fn from_raw(env: sys::napi_env) -> Self { Env(env) } - #[inline] pub fn get_undefined(&self) -> Result { let mut raw_value = ptr::null_mut(); let status = unsafe { sys::napi_get_undefined(self.0, &mut raw_value) }; @@ -47,23 +45,18 @@ impl Env { Ok(JsUndefined::from_raw_unchecked(self.0, raw_value)) } - #[inline] pub fn get_null(&self) -> Result { let mut raw_value = ptr::null_mut(); - let status = unsafe { sys::napi_get_null(self.0, &mut raw_value) }; - check_status(status)?; + check_status(unsafe { sys::napi_get_null(self.0, &mut raw_value) })?; Ok(JsNull::from_raw_unchecked(self.0, raw_value)) } - #[inline] pub fn get_boolean(&self, value: bool) -> Result { let mut raw_value = ptr::null_mut(); - let status = unsafe { sys::napi_get_boolean(self.0, value, &mut raw_value) }; - check_status(status)?; + check_status(unsafe { sys::napi_get_boolean(self.0, value, &mut raw_value) })?; Ok(JsBoolean::from_raw_unchecked(self.0, raw_value)) } - #[inline] pub fn create_int32(&self, int: i32) -> Result { let mut raw_value = ptr::null_mut(); check_status(unsafe { @@ -72,7 +65,6 @@ impl Env { Ok(JsNumber::from_raw_unchecked(self.0, raw_value)) } - #[inline] pub fn create_int64(&self, int: i64) -> Result { let mut raw_value = ptr::null_mut(); check_status(unsafe { @@ -81,14 +73,12 @@ impl Env { Ok(JsNumber::from_raw_unchecked(self.0, raw_value)) } - #[inline] pub fn create_uint32(&self, number: u32) -> Result { let mut raw_value = ptr::null_mut(); check_status(unsafe { sys::napi_create_uint32(self.0, number, &mut raw_value) })?; Ok(JsNumber::from_raw_unchecked(self.0, raw_value)) } - #[inline] pub fn create_double(&self, double: f64) -> Result { let mut raw_value = ptr::null_mut(); check_status(unsafe { @@ -98,7 +88,6 @@ impl Env { } #[cfg(napi6)] - #[inline] /// [n_api_napi_create_bigint_int64](https://nodejs.org/api/n-api.html#n_api_napi_create_bigint_int64) pub fn create_bigint_from_i64(&self, value: i64) -> Result { let mut raw_value = ptr::null_mut(); @@ -107,7 +96,6 @@ impl Env { } #[cfg(napi6)] - #[inline] pub fn create_bigint_from_u64(&self, value: u64) -> Result { let mut raw_value = ptr::null_mut(); check_status(unsafe { sys::napi_create_bigint_uint64(self.0, value, &mut raw_value) })?; @@ -115,7 +103,6 @@ impl Env { } #[cfg(napi6)] - #[inline] pub fn create_bigint_from_i128(&self, value: i128) -> Result { let mut raw_value = ptr::null_mut(); let sign_bit = if value > 0 { 0 } else { 1 }; @@ -127,7 +114,6 @@ impl Env { } #[cfg(napi6)] - #[inline] pub fn create_bigint_from_u128(&self, value: u128) -> Result { let mut raw_value = ptr::null_mut(); let words = &value as *const u128 as *const u64; @@ -136,7 +122,6 @@ impl Env { } #[cfg(napi6)] - #[inline] /// [n_api_napi_create_bigint_words](https://nodejs.org/api/n-api.html#n_api_napi_create_bigint_words) /// The resulting BigInt will be negative when sign_bit is true. pub fn create_bigint_from_words(&self, sign_bit: bool, words: Vec) -> Result { @@ -157,34 +142,28 @@ impl Env { Ok(JsBigint::from_raw_unchecked(self.0, raw_value, len as _)) } - #[inline] pub fn create_string(&self, s: &str) -> Result { self.create_string_from_chars(s.as_ptr() as *const _, s.len() as u64) } - #[inline] pub fn create_string_from_std(&self, s: String) -> Result { self.create_string_from_chars(s.as_ptr() as *const _, s.len() as u64) } - #[inline] pub fn create_string_from_vec_u8(&self, bytes: Vec) -> Result { self.create_string_from_chars(bytes.as_ptr() as *const _, bytes.len() as u64) } - #[inline] pub fn create_string_from_vec_i8(&self, bytes: Vec) -> Result { self.create_string_from_chars(bytes.as_ptr(), bytes.len() as u64) } - #[inline] fn create_string_from_chars(&self, data_ptr: *const c_char, len: u64) -> Result { let mut raw_value = ptr::null_mut(); check_status(unsafe { sys::napi_create_string_utf8(self.0, data_ptr, len, &mut raw_value) })?; Ok(JsString::from_raw_unchecked(self.0, raw_value)) } - #[inline] pub fn create_string_utf16(&self, chars: &[u16]) -> Result { let mut raw_value = ptr::null_mut(); check_status(unsafe { @@ -193,7 +172,6 @@ impl Env { Ok(JsString::from_raw_unchecked(self.0, raw_value)) } - #[inline] pub fn create_string_latin1(&self, chars: &[u8]) -> Result { let mut raw_value = ptr::null_mut(); check_status(unsafe { @@ -207,14 +185,12 @@ impl Env { Ok(JsString::from_raw_unchecked(self.0, raw_value)) } - #[inline] pub fn create_symbol_from_js_string(&self, description: JsString) -> Result { let mut result = ptr::null_mut(); check_status(unsafe { sys::napi_create_symbol(self.0, description.0.value, &mut result) })?; Ok(JsSymbol::from_raw_unchecked(self.0, result)) } - #[inline] pub fn create_symbol(&self, description: Option<&str>) -> Result { let mut result = ptr::null_mut(); check_status(unsafe { @@ -230,14 +206,12 @@ impl Env { Ok(JsSymbol::from_raw_unchecked(self.0, result)) } - #[inline] pub fn create_object(&self) -> Result { let mut raw_value = ptr::null_mut(); check_status(unsafe { sys::napi_create_object(self.0, &mut raw_value) })?; Ok(JsObject::from_raw_unchecked(self.0, raw_value)) } - #[inline] pub fn create_array_with_length(&self, length: usize) -> Result { let mut raw_value = ptr::null_mut(); check_status(unsafe { @@ -246,7 +220,6 @@ impl Env { Ok(JsObject::from_raw_unchecked(self.0, raw_value)) } - #[inline] pub fn create_buffer(&self, length: u64) -> Result { let mut raw_value = ptr::null_mut(); let mut data = Vec::with_capacity(length as usize); @@ -264,7 +237,6 @@ impl Env { )) } - #[inline] pub fn create_buffer_with_data(&self, mut data: Vec) -> Result { let length = data.len() as u64; let mut raw_value = ptr::null_mut(); @@ -290,7 +262,6 @@ impl Env { )) } - #[inline] pub fn create_arraybuffer(&self, length: u64) -> Result { let mut raw_value = ptr::null_mut(); let mut data = Vec::with_capacity(length as usize); @@ -305,7 +276,6 @@ impl Env { Ok(array_buffer) } - #[inline] pub fn create_arraybuffer_with_data(&self, data: Vec) -> Result { let length = data.len() as u64; let mut raw_value = ptr::null_mut(); @@ -329,7 +299,6 @@ impl Env { Ok(array_buffer) } - #[inline] pub fn create_function(&self, name: &str, callback: Callback) -> Result { let mut raw_result = ptr::null_mut(); check_status(unsafe { @@ -346,14 +315,12 @@ impl Env { Ok(JsFunction::from_raw_unchecked(self.0, raw_result)) } - #[inline] pub fn throw(&self, error: Error) -> Result<()> { let err_value = self.create_error(error)?.0.value; check_status(unsafe { sys::napi_throw(self.0, err_value) })?; Ok(()) } - #[inline] pub fn throw_error(&self, msg: &str) -> Result<()> { check_status(unsafe { sys::napi_throw_error( @@ -364,7 +331,6 @@ impl Env { }) } - #[inline] pub fn create_reference(&self, value: T) -> Result> { let mut raw_ref = ptr::null_mut(); let initial_ref_count = 1; @@ -375,7 +341,6 @@ impl Env { Ok(Ref::new(self.0, raw_ref)) } - #[inline] pub fn get_reference_value(&self, reference: &Ref) -> Result { let mut raw_value = ptr::null_mut(); check_status(unsafe { @@ -385,7 +350,6 @@ impl Env { T::from_raw(self.0, raw_value) } - #[inline] pub fn define_class( &self, name: &str, @@ -414,7 +378,6 @@ impl Env { Ok(JsFunction::from_raw_unchecked(self.0, raw_result)) } - #[inline] pub fn wrap(&self, js_object: &mut JsObject, native_object: T) -> Result<()> { check_status(unsafe { sys::napi_wrap( @@ -428,7 +391,6 @@ impl Env { }) } - #[inline] pub fn unwrap(&self, js_object: &JsObject) -> Result<&mut T> { unsafe { let mut unknown_tagged_object: *mut c_void = ptr::null_mut(); @@ -454,7 +416,6 @@ impl Env { } } - #[inline] pub fn drop_wrapped(&self, js_object: JsObject) -> Result<()> { unsafe { let mut unknown_tagged_object: *mut c_void = ptr::null_mut(); @@ -479,7 +440,6 @@ impl Env { } } - #[inline] pub fn create_external(&self, native_object: T) -> Result { let mut object_value = ptr::null_mut(); check_status(unsafe { @@ -494,7 +454,6 @@ impl Env { Ok(JsExternal::from_raw_unchecked(self.0, object_value)) } - #[inline] pub fn get_value_external(&self, js_external: &JsExternal) -> Result<&mut T> { unsafe { let mut unknown_tagged_object = ptr::null_mut(); @@ -521,7 +480,6 @@ impl Env { } } - #[inline] pub fn create_error(&self, e: Error) -> Result { let reason = e.reason; let reason_string = self.create_string(reason.as_str())?; @@ -532,7 +490,6 @@ impl Env { Ok(JsObject::from_raw_unchecked(self.0, result)) } - #[inline] pub fn spawn(&self, task: T) -> Result { let mut raw_promise = ptr::null_mut(); let mut raw_deferred = ptr::null_mut(); @@ -542,14 +499,12 @@ impl Env { Ok(JsObject::from_raw_unchecked(self.0, raw_promise)) } - #[inline] pub fn get_global(&self) -> Result { let mut raw_global = ptr::null_mut(); check_status(unsafe { sys::napi_get_global(self.0, &mut raw_global) })?; Ok(JsObject::from_raw_unchecked(self.0, raw_global)) } - #[inline] pub fn get_napi_version(&self) -> Result { let global = self.get_global()?; let process: JsObject = global.get_named_property("process")?; @@ -562,7 +517,6 @@ impl Env { } #[cfg(napi2)] - #[inline] pub fn get_uv_event_loop(&self) -> Result<*mut sys::uv_loop_s> { let mut uv_loop: *mut sys::uv_loop_s = ptr::null_mut(); check_status(unsafe { sys::napi_get_uv_event_loop(self.0, &mut uv_loop) })?; @@ -570,7 +524,6 @@ impl Env { } #[cfg(all(feature = "libuv", napi4))] - #[inline] pub fn execute< T: 'static + Send, V: 'static + NapiValue, @@ -595,7 +548,6 @@ impl Env { } #[cfg(all(feature = "tokio_rt", napi4))] - #[inline] pub fn execute_tokio_future< T: 'static + Send, V: 'static + NapiValue, @@ -646,7 +598,6 @@ impl Env { /// } /// ``` #[cfg(feature = "serde-json")] - #[inline] pub fn to_js_value(&self, node: &T) -> Result where T: Serialize, @@ -672,7 +623,6 @@ impl Env { /// } /// #[cfg(feature = "serde-json")] - #[inline] pub fn from_js_value(&self, value: V) -> Result where T: DeserializeOwned + ?Sized, @@ -687,7 +637,6 @@ impl Env { T::deserialize(&mut de) } - #[inline] pub fn strict_equals(&self, a: A, b: B) -> Result { let mut result = false; check_status(unsafe { @@ -696,7 +645,6 @@ impl Env { Ok(result) } - #[inline] pub fn get_node_version(&self) -> Result { let mut result = ptr::null(); check_status(unsafe { sys::napi_get_node_version(self.0, &mut result) })?; diff --git a/napi/src/js_values/arraybuffer.rs b/napi/src/js_values/arraybuffer.rs index a9ef12a8..eca15128 100644 --- a/napi/src/js_values/arraybuffer.rs +++ b/napi/src/js_values/arraybuffer.rs @@ -1,7 +1,7 @@ use std::convert::TryFrom; use std::ptr; -use super::{JsNumber, JsObject, JsString, JsUnknown, NapiValue, Value, ValueType}; +use super::{JsNumber, JsObject, JsString, JsUnknown, NapiValue, Status, Value, ValueType}; use crate::error::check_status; use crate::{sys, Error, Result}; @@ -153,6 +153,25 @@ impl NapiValue for JsArrayBuffer { len, }) } + + fn from_raw_without_typecheck(env: sys::napi_env, value: sys::napi_value) -> Self { + let mut data = ptr::null_mut(); + let mut len: u64 = 0; + let status = unsafe { sys::napi_get_arraybuffer_info(env, value, &mut data, &mut len) }; + debug_assert!( + Status::from(status) == Status::Ok, + "napi_get_arraybuffer_info failed" + ); + JsArrayBuffer { + value: JsObject(Value { + env, + value, + value_type: ValueType::Object, + }), + data: data as *const u8, + len, + } + } } impl TryFrom for JsArrayBuffer { diff --git a/napi/src/js_values/bigint.rs b/napi/src/js_values/bigint.rs index 3bb47a67..3242953d 100644 --- a/napi/src/js_values/bigint.rs +++ b/napi/src/js_values/bigint.rs @@ -153,6 +153,31 @@ impl NapiValue for JsBigint { word_count, }) } + + fn from_raw_without_typecheck(env: sys::napi_env, value: sys::napi_value) -> Self { + let mut word_count: u64 = 0; + let status = unsafe { + sys::napi_get_value_bigint_words( + env, + value, + ptr::null_mut(), + &mut word_count, + ptr::null_mut(), + ) + }; + debug_assert!( + Status::from(status) == Status::Ok, + "napi_get_value_bigint_words failed" + ); + JsBigint { + raw: Value { + env, + value, + value_type: ValueType::Bigint, + }, + word_count, + } + } } /// The BigInt will be converted losslessly when the value is over what an int64 could hold. diff --git a/napi/src/js_values/buffer.rs b/napi/src/js_values/buffer.rs index 6b461b3f..15e54c49 100644 --- a/napi/src/js_values/buffer.rs +++ b/napi/src/js_values/buffer.rs @@ -3,7 +3,7 @@ use std::ops::Deref; use std::ptr; use std::slice; -use super::{JsNumber, JsObject, JsString, JsUnknown, NapiValue, Value, ValueType}; +use super::{JsNumber, JsObject, JsString, JsUnknown, NapiValue, Status, Value, ValueType}; use crate::error::check_status; use crate::{sys, Error, Result}; @@ -157,6 +157,24 @@ impl NapiValue for JsBuffer { data: unsafe { slice::from_raw_parts_mut(data as *mut _, len as usize) }, }) } + + fn from_raw_without_typecheck(env: sys::napi_env, value: sys::napi_value) -> Self { + let mut data = ptr::null_mut(); + let mut len: u64 = 0; + let status = unsafe { sys::napi_get_buffer_info(env, value, &mut data, &mut len) }; + debug_assert!( + Status::from(status) == Status::Ok, + "napi_get_buffer_info failed" + ); + JsBuffer { + value: JsObject(Value { + env, + value, + value_type: ValueType::Object, + }), + data: unsafe { slice::from_raw_parts_mut(data as *mut _, len as usize) }, + } + } } impl AsRef<[u8]> for JsBuffer { diff --git a/napi/src/js_values/either.rs b/napi/src/js_values/either.rs index 55413d92..abb7b248 100644 --- a/napi/src/js_values/either.rs +++ b/napi/src/js_values/either.rs @@ -22,6 +22,10 @@ impl NapiValue for Either { .or_else(|_| B::from_raw(env, value).map(Self::B)) } + fn from_raw_without_typecheck(env: sys::napi_env, value: sys::napi_value) -> Either { + Self::from_raw(env, value).unwrap() + } + fn raw_value(&self) -> sys::napi_value { match self { Either::A(v) => v.raw_value(), diff --git a/napi/src/js_values/mod.rs b/napi/src/js_values/mod.rs index d7f59773..cc6b211f 100644 --- a/napi/src/js_values/mod.rs +++ b/napi/src/js_values/mod.rs @@ -91,6 +91,14 @@ macro_rules! impl_napi_value_trait { fn raw_value(&self) -> sys::napi_value { self.0.value } + + fn from_raw_without_typecheck(env: sys::napi_env, value: sys::napi_value) -> $js_value { + $js_value(Value { + env, + value, + value_type: $value_type, + }) + } } impl $js_value { @@ -223,6 +231,8 @@ macro_rules! impl_js_value_methods { pub trait NapiValue: Sized { fn from_raw(env: sys::napi_env, value: sys::napi_value) -> Result; + fn from_raw_without_typecheck(env: sys::napi_env, value: sys::napi_value) -> Self; + fn raw_value(&self) -> sys::napi_value; } @@ -258,6 +268,14 @@ impl NapiValue for JsUnknown { })) } + fn from_raw_without_typecheck(env: sys::napi_env, value: sys::napi_value) -> Self { + JsUnknown(Value { + env, + value, + value_type: Unknown, + }) + } + fn raw_value(&self) -> sys::napi_value { self.0.value } diff --git a/napi/src/js_values/string.rs b/napi/src/js_values/string.rs index 6190bd78..9065e5e4 100644 --- a/napi/src/js_values/string.rs +++ b/napi/src/js_values/string.rs @@ -15,7 +15,6 @@ use crate::{sys, Error, Result, Status}; pub struct JsString(pub(crate) Value); impl JsString { - #[inline] pub fn utf8_len(&self) -> Result { let mut length = 0; check_status(unsafe { @@ -24,7 +23,6 @@ impl JsString { Ok(length as usize) } - #[inline] pub fn latin1_len(&self) -> Result { let mut length = 0; check_status(unsafe { @@ -35,7 +33,6 @@ impl JsString { } impl JsString { - #[inline] pub fn get_utf8(&self) -> Result<&[u8]> { let mut written_char_count: u64 = 0; let len = self.utf8_len()? + 1; @@ -57,7 +54,6 @@ impl JsString { } } - #[inline] pub fn get_latin1(&self) -> Result<(&[u8], usize)> { let mut written_char_count: u64 = 0; let len = self.latin1_len()? + 1; diff --git a/napi/src/lib.rs b/napi/src/lib.rs index a94e85ce..663d39ac 100644 --- a/napi/src/lib.rs +++ b/napi/src/lib.rs @@ -70,9 +70,9 @@ //! ``` //! #[derive(Serialize, Debug, Deserialize)] //! struct AnObject { -//! a: u32, -//! b: Vec, -//! c: String, +//! a: u32, +//! b: Vec, +//! c: String, //! } //! //! #[js_function(1)] diff --git a/napi/src/promise.rs b/napi/src/promise.rs index 4aeec4a8..e222d477 100644 --- a/napi/src/promise.rs +++ b/napi/src/promise.rs @@ -16,7 +16,6 @@ pub struct FuturePromise { unsafe impl Send for FuturePromise {} impl FuturePromise { - #[inline] pub fn create( env: sys::napi_env, raw_deferred: sys::napi_deferred, @@ -42,7 +41,6 @@ impl FuturePromise { }) } - #[inline] pub(crate) fn start(self) -> Result { let mut tsfn_value = ptr::null_mut(); let async_resource_name = self.async_resource_name;