From 2d47969d08584a763b78418cca3b6ce57f010614 Mon Sep 17 00:00:00 2001 From: LongYinan Date: Thu, 19 Nov 2020 00:08:00 +0800 Subject: [PATCH 1/2] fix(napi): CString issues --- napi-derive/src/lib.rs | 2 +- napi/src/env.rs | 6 +----- napi/src/js_values/mod.rs | 13 +++++-------- napi/src/js_values/object_property.rs | 2 +- napi/src/lib.rs | 2 +- 5 files changed, 9 insertions(+), 16 deletions(-) diff --git a/napi-derive/src/lib.rs b/napi-derive/src/lib.rs index 744bbf35..6954c61b 100644 --- a/napi-derive/src/lib.rs +++ b/napi-derive/src/lib.rs @@ -204,7 +204,7 @@ fn get_execute_js_code( 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); + napi::sys::napi_throw_error(raw_env, ptr::null(), CString::from_vec_unchecked(message.into()).into_raw()); } ptr::null_mut() } diff --git a/napi/src/env.rs b/napi/src/env.rs index 462744b9..16c842f2 100644 --- a/napi/src/env.rs +++ b/napi/src/env.rs @@ -368,11 +368,7 @@ impl Env { pub fn throw_error(&self, msg: &str) -> Result<()> { check_status(unsafe { - sys::napi_throw_error( - self.0, - ptr::null(), - CString::from_vec_unchecked(msg.into()).as_ptr() as *const _, - ) + sys::napi_throw_error(self.0, ptr::null(), CString::new(msg)?.into_raw()) }) } diff --git a/napi/src/js_values/mod.rs b/napi/src/js_values/mod.rs index 65387f5f..6b476b54 100644 --- a/napi/src/js_values/mod.rs +++ b/napi/src/js_values/mod.rs @@ -257,7 +257,7 @@ macro_rules! impl_object_methods { where T: NapiValue, { - let key = CString::new(name.to_owned())?; + let key = CString::new(name)?; check_status(unsafe { sys::napi_set_named_property(self.0.env, self.0.value, key.as_ptr(), value.raw()) }) @@ -273,12 +273,9 @@ macro_rules! impl_object_methods { })?; T::from_raw(self.0.env, raw_value) } - pub fn has_named_property(&self, name: S) -> Result - where - S: AsRef, - { + pub fn has_named_property(&self, name: &str) -> Result { let mut result = false; - let key = CString::new(name.as_ref())?; + let key = CString::new(name)?; check_status(unsafe { sys::napi_has_named_property(self.0.env, self.0.value, key.as_ptr(), &mut result) })?; @@ -299,7 +296,7 @@ macro_rules! impl_object_methods { let key_str = CString::new(name)?; let mut js_key = ptr::null_mut(); check_status(unsafe { - sys::napi_create_string_utf8(self.0.env, key_str.as_ptr(), name.len() as _, &mut js_key) + sys::napi_create_string_utf8(self.0.env, key_str.as_ptr(), name.len(), &mut js_key) })?; check_status(unsafe { sys::napi_delete_property(self.0.env, self.0.value, js_key, &mut result) @@ -311,7 +308,7 @@ macro_rules! impl_object_methods { let string = CString::new(key)?; let mut js_key = ptr::null_mut(); check_status(unsafe { - sys::napi_create_string_utf8(self.0.env, string.as_ptr(), key.len() as _, &mut js_key) + sys::napi_create_string_utf8(self.0.env, string.as_ptr(), key.len(), &mut js_key) })?; check_status(unsafe { sys::napi_has_own_property(self.0.env, self.0.value, js_key, &mut result) diff --git a/napi/src/js_values/object_property.rs b/napi/src/js_values/object_property.rs index f0c45390..fff003f8 100644 --- a/napi/src/js_values/object_property.rs +++ b/napi/src/js_values/object_property.rs @@ -37,7 +37,7 @@ impl<'env> Property<'env> { let string_value = CString::new(name)?; let mut result = ptr::null_mut(); check_status(unsafe { - sys::napi_create_string_utf8(env.0, string_value.as_ptr(), name.len() as _, &mut result) + sys::napi_create_string_utf8(env.0, string_value.as_ptr(), name.len(), &mut result) })?; Ok(Property { name, diff --git a/napi/src/lib.rs b/napi/src/lib.rs index be89dead..eac95756 100644 --- a/napi/src/lib.rs +++ b/napi/src/lib.rs @@ -188,7 +188,7 @@ macro_rules! register_module { raw_env, ptr::null(), CString::from_vec_unchecked(format!("Error initializing module: {}", e).into()) - .as_ptr() as *const _, + .into_raw() as *const _, ) }; ptr::null_mut() From 781ff8dc1484c3884fdde88009e01cbd03c786d9 Mon Sep 17 00:00:00 2001 From: LongYinan Date: Fri, 20 Nov 2020 00:07:13 +0800 Subject: [PATCH 2/2] refactor(napi): make NapiTrait to be unsafe close https://github.com/napi-rs/napi-rs/issues/299 --- napi-derive/src/lib.rs | 8 ++--- napi/src/async_work.rs | 2 +- napi/src/call_context.rs | 10 +++--- napi/src/env.rs | 50 +++++++++++++-------------- napi/src/js_values/arraybuffer.rs | 6 ++-- napi/src/js_values/bigint.rs | 40 ++++++++++----------- napi/src/js_values/buffer.rs | 2 +- napi/src/js_values/de.rs | 19 +++++----- napi/src/js_values/either.rs | 6 ++-- napi/src/js_values/function.rs | 12 +++---- napi/src/js_values/global.rs | 4 +-- napi/src/js_values/mod.rs | 34 +++++++++--------- napi/src/js_values/object_property.rs | 2 +- napi/src/js_values/ser.rs | 18 +++++----- test_module/src/class.rs | 6 ++-- test_module/src/function.rs | 2 +- test_module/src/object.rs | 2 +- 17 files changed, 110 insertions(+), 113 deletions(-) diff --git a/napi-derive/src/lib.rs b/napi-derive/src/lib.rs index 6954c61b..58cc950d 100644 --- a/napi-derive/src/lib.rs +++ b/napi-derive/src/lib.rs @@ -118,7 +118,7 @@ pub fn js_function(attr: TokenStream, input: TokenStream) -> TokenStream { debug_assert!(Status::from(status) == Status::Ok, "napi_get_cb_info failed"); } - let mut env = Env::from_raw(raw_env); + let mut env = unsafe { Env::from_raw(raw_env) }; let ctx = CallContext::new(&mut env, cb_info, raw_this, &raw_args, #arg_len_span, argc as usize); #execute_js_function } @@ -156,7 +156,7 @@ pub fn contextless_function(_attr: TokenStream, input: TokenStream) -> TokenStre use napi::{Env, NapiValue, Error, Status}; let mut has_error = false; - let ctx = Env::from_raw(raw_env); + let ctx = unsafe { Env::from_raw(raw_env) }; #execute_js_function } }; @@ -177,13 +177,13 @@ fn get_execute_js_code( let return_token_stream = match function_kind { FunctionKind::Contextless => { quote! { - Ok(Some(v)) => v.raw(), + Ok(Some(v)) => unsafe { v.raw() }, Ok(None) => ptr::null_mut(), } } FunctionKind::JsFunction => { quote! { - Ok(v) => v.raw(), + Ok(v) => unsafe { v.raw() }, } } }; diff --git a/napi/src/async_work.rs b/napi/src/async_work.rs index 2bddc8e7..915bd434 100644 --- a/napi/src/async_work.rs +++ b/napi/src/async_work.rs @@ -23,7 +23,7 @@ pub struct AsyncWorkPromise<'env> { impl<'env> AsyncWorkPromise<'env> { #[inline(always)] pub fn promise_object(&self) -> JsObject { - JsObject::from_raw_unchecked(self.env.0, self.raw_promise) + unsafe { JsObject::from_raw_unchecked(self.env.0, self.raw_promise) } } pub fn cancel(self) -> Result<()> { diff --git a/napi/src/call_context.rs b/napi/src/call_context.rs index 7cff2264..4cd60c65 100644 --- a/napi/src/call_context.rs +++ b/napi/src/call_context.rs @@ -40,7 +40,7 @@ impl<'env> CallContext<'env> { reason: "Arguments index out of range".to_owned(), }) } else { - Ok(ArgType::from_raw_unchecked(self.env.0, self.args[index])) + Ok(unsafe { ArgType::from_raw_unchecked(self.env.0, self.args[index]) }) } } @@ -52,7 +52,7 @@ impl<'env> CallContext<'env> { }) } else { if index < self.length { - ArgType::from_raw(self.env.0, self.args[index]).map(Either::A) + unsafe { ArgType::from_raw(self.env.0, self.args[index]) }.map(Either::A) } else { self.env.get_undefined().map(Either::B) } @@ -65,16 +65,16 @@ impl<'env> CallContext<'env> { { let mut value = ptr::null_mut(); check_status(unsafe { sys::napi_get_new_target(self.env.0, self.callback_info, &mut value) })?; - V::from_raw(self.env.0, value) + unsafe { V::from_raw(self.env.0, value) } } #[inline(always)] pub fn this(&self) -> Result { - T::from_raw(self.env.0, self.raw_this) + unsafe { T::from_raw(self.env.0, self.raw_this) } } #[inline(always)] - pub fn this_unchecked(&self) -> T { + pub unsafe fn this_unchecked(&self) -> T { T::from_raw_unchecked(self.env.0, self.raw_this) } } diff --git a/napi/src/env.rs b/napi/src/env.rs index 16c842f2..9321d64a 100644 --- a/napi/src/env.rs +++ b/napi/src/env.rs @@ -37,26 +37,26 @@ pub type Callback = extern "C" fn(sys::napi_env, sys::napi_callback_info) -> sys pub struct Env(pub(crate) sys::napi_env); impl Env { - pub fn from_raw(env: sys::napi_env) -> Self { + pub unsafe fn from_raw(env: sys::napi_env) -> Self { Env(env) } pub fn get_undefined(&self) -> Result { let mut raw_value = ptr::null_mut(); check_status(unsafe { sys::napi_get_undefined(self.0, &mut raw_value) })?; - Ok(JsUndefined::from_raw_unchecked(self.0, raw_value)) + Ok(unsafe { JsUndefined::from_raw_unchecked(self.0, raw_value) }) } pub fn get_null(&self) -> Result { let mut raw_value = ptr::null_mut(); check_status(unsafe { sys::napi_get_null(self.0, &mut raw_value) })?; - Ok(JsNull::from_raw_unchecked(self.0, raw_value)) + Ok(unsafe { JsNull::from_raw_unchecked(self.0, raw_value) }) } pub fn get_boolean(&self, value: bool) -> Result { let mut raw_value = ptr::null_mut(); check_status(unsafe { sys::napi_get_boolean(self.0, value, &mut raw_value) })?; - Ok(JsBoolean::from_raw_unchecked(self.0, raw_value)) + Ok(unsafe { JsBoolean::from_raw_unchecked(self.0, raw_value) }) } pub fn create_int32(&self, int: i32) -> Result { @@ -64,7 +64,7 @@ impl Env { check_status(unsafe { sys::napi_create_int32(self.0, int, (&mut raw_value) as *mut sys::napi_value) })?; - Ok(JsNumber::from_raw_unchecked(self.0, raw_value)) + Ok(unsafe { JsNumber::from_raw_unchecked(self.0, raw_value) }) } pub fn create_int64(&self, int: i64) -> Result { @@ -72,13 +72,13 @@ impl Env { check_status(unsafe { sys::napi_create_int64(self.0, int, (&mut raw_value) as *mut sys::napi_value) })?; - Ok(JsNumber::from_raw_unchecked(self.0, raw_value)) + Ok(unsafe { JsNumber::from_raw_unchecked(self.0, raw_value) }) } 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)) + Ok(unsafe { JsNumber::from_raw_unchecked(self.0, raw_value) }) } pub fn create_double(&self, double: f64) -> Result { @@ -86,7 +86,7 @@ impl Env { check_status(unsafe { sys::napi_create_double(self.0, double, (&mut raw_value) as *mut sys::napi_value) })?; - Ok(JsNumber::from_raw_unchecked(self.0, raw_value)) + Ok(unsafe { JsNumber::from_raw_unchecked(self.0, raw_value) }) } #[cfg(feature = "napi6")] @@ -165,7 +165,7 @@ impl Env { check_status(unsafe { sys::napi_create_string_utf8(self.0, data_ptr, len as _, &mut raw_value) })?; - Ok(JsString::from_raw_unchecked(self.0, raw_value)) + Ok(unsafe { JsString::from_raw_unchecked(self.0, raw_value) }) } pub fn create_string_utf16(&self, chars: &[u16]) -> Result { @@ -173,7 +173,7 @@ impl Env { check_status(unsafe { sys::napi_create_string_utf16(self.0, chars.as_ptr(), chars.len() as _, &mut raw_value) })?; - Ok(JsString::from_raw_unchecked(self.0, raw_value)) + Ok(unsafe { JsString::from_raw_unchecked(self.0, raw_value) }) } pub fn create_string_latin1(&self, chars: &[u8]) -> Result { @@ -186,13 +186,13 @@ impl Env { &mut raw_value, ) })?; - Ok(JsString::from_raw_unchecked(self.0, raw_value)) + Ok(unsafe { JsString::from_raw_unchecked(self.0, raw_value) }) } 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)) + Ok(unsafe { JsSymbol::from_raw_unchecked(self.0, result) }) } pub fn create_symbol(&self, description: Option<&str>) -> Result { @@ -207,19 +207,19 @@ impl Env { &mut result, ) })?; - Ok(JsSymbol::from_raw_unchecked(self.0, result)) + Ok(unsafe { JsSymbol::from_raw_unchecked(self.0, result) }) } 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)) + Ok(unsafe { JsObject::from_raw_unchecked(self.0, raw_value) }) } pub fn create_array(&self) -> Result { let mut raw_value = ptr::null_mut(); check_status(unsafe { sys::napi_create_array(self.0, &mut raw_value) })?; - Ok(JsObject::from_raw_unchecked(self.0, raw_value)) + Ok(unsafe { JsObject::from_raw_unchecked(self.0, raw_value) }) } pub fn create_array_with_length(&self, length: usize) -> Result { @@ -227,7 +227,7 @@ impl Env { check_status(unsafe { sys::napi_create_array_with_length(self.0, length as _, &mut raw_value) })?; - Ok(JsObject::from_raw_unchecked(self.0, raw_value)) + Ok(unsafe { JsObject::from_raw_unchecked(self.0, raw_value) }) } pub fn create_buffer(&self, length: usize) -> Result { @@ -310,7 +310,7 @@ impl Env { })?; Ok(JsArrayBufferValue::new( - JsArrayBuffer::from_raw_unchecked(self.0, raw_value), + unsafe { JsArrayBuffer::from_raw_unchecked(self.0, raw_value) }, data, )) } @@ -357,7 +357,7 @@ impl Env { ) })?; - Ok(JsFunction::from_raw_unchecked(self.0, raw_result)) + Ok(unsafe { JsFunction::from_raw_unchecked(self.0, raw_result) }) } pub fn throw(&self, error: Error) -> Result<()> { @@ -397,7 +397,7 @@ impl Env { ) })?; - Ok(JsFunction::from_raw_unchecked(self.0, raw_result)) + Ok(unsafe { JsFunction::from_raw_unchecked(self.0, raw_result) }) } pub fn wrap(&self, js_object: &mut JsObject, native_object: T) -> Result<()> { @@ -473,7 +473,7 @@ impl Env { &mut object_value, ) })?; - Ok(JsExternal::from_raw_unchecked(self.0, object_value)) + Ok(unsafe { JsExternal::from_raw_unchecked(self.0, object_value) }) } pub fn get_value_external(&self, js_external: &JsExternal) -> Result<&mut T> { @@ -508,7 +508,7 @@ impl Env { check_status(unsafe { sys::napi_create_error(self.0, ptr::null_mut(), reason_string.0.value, &mut result) })?; - Ok(JsObject::from_raw_unchecked(self.0, result)) + Ok(unsafe { JsObject::from_raw_unchecked(self.0, result) }) } pub fn spawn(&self, task: T) -> Result { @@ -531,7 +531,7 @@ impl Env { 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(JsGlobal::from_raw_unchecked(self.0, raw_global)) + Ok(unsafe { JsGlobal::from_raw_unchecked(self.0, raw_global) }) } pub fn get_napi_version(&self) -> Result { @@ -634,14 +634,14 @@ impl Env { format!("Failed to run future: receiver closed"), ), })?; - Ok(JsObject::from_raw_unchecked(self.0, raw_promise)) + Ok(unsafe { JsObject::from_raw_unchecked(self.0, raw_promise) }) } #[cfg(feature = "napi5")] pub fn create_date(&self, time: f64) -> Result { let mut js_value = ptr::null_mut(); check_status(unsafe { sys::napi_create_date(self.0, time, &mut js_value) })?; - Ok(JsDate::from_raw_unchecked(self.0, js_value)) + Ok(unsafe { JsDate::from_raw_unchecked(self.0, js_value) }) } /// # Serialize `Rust Struct` into `JavaScript Value` @@ -692,7 +692,7 @@ impl Env { { let value = Value { env: self.0, - value: value.raw(), + value: unsafe { value.raw() }, value_type: ValueType::Unknown, }; let mut de = De(&value); diff --git a/napi/src/js_values/arraybuffer.rs b/napi/src/js_values/arraybuffer.rs index 5573d508..560438da 100644 --- a/napi/src/js_values/arraybuffer.rs +++ b/napi/src/js_values/arraybuffer.rs @@ -179,7 +179,7 @@ impl JsArrayBufferValue { } pub fn into_unknown(self) -> JsUnknown { - JsUnknown::from_raw_unchecked(self.value.0.env, self.value.0.value) + unsafe { JsUnknown::from_raw_unchecked(self.value.0.env, self.value.0.value) } } } @@ -225,7 +225,7 @@ impl JsTypedArray { length: len, byte_offset, typedarray_type: typedarray_type.into(), - arraybuffer: JsArrayBuffer::from_raw_unchecked(self.0.env, arraybuffer_value), + arraybuffer: unsafe { JsArrayBuffer::from_raw_unchecked(self.0.env, arraybuffer_value) }, }) } } @@ -248,7 +248,7 @@ impl JsDataView { ) })?; Ok(JsDataViewValue { - arraybuffer: JsArrayBuffer::from_raw_unchecked(self.0.env, arraybuffer_value), + arraybuffer: unsafe { JsArrayBuffer::from_raw_unchecked(self.0.env, arraybuffer_value) }, byte_offset, length, data, diff --git a/napi/src/js_values/bigint.rs b/napi/src/js_values/bigint.rs index 4f98a988..58cedd22 100644 --- a/napi/src/js_values/bigint.rs +++ b/napi/src/js_values/bigint.rs @@ -29,7 +29,7 @@ impl JsBigint { #[inline] pub fn into_unknown(self) -> Result { - JsUnknown::from_raw(self.raw.env, self.raw.value) + unsafe { JsUnknown::from_raw(self.raw.env, self.raw.value) } } #[inline] @@ -124,21 +124,19 @@ impl JsBigint { } impl NapiValue for JsBigint { - fn raw(&self) -> sys::napi_value { + unsafe fn raw(&self) -> sys::napi_value { self.raw.value } - fn from_raw(env: sys::napi_env, value: sys::napi_value) -> Result { + unsafe fn from_raw(env: sys::napi_env, value: sys::napi_value) -> Result { let mut word_count: u64 = 0; - check_status(unsafe { - sys::napi_get_value_bigint_words( - env, - value, - ptr::null_mut(), - &mut word_count as *mut u64 as *mut _, - ptr::null_mut(), - ) - })?; + check_status(sys::napi_get_value_bigint_words( + env, + value, + ptr::null_mut(), + &mut word_count as *mut u64 as *mut _, + ptr::null_mut(), + ))?; Ok(JsBigint { raw: Value { env, @@ -149,17 +147,15 @@ impl NapiValue for JsBigint { }) } - fn from_raw_unchecked(env: sys::napi_env, value: sys::napi_value) -> Self { + unsafe fn from_raw_unchecked(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 as *mut u64 as *mut _, - ptr::null_mut(), - ) - }; + let status = sys::napi_get_value_bigint_words( + env, + value, + ptr::null_mut(), + &mut word_count as *mut u64 as *mut _, + ptr::null_mut(), + ); debug_assert!( Status::from(status) == Status::Ok, "napi_get_value_bigint_words failed" diff --git a/napi/src/js_values/buffer.rs b/napi/src/js_values/buffer.rs index c465e064..83931c2e 100644 --- a/napi/src/js_values/buffer.rs +++ b/napi/src/js_values/buffer.rs @@ -72,7 +72,7 @@ impl JsBufferValue { } pub fn into_unknown(self) -> JsUnknown { - JsUnknown::from_raw_unchecked(self.value.0.env, self.value.0.value) + unsafe { JsUnknown::from_raw_unchecked(self.value.0.env, self.value.0.value) } } } diff --git a/napi/src/js_values/de.rs b/napi/src/js_values/de.rs index 80d71694..6086985e 100644 --- a/napi/src/js_values/de.rs +++ b/napi/src/js_values/de.rs @@ -24,11 +24,12 @@ impl<'x, 'de, 'env> serde::de::Deserializer<'x> for &'de mut De<'env> { match js_value_type { ValueType::Null | ValueType::Undefined => visitor.visit_unit(), ValueType::Boolean => { - let js_boolean = JsBoolean::from_raw_unchecked(self.0.env, self.0.value); + let js_boolean = unsafe { JsBoolean::from_raw_unchecked(self.0.env, self.0.value) }; visitor.visit_bool(js_boolean.get_value()?) } ValueType::Number => { - let js_number: f64 = JsNumber::from_raw_unchecked(self.0.env, self.0.value).try_into()?; + let js_number: f64 = + unsafe { JsNumber::from_raw_unchecked(self.0.env, self.0.value).try_into()? }; if js_number.trunc() == js_number { visitor.visit_i64(js_number as i64) } else { @@ -36,11 +37,11 @@ impl<'x, 'de, 'env> serde::de::Deserializer<'x> for &'de mut De<'env> { } } ValueType::String => { - let js_string = JsString::from_raw_unchecked(self.0.env, self.0.value); + let js_string = unsafe { JsString::from_raw_unchecked(self.0.env, self.0.value) }; visitor.visit_str(js_string.into_utf8()?.as_str()?) } ValueType::Object => { - let js_object = JsObject::from_raw_unchecked(self.0.env, self.0.value); + let js_object = unsafe { JsObject::from_raw_unchecked(self.0.env, self.0.value) }; if js_object.is_array()? { let mut deserializer = JsArrayAccess::new(&js_object, js_object.get_array_length_unchecked()?); @@ -54,7 +55,7 @@ impl<'x, 'de, 'env> serde::de::Deserializer<'x> for &'de mut De<'env> { } #[cfg(feature = "napi6")] ValueType::Bigint => { - let mut js_bigint = JsBigint::from_raw(self.0.env, self.0.value)?; + let mut js_bigint = unsafe { JsBigint::from_raw(self.0.env, self.0.value)? }; let (signed, v, _loss) = js_bigint.get_u128()?; if signed { visitor.visit_i128(-(v as i128)) @@ -106,13 +107,13 @@ impl<'x, 'de, 'env> serde::de::Deserializer<'x> for &'de mut De<'env> { let js_value_type = type_of(self.0.env, self.0.value)?; match js_value_type { ValueType::String => visitor.visit_enum(JsEnumAccess::new( - JsString::from_raw_unchecked(self.0.env, self.0.value) + unsafe { JsString::from_raw_unchecked(self.0.env, self.0.value) } .into_utf8()? .to_owned()?, None, )), ValueType::Object => { - let js_object = JsObject::from_raw_unchecked(self.0.env, self.0.value); + let js_object = unsafe { JsObject::from_raw_unchecked(self.0.env, self.0.value) }; let properties = js_object.get_property_names::()?; let property_len = properties.get_array_length_unchecked()?; if property_len != 1 { @@ -226,7 +227,7 @@ impl<'de, 'env> VariantAccess<'de> for JsVariantAccess<'env> { { match self.value { Some(js_value) => { - let js_object = JsObject::from_raw(js_value.env, js_value.value)?; + let js_object = unsafe { JsObject::from_raw(js_value.env, js_value.value)? }; if js_object.is_array()? { let mut deserializer = JsArrayAccess::new(&js_object, js_object.get_array_length_unchecked()?); @@ -251,7 +252,7 @@ impl<'de, 'env> VariantAccess<'de> for JsVariantAccess<'env> { { match self.value { Some(js_value) => { - if let Ok(val) = JsObject::from_raw(js_value.env, js_value.value) { + if let Ok(val) = unsafe { JsObject::from_raw(js_value.env, js_value.value) } { let mut deserializer = JsObjectAccess::new(&val)?; visitor.visit_map(&mut deserializer) } else { diff --git a/napi/src/js_values/either.rs b/napi/src/js_values/either.rs index 015e6e1f..93ee7fb6 100644 --- a/napi/src/js_values/either.rs +++ b/napi/src/js_values/either.rs @@ -16,17 +16,17 @@ impl Into> for Either { } impl NapiValue for Either { - fn from_raw(env: sys::napi_env, value: sys::napi_value) -> Result> { + unsafe fn from_raw(env: sys::napi_env, value: sys::napi_value) -> Result> { A::from_raw(env, value) .map(Self::A) .or_else(|_| B::from_raw(env, value).map(Self::B)) } - fn from_raw_unchecked(env: sys::napi_env, value: sys::napi_value) -> Either { + unsafe fn from_raw_unchecked(env: sys::napi_env, value: sys::napi_value) -> Either { Self::from_raw(env, value).unwrap() } - fn raw(&self) -> sys::napi_value { + unsafe fn raw(&self) -> sys::napi_value { match self { Either::A(v) => v.raw(), Either::B(v) => v.raw(), diff --git a/napi/src/js_values/function.rs b/napi/src/js_values/function.rs index a1d38b6f..9c3736b2 100644 --- a/napi/src/js_values/function.rs +++ b/napi/src/js_values/function.rs @@ -26,12 +26,12 @@ impl JsFunction { /// [napi_call_function](https://nodejs.org/api/n-api.html#n_api_napi_call_function) pub fn call(&self, this: Option<&JsObject>, args: &[JsUnknown]) -> Result { let raw_this = this - .map(|v| v.raw()) + .map(|v| unsafe { v.raw() }) .or_else(|| { - Env::from_raw(self.0.env) + unsafe { Env::from_raw(self.0.env) } .get_undefined() .ok() - .map(|u| u.raw()) + .map(|u| unsafe { u.raw() }) }) .ok_or(Error::new( Status::GenericFailure, @@ -53,7 +53,7 @@ impl JsFunction { ) })?; - JsUnknown::from_raw(self.0.env, return_value) + unsafe { JsUnknown::from_raw(self.0.env, return_value) } } /// https://nodejs.org/api/n-api.html#n_api_napi_new_instance @@ -66,7 +66,7 @@ impl JsFunction { let length = args.len(); let raw_args = args .iter() - .map(|arg| arg.raw()) + .map(|arg| unsafe { arg.raw() }) .collect::>(); check_status(unsafe { sys::napi_new_instance( @@ -77,6 +77,6 @@ impl JsFunction { &mut js_instance, ) })?; - Ok(JsObject::from_raw_unchecked(self.0.env, js_instance)) + Ok(unsafe { JsObject::from_raw_unchecked(self.0.env, js_instance) }) } } diff --git a/napi/src/js_values/global.rs b/napi/src/js_values/global.rs index b67c1641..70b56021 100644 --- a/napi/src/js_values/global.rs +++ b/napi/src/js_values/global.rs @@ -19,7 +19,7 @@ impl JsGlobal { None, &[ handler.into_unknown(), - Env::from_raw(self.0.env) + unsafe { Env::from_raw(self.0.env) } .create_double(interval)? .into_unknown(), ], @@ -41,7 +41,7 @@ impl JsGlobal { None, &[ handler.into_unknown(), - Env::from_raw(self.0.env) + unsafe { Env::from_raw(self.0.env) } .create_double(interval)? .into_unknown(), ], diff --git a/napi/src/js_values/mod.rs b/napi/src/js_values/mod.rs index 6b476b54..3ae48777 100644 --- a/napi/src/js_values/mod.rs +++ b/napi/src/js_values/mod.rs @@ -85,7 +85,7 @@ pub(crate) fn type_of(env: sys::napi_env, raw_value: sys::napi_value) -> Result< macro_rules! impl_napi_value_trait { ($js_value:ident, $value_type:ident) => { impl NapiValue for $js_value { - fn from_raw(env: sys::napi_env, value: sys::napi_value) -> Result<$js_value> { + unsafe fn from_raw(env: sys::napi_env, value: sys::napi_value) -> Result<$js_value> { let value_type = type_of(env, value)?; if value_type != $value_type { Err(Error::new( @@ -101,11 +101,11 @@ macro_rules! impl_napi_value_trait { } } - fn raw(&self) -> sys::napi_value { + unsafe fn raw(&self) -> sys::napi_value { self.0.value } - fn from_raw_unchecked(env: sys::napi_env, value: sys::napi_value) -> $js_value { + unsafe fn from_raw_unchecked(env: sys::napi_env, value: sys::napi_value) -> $js_value { $js_value(Value { env, value, @@ -117,7 +117,7 @@ macro_rules! impl_napi_value_trait { impl TryFrom for $js_value { type Error = Error; fn try_from(value: JsUnknown) -> Result<$js_value> { - $js_value::from_raw(value.0.env, value.0.value) + unsafe { $js_value::from_raw(value.0.env, value.0.value) } } } }; @@ -128,7 +128,7 @@ macro_rules! impl_js_value_methods { impl $js_value { #[inline] pub fn into_unknown(self) -> JsUnknown { - JsUnknown::from_raw_unchecked(self.0.env, self.0.value) + unsafe { JsUnknown::from_raw_unchecked(self.0.env, self.0.value) } } #[inline] @@ -251,7 +251,7 @@ macro_rules! impl_object_methods { check_status(unsafe { sys::napi_get_property(self.0.env, self.0.value, key.raw(), &mut raw_value) })?; - T::from_raw(self.0.env, raw_value) + unsafe { T::from_raw(self.0.env, raw_value) } } pub fn set_named_property(&mut self, name: &str, value: T) -> Result<()> where @@ -271,7 +271,7 @@ macro_rules! impl_object_methods { check_status(unsafe { sys::napi_get_named_property(self.0.env, self.0.value, key.as_ptr(), &mut raw_value) })?; - T::from_raw(self.0.env, raw_value) + unsafe { T::from_raw(self.0.env, raw_value) } } pub fn has_named_property(&self, name: &str) -> Result { let mut result = false; @@ -355,7 +355,7 @@ macro_rules! impl_object_methods { check_status(unsafe { sys::napi_get_property_names(self.0.env, self.0.value, &mut raw_value) })?; - T::from_raw(self.0.env, raw_value) + unsafe { T::from_raw(self.0.env, raw_value) } } /// https://nodejs.org/api/n-api.html#n_api_napi_get_all_property_names @@ -378,7 +378,7 @@ macro_rules! impl_object_methods { &mut properties_value, ) })?; - Ok(JsObject::from_raw_unchecked(self.0.env, properties_value)) + Ok(unsafe { JsObject::from_raw_unchecked(self.0.env, properties_value) }) } /// This returns the equivalent of `Object.getPrototypeOf` (which is not the same as the function's prototype property). @@ -388,7 +388,7 @@ macro_rules! impl_object_methods { { let mut result = ptr::null_mut(); check_status(unsafe { sys::napi_get_prototype(self.0.env, self.0.value, &mut result) })?; - T::from_raw(self.0.env, result) + unsafe { T::from_raw(self.0.env, result) } } pub fn set_element(&mut self, index: u32, value: T) -> Result<()> @@ -419,7 +419,7 @@ macro_rules! impl_object_methods { check_status(unsafe { sys::napi_get_element(self.0.env, self.0.value, index, &mut raw_value) })?; - T::from_raw(self.0.env, raw_value) + unsafe { T::from_raw(self.0.env, raw_value) } } /// This method allows the efficient definition of multiple properties on a given object. @@ -462,11 +462,11 @@ macro_rules! impl_object_methods { } pub trait NapiValue: Sized { - fn from_raw(env: sys::napi_env, value: sys::napi_value) -> Result; + unsafe fn from_raw(env: sys::napi_env, value: sys::napi_value) -> Result; - fn from_raw_unchecked(env: sys::napi_env, value: sys::napi_value) -> Self; + unsafe fn from_raw_unchecked(env: sys::napi_env, value: sys::napi_value) -> Self; - fn raw(&self) -> sys::napi_value; + unsafe fn raw(&self) -> sys::napi_value; } impl_js_value_methods!(JsUnknown); @@ -516,7 +516,7 @@ impl_napi_value_trait!(JsExternal, External); impl_napi_value_trait!(JsSymbol, Symbol); impl NapiValue for JsUnknown { - fn from_raw(env: sys::napi_env, value: sys::napi_value) -> Result { + unsafe fn from_raw(env: sys::napi_env, value: sys::napi_value) -> Result { Ok(JsUnknown(Value { env, value, @@ -524,7 +524,7 @@ impl NapiValue for JsUnknown { })) } - fn from_raw_unchecked(env: sys::napi_env, value: sys::napi_value) -> Self { + unsafe fn from_raw_unchecked(env: sys::napi_env, value: sys::napi_value) -> Self { JsUnknown(Value { env, value, @@ -533,7 +533,7 @@ impl NapiValue for JsUnknown { } /// get raw js value ptr - fn raw(&self) -> sys::napi_value { + unsafe fn raw(&self) -> sys::napi_value { self.0.value } } diff --git a/napi/src/js_values/object_property.rs b/napi/src/js_values/object_property.rs index fff003f8..247cb0dc 100644 --- a/napi/src/js_values/object_property.rs +++ b/napi/src/js_values/object_property.rs @@ -55,7 +55,7 @@ impl<'env> Property<'env> { } pub fn with_value(mut self, value: T) -> Self { - self.raw_descriptor.value = T::raw(&value); + self.raw_descriptor.value = unsafe { T::raw(&value) }; self } diff --git a/napi/src/js_values/ser.rs b/napi/src/js_values/ser.rs index b3239fe8..41afe393 100644 --- a/napi/src/js_values/ser.rs +++ b/napi/src/js_values/ser.rs @@ -333,7 +333,7 @@ impl ser::SerializeSeq for SeqSerializer { where T: Serialize, { - let env = Env::from_raw(self.array.0.env); + let env = unsafe { Env::from_raw(self.array.0.env) }; self.array.set_element( self.current_index as _, JsUnknown(value.serialize(Ser::new(&env))?), @@ -357,7 +357,7 @@ impl ser::SerializeTuple for SeqSerializer { where T: Serialize, { - let env = Env::from_raw(self.array.0.env); + let env = unsafe { Env::from_raw(self.array.0.env) }; self.array.set_element( self.current_index as _, JsUnknown(value.serialize(Ser::new(&env))?), @@ -382,7 +382,7 @@ impl ser::SerializeTupleStruct for SeqSerializer { where T: Serialize, { - let env = Env::from_raw(self.array.0.env); + let env = unsafe { Env::from_raw(self.array.0.env) }; self.array.set_element( self.current_index as _, JsUnknown(value.serialize(Ser::new(&env))?), @@ -407,7 +407,7 @@ impl ser::SerializeTupleVariant for SeqSerializer { where T: Serialize, { - let env = Env::from_raw(self.array.0.env); + let env = unsafe { Env::from_raw(self.array.0.env) }; self.array.set_element( self.current_index as _, JsUnknown(value.serialize(Ser::new(&env))?), @@ -437,7 +437,7 @@ impl ser::SerializeMap for MapSerializer { where T: Serialize, { - let env = Env::from_raw(self.obj.0.env); + let env = unsafe { Env::from_raw(self.obj.0.env) }; self.key = JsString(key.serialize(Ser::new(&env))?); Ok(()) } @@ -447,7 +447,7 @@ impl ser::SerializeMap for MapSerializer { where T: Serialize, { - let env = Env::from_raw(self.obj.0.env); + let env = unsafe { Env::from_raw(self.obj.0.env) }; self.obj.set_property( JsString(Value { env: self.key.0.env, @@ -469,7 +469,7 @@ impl ser::SerializeMap for MapSerializer { K: Serialize, V: Serialize, { - let env = Env::from_raw(self.obj.0.env); + let env = unsafe { Env::from_raw(self.obj.0.env) }; self.obj.set_property( JsString(key.serialize(Ser::new(&env))?), JsUnknown(value.serialize(Ser::new(&env))?), @@ -497,7 +497,7 @@ impl ser::SerializeStruct for StructSerializer { where T: Serialize, { - let env = Env::from_raw(self.obj.0.env); + let env = unsafe { Env::from_raw(self.obj.0.env) }; self .obj .set_named_property(key, JsUnknown(value.serialize(Ser::new(&env))?))?; @@ -520,7 +520,7 @@ impl ser::SerializeStructVariant for StructSerializer { where T: Serialize, { - let env = Env::from_raw(self.obj.0.env); + let env = unsafe { Env::from_raw(self.obj.0.env) }; self .obj .set_named_property(key, JsUnknown(value.serialize(Ser::new(&env))?))?; diff --git a/test_module/src/class.rs b/test_module/src/class.rs index 58de0572..19ef82c8 100644 --- a/test_module/src/class.rs +++ b/test_module/src/class.rs @@ -19,7 +19,7 @@ fn create_test_class(ctx: CallContext) -> Result { #[js_function(1)] fn test_class_constructor(ctx: CallContext) -> Result { let count: i32 = ctx.get::(0)?.try_into()?; - let mut this: JsObject = ctx.this_unchecked(); + let mut this: JsObject = unsafe { ctx.this_unchecked() }; ctx .env .wrap(&mut this, NativeClass { value: count + 100 })?; @@ -30,7 +30,7 @@ fn test_class_constructor(ctx: CallContext) -> Result { #[js_function(1)] fn add_count(ctx: CallContext) -> Result { let add: i32 = ctx.get::(0)?.try_into()?; - let mut this: JsObject = ctx.this_unchecked(); + let mut this: JsObject = unsafe { ctx.this_unchecked() }; let count: i32 = this.get_named_property::("count")?.try_into()?; this.set_named_property("count", ctx.env.create_int32(count + add)?)?; ctx.env.get_undefined() @@ -39,7 +39,7 @@ fn add_count(ctx: CallContext) -> Result { #[js_function(1)] fn add_native_count(ctx: CallContext) -> Result { let add: i32 = ctx.get::(0)?.try_into()?; - let this: JsObject = ctx.this_unchecked(); + let this: JsObject = unsafe { ctx.this_unchecked() }; let native_class: &mut NativeClass = ctx.env.unwrap(&this)?; native_class.value = native_class.value + add; ctx.env.create_int32(native_class.value) diff --git a/test_module/src/function.rs b/test_module/src/function.rs index 94cd8c6b..dfbea834 100644 --- a/test_module/src/function.rs +++ b/test_module/src/function.rs @@ -13,7 +13,7 @@ pub fn call_function(ctx: CallContext) -> Result { #[js_function(1)] pub fn call_function_with_this(ctx: CallContext) -> Result { - let js_this: JsObject = ctx.this_unchecked(); + let js_this: JsObject = unsafe { ctx.this_unchecked() }; let js_func = ctx.get::(0)?; js_func.call(Some(&js_this), &[])?; diff --git a/test_module/src/object.rs b/test_module/src/object.rs index fef07abc..753b05c6 100644 --- a/test_module/src/object.rs +++ b/test_module/src/object.rs @@ -146,7 +146,7 @@ fn test_define_properties(ctx: CallContext) -> Result { #[js_function(1)] fn add(ctx: CallContext) -> Result { - let mut this: JsObject = ctx.this_unchecked(); + let mut this: JsObject = unsafe { ctx.this_unchecked() }; let count: i32 = this.get_named_property::("count")?.try_into()?; let value_to_add: i32 = ctx.get::(0)?.try_into()?; this.set_named_property("count", ctx.env.create_int32(count + value_to_add)?)?;