Merge pull request #309 from napi-rs/cstring-issues

fix(napi): CString issues
This commit is contained in:
LongYinan 2020-11-20 00:44:16 +08:00 committed by GitHub
commit 89d507d522
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 119 additions and 129 deletions

View file

@ -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"); 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); let ctx = CallContext::new(&mut env, cb_info, raw_this, &raw_args, #arg_len_span, argc as usize);
#execute_js_function #execute_js_function
} }
@ -156,7 +156,7 @@ pub fn contextless_function(_attr: TokenStream, input: TokenStream) -> TokenStre
use napi::{Env, NapiValue, Error, Status}; use napi::{Env, NapiValue, Error, Status};
let mut has_error = false; let mut has_error = false;
let ctx = Env::from_raw(raw_env); let ctx = unsafe { Env::from_raw(raw_env) };
#execute_js_function #execute_js_function
} }
}; };
@ -177,13 +177,13 @@ fn get_execute_js_code(
let return_token_stream = match function_kind { let return_token_stream = match function_kind {
FunctionKind::Contextless => { FunctionKind::Contextless => {
quote! { quote! {
Ok(Some(v)) => v.raw(), Ok(Some(v)) => unsafe { v.raw() },
Ok(None) => ptr::null_mut(), Ok(None) => ptr::null_mut(),
} }
} }
FunctionKind::JsFunction => { FunctionKind::JsFunction => {
quote! { quote! {
Ok(v) => v.raw(), Ok(v) => unsafe { v.raw() },
} }
} }
}; };
@ -204,7 +204,7 @@ fn get_execute_js_code(
Err(e) => { Err(e) => {
let message = format!("{}", e); let message = format!("{}", e);
unsafe { 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() ptr::null_mut()
} }

View file

@ -23,7 +23,7 @@ pub struct AsyncWorkPromise<'env> {
impl<'env> AsyncWorkPromise<'env> { impl<'env> AsyncWorkPromise<'env> {
#[inline(always)] #[inline(always)]
pub fn promise_object(&self) -> JsObject { 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<()> { pub fn cancel(self) -> Result<()> {

View file

@ -40,7 +40,7 @@ impl<'env> CallContext<'env> {
reason: "Arguments index out of range".to_owned(), reason: "Arguments index out of range".to_owned(),
}) })
} else { } 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 { } else {
if index < self.length { 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 { } else {
self.env.get_undefined().map(Either::B) self.env.get_undefined().map(Either::B)
} }
@ -65,16 +65,16 @@ impl<'env> CallContext<'env> {
{ {
let mut value = ptr::null_mut(); let mut value = ptr::null_mut();
check_status(unsafe { sys::napi_get_new_target(self.env.0, self.callback_info, &mut value) })?; 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)] #[inline(always)]
pub fn this<T: NapiValue>(&self) -> Result<T> { pub fn this<T: NapiValue>(&self) -> Result<T> {
T::from_raw(self.env.0, self.raw_this) unsafe { T::from_raw(self.env.0, self.raw_this) }
} }
#[inline(always)] #[inline(always)]
pub fn this_unchecked<T: NapiValue>(&self) -> T { pub unsafe fn this_unchecked<T: NapiValue>(&self) -> T {
T::from_raw_unchecked(self.env.0, self.raw_this) T::from_raw_unchecked(self.env.0, self.raw_this)
} }
} }

View file

@ -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); pub struct Env(pub(crate) sys::napi_env);
impl Env { impl Env {
pub fn from_raw(env: sys::napi_env) -> Self { pub unsafe fn from_raw(env: sys::napi_env) -> Self {
Env(env) Env(env)
} }
pub fn get_undefined(&self) -> Result<JsUndefined> { pub fn get_undefined(&self) -> Result<JsUndefined> {
let mut raw_value = ptr::null_mut(); let mut raw_value = ptr::null_mut();
check_status(unsafe { sys::napi_get_undefined(self.0, &mut raw_value) })?; 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<JsNull> { pub fn get_null(&self) -> Result<JsNull> {
let mut raw_value = ptr::null_mut(); let mut raw_value = ptr::null_mut();
check_status(unsafe { sys::napi_get_null(self.0, &mut raw_value) })?; 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<JsBoolean> { pub fn get_boolean(&self, value: bool) -> Result<JsBoolean> {
let mut raw_value = ptr::null_mut(); let mut raw_value = ptr::null_mut();
check_status(unsafe { sys::napi_get_boolean(self.0, value, &mut raw_value) })?; 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<JsNumber> { pub fn create_int32(&self, int: i32) -> Result<JsNumber> {
@ -64,7 +64,7 @@ impl Env {
check_status(unsafe { check_status(unsafe {
sys::napi_create_int32(self.0, int, (&mut raw_value) as *mut sys::napi_value) 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<JsNumber> { pub fn create_int64(&self, int: i64) -> Result<JsNumber> {
@ -72,13 +72,13 @@ impl Env {
check_status(unsafe { check_status(unsafe {
sys::napi_create_int64(self.0, int, (&mut raw_value) as *mut sys::napi_value) 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<JsNumber> { pub fn create_uint32(&self, number: u32) -> Result<JsNumber> {
let mut raw_value = ptr::null_mut(); let mut raw_value = ptr::null_mut();
check_status(unsafe { sys::napi_create_uint32(self.0, number, &mut raw_value) })?; 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<JsNumber> { pub fn create_double(&self, double: f64) -> Result<JsNumber> {
@ -86,7 +86,7 @@ impl Env {
check_status(unsafe { check_status(unsafe {
sys::napi_create_double(self.0, double, (&mut raw_value) as *mut sys::napi_value) 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")] #[cfg(feature = "napi6")]
@ -165,7 +165,7 @@ impl Env {
check_status(unsafe { check_status(unsafe {
sys::napi_create_string_utf8(self.0, data_ptr, len as _, &mut raw_value) 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<JsString> { pub fn create_string_utf16(&self, chars: &[u16]) -> Result<JsString> {
@ -173,7 +173,7 @@ impl Env {
check_status(unsafe { check_status(unsafe {
sys::napi_create_string_utf16(self.0, chars.as_ptr(), chars.len() as _, &mut raw_value) 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<JsString> { pub fn create_string_latin1(&self, chars: &[u8]) -> Result<JsString> {
@ -186,13 +186,13 @@ impl Env {
&mut raw_value, &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<JsSymbol> { pub fn create_symbol_from_js_string(&self, description: JsString) -> Result<JsSymbol> {
let mut result = ptr::null_mut(); let mut result = ptr::null_mut();
check_status(unsafe { sys::napi_create_symbol(self.0, description.0.value, &mut result) })?; 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<JsSymbol> { pub fn create_symbol(&self, description: Option<&str>) -> Result<JsSymbol> {
@ -207,19 +207,19 @@ impl Env {
&mut result, &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<JsObject> { pub fn create_object(&self) -> Result<JsObject> {
let mut raw_value = ptr::null_mut(); let mut raw_value = ptr::null_mut();
check_status(unsafe { sys::napi_create_object(self.0, &mut raw_value) })?; 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<JsObject> { pub fn create_array(&self) -> Result<JsObject> {
let mut raw_value = ptr::null_mut(); let mut raw_value = ptr::null_mut();
check_status(unsafe { sys::napi_create_array(self.0, &mut raw_value) })?; 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<JsObject> { pub fn create_array_with_length(&self, length: usize) -> Result<JsObject> {
@ -227,7 +227,7 @@ impl Env {
check_status(unsafe { check_status(unsafe {
sys::napi_create_array_with_length(self.0, length as _, &mut raw_value) 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<JsBufferValue> { pub fn create_buffer(&self, length: usize) -> Result<JsBufferValue> {
@ -310,7 +310,7 @@ impl Env {
})?; })?;
Ok(JsArrayBufferValue::new( Ok(JsArrayBufferValue::new(
JsArrayBuffer::from_raw_unchecked(self.0, raw_value), unsafe { JsArrayBuffer::from_raw_unchecked(self.0, raw_value) },
data, 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<()> { pub fn throw(&self, error: Error) -> Result<()> {
@ -368,11 +368,7 @@ impl Env {
pub fn throw_error(&self, msg: &str) -> Result<()> { pub fn throw_error(&self, msg: &str) -> Result<()> {
check_status(unsafe { check_status(unsafe {
sys::napi_throw_error( sys::napi_throw_error(self.0, ptr::null(), CString::new(msg)?.into_raw())
self.0,
ptr::null(),
CString::from_vec_unchecked(msg.into()).as_ptr() as *const _,
)
}) })
} }
@ -401,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<T: 'static>(&self, js_object: &mut JsObject, native_object: T) -> Result<()> { pub fn wrap<T: 'static>(&self, js_object: &mut JsObject, native_object: T) -> Result<()> {
@ -477,7 +473,7 @@ impl Env {
&mut object_value, &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<T: 'static>(&self, js_external: &JsExternal) -> Result<&mut T> { pub fn get_value_external<T: 'static>(&self, js_external: &JsExternal) -> Result<&mut T> {
@ -512,7 +508,7 @@ impl Env {
check_status(unsafe { check_status(unsafe {
sys::napi_create_error(self.0, ptr::null_mut(), reason_string.0.value, &mut result) 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<T: 'static + Task>(&self, task: T) -> Result<AsyncWorkPromise> { pub fn spawn<T: 'static + Task>(&self, task: T) -> Result<AsyncWorkPromise> {
@ -535,7 +531,7 @@ impl Env {
pub fn get_global(&self) -> Result<JsGlobal> { pub fn get_global(&self) -> Result<JsGlobal> {
let mut raw_global = ptr::null_mut(); let mut raw_global = ptr::null_mut();
check_status(unsafe { sys::napi_get_global(self.0, &mut raw_global) })?; 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<u32> { pub fn get_napi_version(&self) -> Result<u32> {
@ -638,14 +634,14 @@ impl Env {
format!("Failed to run future: receiver closed"), 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")] #[cfg(feature = "napi5")]
pub fn create_date(&self, time: f64) -> Result<JsDate> { pub fn create_date(&self, time: f64) -> Result<JsDate> {
let mut js_value = ptr::null_mut(); let mut js_value = ptr::null_mut();
check_status(unsafe { sys::napi_create_date(self.0, time, &mut js_value) })?; 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` /// # Serialize `Rust Struct` into `JavaScript Value`
@ -696,7 +692,7 @@ impl Env {
{ {
let value = Value { let value = Value {
env: self.0, env: self.0,
value: value.raw(), value: unsafe { value.raw() },
value_type: ValueType::Unknown, value_type: ValueType::Unknown,
}; };
let mut de = De(&value); let mut de = De(&value);

View file

@ -179,7 +179,7 @@ impl JsArrayBufferValue {
} }
pub fn into_unknown(self) -> JsUnknown { 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, length: len,
byte_offset, byte_offset,
typedarray_type: typedarray_type.into(), 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 { 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, byte_offset,
length, length,
data, data,

View file

@ -29,7 +29,7 @@ impl JsBigint {
#[inline] #[inline]
pub fn into_unknown(self) -> Result<JsUnknown> { pub fn into_unknown(self) -> Result<JsUnknown> {
JsUnknown::from_raw(self.raw.env, self.raw.value) unsafe { JsUnknown::from_raw(self.raw.env, self.raw.value) }
} }
#[inline] #[inline]
@ -124,21 +124,19 @@ impl JsBigint {
} }
impl NapiValue for JsBigint { impl NapiValue for JsBigint {
fn raw(&self) -> sys::napi_value { unsafe fn raw(&self) -> sys::napi_value {
self.raw.value self.raw.value
} }
fn from_raw(env: sys::napi_env, value: sys::napi_value) -> Result<Self> { unsafe fn from_raw(env: sys::napi_env, value: sys::napi_value) -> Result<Self> {
let mut word_count: u64 = 0; let mut word_count: u64 = 0;
check_status(unsafe { check_status(sys::napi_get_value_bigint_words(
sys::napi_get_value_bigint_words(
env, env,
value, value,
ptr::null_mut(), ptr::null_mut(),
&mut word_count as *mut u64 as *mut _, &mut word_count as *mut u64 as *mut _,
ptr::null_mut(), ptr::null_mut(),
) ))?;
})?;
Ok(JsBigint { Ok(JsBigint {
raw: Value { raw: Value {
env, 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 mut word_count: u64 = 0;
let status = unsafe { let status = sys::napi_get_value_bigint_words(
sys::napi_get_value_bigint_words(
env, env,
value, value,
ptr::null_mut(), ptr::null_mut(),
&mut word_count as *mut u64 as *mut _, &mut word_count as *mut u64 as *mut _,
ptr::null_mut(), ptr::null_mut(),
) );
};
debug_assert!( debug_assert!(
Status::from(status) == Status::Ok, Status::from(status) == Status::Ok,
"napi_get_value_bigint_words failed" "napi_get_value_bigint_words failed"

View file

@ -72,7 +72,7 @@ impl JsBufferValue {
} }
pub fn into_unknown(self) -> JsUnknown { 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) }
} }
} }

View file

@ -24,11 +24,12 @@ impl<'x, 'de, 'env> serde::de::Deserializer<'x> for &'de mut De<'env> {
match js_value_type { match js_value_type {
ValueType::Null | ValueType::Undefined => visitor.visit_unit(), ValueType::Null | ValueType::Undefined => visitor.visit_unit(),
ValueType::Boolean => { 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()?) visitor.visit_bool(js_boolean.get_value()?)
} }
ValueType::Number => { 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 { if js_number.trunc() == js_number {
visitor.visit_i64(js_number as i64) visitor.visit_i64(js_number as i64)
} else { } else {
@ -36,11 +37,11 @@ impl<'x, 'de, 'env> serde::de::Deserializer<'x> for &'de mut De<'env> {
} }
} }
ValueType::String => { 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()?) visitor.visit_str(js_string.into_utf8()?.as_str()?)
} }
ValueType::Object => { 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()? { if js_object.is_array()? {
let mut deserializer = let mut deserializer =
JsArrayAccess::new(&js_object, js_object.get_array_length_unchecked()?); 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")] #[cfg(feature = "napi6")]
ValueType::Bigint => { 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()?; let (signed, v, _loss) = js_bigint.get_u128()?;
if signed { if signed {
visitor.visit_i128(-(v as i128)) 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)?; let js_value_type = type_of(self.0.env, self.0.value)?;
match js_value_type { match js_value_type {
ValueType::String => visitor.visit_enum(JsEnumAccess::new( 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()? .into_utf8()?
.to_owned()?, .to_owned()?,
None, None,
)), )),
ValueType::Object => { 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::<JsObject>()?; let properties = js_object.get_property_names::<JsObject>()?;
let property_len = properties.get_array_length_unchecked()?; let property_len = properties.get_array_length_unchecked()?;
if property_len != 1 { if property_len != 1 {
@ -226,7 +227,7 @@ impl<'de, 'env> VariantAccess<'de> for JsVariantAccess<'env> {
{ {
match self.value { match self.value {
Some(js_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()? { if js_object.is_array()? {
let mut deserializer = let mut deserializer =
JsArrayAccess::new(&js_object, js_object.get_array_length_unchecked()?); 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 { match self.value {
Some(js_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)?; let mut deserializer = JsObjectAccess::new(&val)?;
visitor.visit_map(&mut deserializer) visitor.visit_map(&mut deserializer)
} else { } else {

View file

@ -16,17 +16,17 @@ impl<T: NapiValue> Into<Option<T>> for Either<T, JsUndefined> {
} }
impl<A: NapiValue, B: NapiValue> NapiValue for Either<A, B> { impl<A: NapiValue, B: NapiValue> NapiValue for Either<A, B> {
fn from_raw(env: sys::napi_env, value: sys::napi_value) -> Result<Either<A, B>> { unsafe fn from_raw(env: sys::napi_env, value: sys::napi_value) -> Result<Either<A, B>> {
A::from_raw(env, value) A::from_raw(env, value)
.map(Self::A) .map(Self::A)
.or_else(|_| B::from_raw(env, value).map(Self::B)) .or_else(|_| B::from_raw(env, value).map(Self::B))
} }
fn from_raw_unchecked(env: sys::napi_env, value: sys::napi_value) -> Either<A, B> { unsafe fn from_raw_unchecked(env: sys::napi_env, value: sys::napi_value) -> Either<A, B> {
Self::from_raw(env, value).unwrap() Self::from_raw(env, value).unwrap()
} }
fn raw(&self) -> sys::napi_value { unsafe fn raw(&self) -> sys::napi_value {
match self { match self {
Either::A(v) => v.raw(), Either::A(v) => v.raw(),
Either::B(v) => v.raw(), Either::B(v) => v.raw(),

View file

@ -26,12 +26,12 @@ impl JsFunction {
/// [napi_call_function](https://nodejs.org/api/n-api.html#n_api_napi_call_function) /// [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<JsUnknown> { pub fn call(&self, this: Option<&JsObject>, args: &[JsUnknown]) -> Result<JsUnknown> {
let raw_this = this let raw_this = this
.map(|v| v.raw()) .map(|v| unsafe { v.raw() })
.or_else(|| { .or_else(|| {
Env::from_raw(self.0.env) unsafe { Env::from_raw(self.0.env) }
.get_undefined() .get_undefined()
.ok() .ok()
.map(|u| u.raw()) .map(|u| unsafe { u.raw() })
}) })
.ok_or(Error::new( .ok_or(Error::new(
Status::GenericFailure, 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 /// https://nodejs.org/api/n-api.html#n_api_napi_new_instance
@ -66,7 +66,7 @@ impl JsFunction {
let length = args.len(); let length = args.len();
let raw_args = args let raw_args = args
.iter() .iter()
.map(|arg| arg.raw()) .map(|arg| unsafe { arg.raw() })
.collect::<Vec<sys::napi_value>>(); .collect::<Vec<sys::napi_value>>();
check_status(unsafe { check_status(unsafe {
sys::napi_new_instance( sys::napi_new_instance(
@ -77,6 +77,6 @@ impl JsFunction {
&mut js_instance, &mut js_instance,
) )
})?; })?;
Ok(JsObject::from_raw_unchecked(self.0.env, js_instance)) Ok(unsafe { JsObject::from_raw_unchecked(self.0.env, js_instance) })
} }
} }

View file

@ -19,7 +19,7 @@ impl JsGlobal {
None, None,
&[ &[
handler.into_unknown(), handler.into_unknown(),
Env::from_raw(self.0.env) unsafe { Env::from_raw(self.0.env) }
.create_double(interval)? .create_double(interval)?
.into_unknown(), .into_unknown(),
], ],
@ -41,7 +41,7 @@ impl JsGlobal {
None, None,
&[ &[
handler.into_unknown(), handler.into_unknown(),
Env::from_raw(self.0.env) unsafe { Env::from_raw(self.0.env) }
.create_double(interval)? .create_double(interval)?
.into_unknown(), .into_unknown(),
], ],

View file

@ -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 { macro_rules! impl_napi_value_trait {
($js_value:ident, $value_type:ident) => { ($js_value:ident, $value_type:ident) => {
impl NapiValue for $js_value { 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)?; let value_type = type_of(env, value)?;
if value_type != $value_type { if value_type != $value_type {
Err(Error::new( 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 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 { $js_value(Value {
env, env,
value, value,
@ -117,7 +117,7 @@ macro_rules! impl_napi_value_trait {
impl TryFrom<JsUnknown> for $js_value { impl TryFrom<JsUnknown> for $js_value {
type Error = Error; type Error = Error;
fn try_from(value: JsUnknown) -> Result<$js_value> { 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 { impl $js_value {
#[inline] #[inline]
pub fn into_unknown(self) -> JsUnknown { 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] #[inline]
@ -251,13 +251,13 @@ macro_rules! impl_object_methods {
check_status(unsafe { check_status(unsafe {
sys::napi_get_property(self.0.env, self.0.value, key.raw(), &mut raw_value) 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<T>(&mut self, name: &str, value: T) -> Result<()> pub fn set_named_property<T>(&mut self, name: &str, value: T) -> Result<()>
where where
T: NapiValue, T: NapiValue,
{ {
let key = CString::new(name.to_owned())?; let key = CString::new(name)?;
check_status(unsafe { check_status(unsafe {
sys::napi_set_named_property(self.0.env, self.0.value, key.as_ptr(), value.raw()) sys::napi_set_named_property(self.0.env, self.0.value, key.as_ptr(), value.raw())
}) })
@ -271,14 +271,11 @@ macro_rules! impl_object_methods {
check_status(unsafe { check_status(unsafe {
sys::napi_get_named_property(self.0.env, self.0.value, key.as_ptr(), &mut raw_value) 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<S>(&self, name: S) -> Result<bool> pub fn has_named_property(&self, name: &str) -> Result<bool> {
where
S: AsRef<str>,
{
let mut result = false; let mut result = false;
let key = CString::new(name.as_ref())?; let key = CString::new(name)?;
check_status(unsafe { check_status(unsafe {
sys::napi_has_named_property(self.0.env, self.0.value, key.as_ptr(), &mut result) 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 key_str = CString::new(name)?;
let mut js_key = ptr::null_mut(); let mut js_key = ptr::null_mut();
check_status(unsafe { 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 { check_status(unsafe {
sys::napi_delete_property(self.0.env, self.0.value, js_key, &mut result) 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 string = CString::new(key)?;
let mut js_key = ptr::null_mut(); let mut js_key = ptr::null_mut();
check_status(unsafe { 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 { check_status(unsafe {
sys::napi_has_own_property(self.0.env, self.0.value, js_key, &mut result) sys::napi_has_own_property(self.0.env, self.0.value, js_key, &mut result)
@ -358,7 +355,7 @@ macro_rules! impl_object_methods {
check_status(unsafe { check_status(unsafe {
sys::napi_get_property_names(self.0.env, self.0.value, &mut raw_value) 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 /// https://nodejs.org/api/n-api.html#n_api_napi_get_all_property_names
@ -381,7 +378,7 @@ macro_rules! impl_object_methods {
&mut properties_value, &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). /// This returns the equivalent of `Object.getPrototypeOf` (which is not the same as the function's prototype property).
@ -391,7 +388,7 @@ macro_rules! impl_object_methods {
{ {
let mut result = ptr::null_mut(); let mut result = ptr::null_mut();
check_status(unsafe { sys::napi_get_prototype(self.0.env, self.0.value, &mut result) })?; 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<T>(&mut self, index: u32, value: T) -> Result<()> pub fn set_element<T>(&mut self, index: u32, value: T) -> Result<()>
@ -422,7 +419,7 @@ macro_rules! impl_object_methods {
check_status(unsafe { check_status(unsafe {
sys::napi_get_element(self.0.env, self.0.value, index, &mut raw_value) 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. /// This method allows the efficient definition of multiple properties on a given object.
@ -465,11 +462,11 @@ macro_rules! impl_object_methods {
} }
pub trait NapiValue: Sized { pub trait NapiValue: Sized {
fn from_raw(env: sys::napi_env, value: sys::napi_value) -> Result<Self>; unsafe fn from_raw(env: sys::napi_env, value: sys::napi_value) -> Result<Self>;
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); impl_js_value_methods!(JsUnknown);
@ -519,7 +516,7 @@ impl_napi_value_trait!(JsExternal, External);
impl_napi_value_trait!(JsSymbol, Symbol); impl_napi_value_trait!(JsSymbol, Symbol);
impl NapiValue for JsUnknown { impl NapiValue for JsUnknown {
fn from_raw(env: sys::napi_env, value: sys::napi_value) -> Result<Self> { unsafe fn from_raw(env: sys::napi_env, value: sys::napi_value) -> Result<Self> {
Ok(JsUnknown(Value { Ok(JsUnknown(Value {
env, env,
value, value,
@ -527,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 { JsUnknown(Value {
env, env,
value, value,
@ -536,7 +533,7 @@ impl NapiValue for JsUnknown {
} }
/// get raw js value ptr /// get raw js value ptr
fn raw(&self) -> sys::napi_value { unsafe fn raw(&self) -> sys::napi_value {
self.0.value self.0.value
} }
} }

View file

@ -37,7 +37,7 @@ impl<'env> Property<'env> {
let string_value = CString::new(name)?; let string_value = CString::new(name)?;
let mut result = ptr::null_mut(); let mut result = ptr::null_mut();
check_status(unsafe { 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 { Ok(Property {
name, name,
@ -55,7 +55,7 @@ impl<'env> Property<'env> {
} }
pub fn with_value<T: NapiValue>(mut self, value: T) -> Self { pub fn with_value<T: NapiValue>(mut self, value: T) -> Self {
self.raw_descriptor.value = T::raw(&value); self.raw_descriptor.value = unsafe { T::raw(&value) };
self self
} }

View file

@ -333,7 +333,7 @@ impl ser::SerializeSeq for SeqSerializer {
where where
T: Serialize, 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.array.set_element(
self.current_index as _, self.current_index as _,
JsUnknown(value.serialize(Ser::new(&env))?), JsUnknown(value.serialize(Ser::new(&env))?),
@ -357,7 +357,7 @@ impl ser::SerializeTuple for SeqSerializer {
where where
T: Serialize, 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.array.set_element(
self.current_index as _, self.current_index as _,
JsUnknown(value.serialize(Ser::new(&env))?), JsUnknown(value.serialize(Ser::new(&env))?),
@ -382,7 +382,7 @@ impl ser::SerializeTupleStruct for SeqSerializer {
where where
T: Serialize, 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.array.set_element(
self.current_index as _, self.current_index as _,
JsUnknown(value.serialize(Ser::new(&env))?), JsUnknown(value.serialize(Ser::new(&env))?),
@ -407,7 +407,7 @@ impl ser::SerializeTupleVariant for SeqSerializer {
where where
T: Serialize, 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.array.set_element(
self.current_index as _, self.current_index as _,
JsUnknown(value.serialize(Ser::new(&env))?), JsUnknown(value.serialize(Ser::new(&env))?),
@ -437,7 +437,7 @@ impl ser::SerializeMap for MapSerializer {
where where
T: Serialize, 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))?); self.key = JsString(key.serialize(Ser::new(&env))?);
Ok(()) Ok(())
} }
@ -447,7 +447,7 @@ impl ser::SerializeMap for MapSerializer {
where where
T: Serialize, 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( self.obj.set_property(
JsString(Value { JsString(Value {
env: self.key.0.env, env: self.key.0.env,
@ -469,7 +469,7 @@ impl ser::SerializeMap for MapSerializer {
K: Serialize, K: Serialize,
V: 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( self.obj.set_property(
JsString(key.serialize(Ser::new(&env))?), JsString(key.serialize(Ser::new(&env))?),
JsUnknown(value.serialize(Ser::new(&env))?), JsUnknown(value.serialize(Ser::new(&env))?),
@ -497,7 +497,7 @@ impl ser::SerializeStruct for StructSerializer {
where where
T: Serialize, T: Serialize,
{ {
let env = Env::from_raw(self.obj.0.env); let env = unsafe { Env::from_raw(self.obj.0.env) };
self self
.obj .obj
.set_named_property(key, JsUnknown(value.serialize(Ser::new(&env))?))?; .set_named_property(key, JsUnknown(value.serialize(Ser::new(&env))?))?;
@ -520,7 +520,7 @@ impl ser::SerializeStructVariant for StructSerializer {
where where
T: Serialize, T: Serialize,
{ {
let env = Env::from_raw(self.obj.0.env); let env = unsafe { Env::from_raw(self.obj.0.env) };
self self
.obj .obj
.set_named_property(key, JsUnknown(value.serialize(Ser::new(&env))?))?; .set_named_property(key, JsUnknown(value.serialize(Ser::new(&env))?))?;

View file

@ -188,7 +188,7 @@ macro_rules! register_module {
raw_env, raw_env,
ptr::null(), ptr::null(),
CString::from_vec_unchecked(format!("Error initializing module: {}", e).into()) CString::from_vec_unchecked(format!("Error initializing module: {}", e).into())
.as_ptr() as *const _, .into_raw() as *const _,
) )
}; };
ptr::null_mut() ptr::null_mut()

View file

@ -19,7 +19,7 @@ fn create_test_class(ctx: CallContext) -> Result<JsFunction> {
#[js_function(1)] #[js_function(1)]
fn test_class_constructor(ctx: CallContext) -> Result<JsUndefined> { fn test_class_constructor(ctx: CallContext) -> Result<JsUndefined> {
let count: i32 = ctx.get::<JsNumber>(0)?.try_into()?; let count: i32 = ctx.get::<JsNumber>(0)?.try_into()?;
let mut this: JsObject = ctx.this_unchecked(); let mut this: JsObject = unsafe { ctx.this_unchecked() };
ctx ctx
.env .env
.wrap(&mut this, NativeClass { value: count + 100 })?; .wrap(&mut this, NativeClass { value: count + 100 })?;
@ -30,7 +30,7 @@ fn test_class_constructor(ctx: CallContext) -> Result<JsUndefined> {
#[js_function(1)] #[js_function(1)]
fn add_count(ctx: CallContext) -> Result<JsUndefined> { fn add_count(ctx: CallContext) -> Result<JsUndefined> {
let add: i32 = ctx.get::<JsNumber>(0)?.try_into()?; let add: i32 = ctx.get::<JsNumber>(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::<JsNumber>("count")?.try_into()?; let count: i32 = this.get_named_property::<JsNumber>("count")?.try_into()?;
this.set_named_property("count", ctx.env.create_int32(count + add)?)?; this.set_named_property("count", ctx.env.create_int32(count + add)?)?;
ctx.env.get_undefined() ctx.env.get_undefined()
@ -39,7 +39,7 @@ fn add_count(ctx: CallContext) -> Result<JsUndefined> {
#[js_function(1)] #[js_function(1)]
fn add_native_count(ctx: CallContext) -> Result<JsNumber> { fn add_native_count(ctx: CallContext) -> Result<JsNumber> {
let add: i32 = ctx.get::<JsNumber>(0)?.try_into()?; let add: i32 = ctx.get::<JsNumber>(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)?; let native_class: &mut NativeClass = ctx.env.unwrap(&this)?;
native_class.value = native_class.value + add; native_class.value = native_class.value + add;
ctx.env.create_int32(native_class.value) ctx.env.create_int32(native_class.value)

View file

@ -13,7 +13,7 @@ pub fn call_function(ctx: CallContext) -> Result<JsNull> {
#[js_function(1)] #[js_function(1)]
pub fn call_function_with_this(ctx: CallContext) -> Result<JsNull> { pub fn call_function_with_this(ctx: CallContext) -> Result<JsNull> {
let js_this: JsObject = ctx.this_unchecked(); let js_this: JsObject = unsafe { ctx.this_unchecked() };
let js_func = ctx.get::<JsFunction>(0)?; let js_func = ctx.get::<JsFunction>(0)?;
js_func.call(Some(&js_this), &[])?; js_func.call(Some(&js_this), &[])?;

View file

@ -146,7 +146,7 @@ fn test_define_properties(ctx: CallContext) -> Result<JsUndefined> {
#[js_function(1)] #[js_function(1)]
fn add(ctx: CallContext) -> Result<JsUndefined> { fn add(ctx: CallContext) -> Result<JsUndefined> {
let mut this: JsObject = ctx.this_unchecked(); let mut this: JsObject = unsafe { ctx.this_unchecked() };
let count: i32 = this.get_named_property::<JsNumber>("count")?.try_into()?; let count: i32 = this.get_named_property::<JsNumber>("count")?.try_into()?;
let value_to_add: i32 = ctx.get::<JsNumber>(0)?.try_into()?; let value_to_add: i32 = ctx.get::<JsNumber>(0)?.try_into()?;
this.set_named_property("count", ctx.env.create_int32(count + value_to_add)?)?; this.set_named_property("count", ctx.env.create_int32(count + value_to_add)?)?;