Merge pull request #1024 from messense/forbid-unsafe_op_in_unsafe_fn

chore: forbid unsafe_op_in_unsafe_fn
This commit is contained in:
LongYinan 2022-01-13 14:30:53 +08:00 committed by GitHub
commit 8a4870c8dd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 599 additions and 516 deletions

View file

@ -92,7 +92,7 @@ unsafe impl<T: Task> Sync for AsyncWork<T> {}
/// env here is the same with the one in `CallContext`.
/// So it actually could do nothing here, because `execute` function is called in the other thread mostly.
unsafe extern "C" fn execute<T: Task>(_env: sys::napi_env, data: *mut c_void) {
let mut work = Box::from_raw(data as *mut AsyncWork<T>);
let mut work = unsafe { Box::from_raw(data as *mut AsyncWork<T>) };
let _ = mem::replace(
&mut work.value,
work.inner_task.compute().map(mem::MaybeUninit::new),
@ -105,36 +105,39 @@ unsafe extern "C" fn complete<T: Task>(
status: sys::napi_status,
data: *mut c_void,
) {
let mut work = Box::from_raw(data as *mut AsyncWork<T>);
let mut work = unsafe { Box::from_raw(data as *mut AsyncWork<T>) };
let value_ptr = mem::replace(&mut work.value, Ok(mem::MaybeUninit::zeroed()));
let deferred = mem::replace(&mut work.deferred, ptr::null_mut());
let napi_async_work = mem::replace(&mut work.napi_async_work, ptr::null_mut());
let value = match value_ptr {
Ok(v) => {
let output = v.assume_init();
work.inner_task.resolve(Env::from_raw(env), output)
let output = unsafe { v.assume_init() };
work
.inner_task
.resolve(unsafe { Env::from_raw(env) }, output)
}
Err(e) => work.inner_task.reject(Env::from_raw(env), e),
Err(e) => work.inner_task.reject(unsafe { Env::from_raw(env) }, e),
};
if status != sys::Status::napi_cancelled && work.status.load(Ordering::Relaxed) != 2 {
match check_status!(status)
.and_then(move |_| value)
.and_then(|v| ToNapiValue::to_napi_value(env, v))
.and_then(|v| unsafe { ToNapiValue::to_napi_value(env, v) })
{
Ok(v) => {
let status = sys::napi_resolve_deferred(env, deferred, v);
let status = unsafe { sys::napi_resolve_deferred(env, deferred, v) };
debug_assert!(status == sys::Status::napi_ok, "Resolve promise failed");
}
Err(e) => {
let status = sys::napi_reject_deferred(env, deferred, JsError::from(e).into_value(env));
let status =
unsafe { sys::napi_reject_deferred(env, deferred, JsError::from(e).into_value(env)) };
debug_assert!(status == sys::Status::napi_ok, "Reject promise failed");
}
};
}
if let Err(e) = work.inner_task.finally(Env::from_raw(env)) {
if let Err(e) = work.inner_task.finally(unsafe { Env::from_raw(env) }) {
debug_assert!(false, "Panic in Task finally fn: {:?}", e);
}
let delete_status = sys::napi_delete_async_work(env, napi_async_work);
let delete_status = unsafe { sys::napi_delete_async_work(env, napi_async_work) };
debug_assert!(
delete_status == sys::Status::napi_ok,
"Delete async work failed"

View file

@ -3,7 +3,8 @@
macro_rules! check_status_or_throw {
($env:expr, $code:expr, $($msg:tt)*) => {
if let Err(e) = $crate::check_status!($code, $($msg)*) {
$crate::JsError::from(e).throw_into($env);
#[allow(unused_unsafe)]
unsafe { $crate::JsError::from(e).throw_into($env) };
return;
}
};

View file

@ -68,13 +68,13 @@ impl TypeName for JsUnknown {
impl<T: NapiRaw> ToNapiValue for T {
unsafe fn to_napi_value(_env: sys::napi_env, val: Self) -> Result<sys::napi_value> {
Ok(NapiRaw::raw(&val))
Ok(unsafe { NapiRaw::raw(&val) })
}
}
impl<T: NapiValue> FromNapiValue for T {
unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result<Self> {
Ok(T::from_raw_unchecked(env, napi_val))
Ok(unsafe { T::from_raw_unchecked(env, napi_val) })
}
}
@ -118,7 +118,7 @@ pub trait ValidateNapiValue: FromNapiValue + TypeName {
let mut result = -1;
check_status!(
sys::napi_typeof(env, napi_val, &mut result),
unsafe { sys::napi_typeof(env, napi_val, &mut result) },
"Failed to detect napi value type",
)?;
@ -162,13 +162,13 @@ where
let mut val_type = 0;
check_status!(
sys::napi_typeof(env, napi_val, &mut val_type),
unsafe { sys::napi_typeof(env, napi_val, &mut val_type) },
"Failed to convert napi value into rust type `Option<T>`",
)?;
match val_type {
sys::ValueType::napi_undefined | sys::ValueType::napi_null => Ok(None),
_ => Ok(Some(T::from_napi_value(env, napi_val)?)),
_ => Ok(Some(unsafe { T::from_napi_value(env, napi_val)? })),
}
}
}
@ -179,11 +179,11 @@ where
{
unsafe fn to_napi_value(env: sys::napi_env, val: Self) -> Result<sys::napi_value> {
match val {
Some(val) => T::to_napi_value(env, val),
Some(val) => unsafe { T::to_napi_value(env, val) },
None => {
let mut ptr = ptr::null_mut();
check_status!(
sys::napi_get_null(env, &mut ptr),
unsafe { sys::napi_get_null(env, &mut ptr) },
"Failed to convert rust type `Option<T>` into napi value",
)?;
Ok(ptr)
@ -198,13 +198,13 @@ where
{
unsafe fn to_napi_value(env: sys::napi_env, val: Self) -> Result<sys::napi_value> {
match val {
Ok(v) => T::to_napi_value(env, v),
Ok(v) => unsafe { T::to_napi_value(env, v) },
Err(e) => {
let error_code = String::to_napi_value(env, format!("{:?}", e.status))?;
let reason = String::to_napi_value(env, e.reason)?;
let error_code = unsafe { String::to_napi_value(env, format!("{:?}", e.status))? };
let reason = unsafe { String::to_napi_value(env, e.reason)? };
let mut error = ptr::null_mut();
check_status!(
sys::napi_create_error(env, error_code, reason, &mut error),
unsafe { sys::napi_create_error(env, error_code, reason, &mut error) },
"Failed to create napi error"
)?;

View file

@ -91,7 +91,7 @@ impl FromNapiValue for Array {
unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result<Self> {
let mut is_arr = false;
check_status!(
sys::napi_is_array(env, napi_val, &mut is_arr),
unsafe { sys::napi_is_array(env, napi_val, &mut is_arr) },
"Failed to check given napi value is array"
)?;
@ -99,7 +99,7 @@ impl FromNapiValue for Array {
let mut len = 0;
check_status!(
sys::napi_get_array_length(env, napi_val, &mut len),
unsafe { sys::napi_get_array_length(env, napi_val, &mut len) },
"Failed to get Array length",
)?;
@ -182,7 +182,7 @@ where
arr.set(i as u32, v)?;
}
Array::to_napi_value(env, arr)
unsafe { Array::to_napi_value(env, arr) }
}
}
@ -196,7 +196,7 @@ macro_rules! impl_for_primitive_type {
arr.set(i as u32, *v)?;
}
Array::to_napi_value(env, arr)
unsafe { Array::to_napi_value(env, arr) }
}
}
};
@ -216,7 +216,7 @@ impl ToNapiValue for &Vec<String> {
arr.set(i as u32, v.as_str())?;
}
Array::to_napi_value(env, arr)
unsafe { Array::to_napi_value(env, arr) }
}
}
@ -225,7 +225,7 @@ where
T: FromNapiValue,
{
unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result<Self> {
let arr = Array::from_napi_value(env, napi_val)?;
let arr = unsafe { Array::from_napi_value(env, napi_val)? };
let mut vec = vec![];
for i in 0..arr.len() {

View file

@ -117,6 +117,7 @@ macro_rules! impl_typed_array {
let mut array_buffer = ptr::null_mut();
let mut byte_offset = 0;
check_status!(
unsafe {
sys::napi_get_typedarray_info(
env,
napi_val,
@ -124,8 +125,9 @@ macro_rules! impl_typed_array {
&mut length,
&mut data,
&mut array_buffer,
&mut byte_offset
),
&mut byte_offset,
)
},
"Get TypedArray info failed"
)?;
if typed_array_type != $typed_array_type as i32 {
@ -155,18 +157,21 @@ macro_rules! impl_typed_array {
val.finalizer_notify,
)));
check_status!(
unsafe {
sys::napi_create_external_arraybuffer(
env,
val.data as *mut c_void,
length,
Some(finalizer::<$rust_type>),
hint_ptr as *mut c_void,
&mut arraybuffer_value
),
&mut arraybuffer_value,
)
},
"Create external arraybuffer failed"
)?;
let mut napi_val = ptr::null_mut();
check_status!(
unsafe {
sys::napi_create_typedarray(
env,
$typed_array_type as i32,
@ -174,7 +179,8 @@ macro_rules! impl_typed_array {
arraybuffer_value,
0,
&mut napi_val,
),
)
},
"Create TypedArray failed"
)?;
Ok(napi_val)
@ -188,15 +194,16 @@ unsafe extern "C" fn finalizer<T>(
finalize_data: *mut c_void,
finalize_hint: *mut c_void,
) {
let (data_managed_type, length, finalizer_notify) =
*Box::from_raw(finalize_hint as *mut (DataManagedType, usize, Box<dyn FnOnce(*mut T, usize)>));
let (data_managed_type, length, finalizer_notify) = unsafe {
*Box::from_raw(finalize_hint as *mut (DataManagedType, usize, Box<dyn FnOnce(*mut T, usize)>))
};
match data_managed_type {
DataManagedType::Vm => {
// do nothing
}
DataManagedType::Owned => {
let length = length;
Vec::from_raw_parts(finalize_data as *mut T, length, length);
unsafe { Vec::from_raw_parts(finalize_data as *mut T, length, length) };
}
DataManagedType::External => {
(finalizer_notify)(finalize_data as *mut T, length);

View file

@ -41,15 +41,19 @@ impl TypeName for BigInt {
impl FromNapiValue for BigInt {
unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> crate::Result<Self> {
let mut word_count = 0usize;
check_status!(sys::napi_get_value_bigint_words(
check_status!(unsafe {
sys::napi_get_value_bigint_words(
env,
napi_val,
ptr::null_mut(),
&mut word_count,
ptr::null_mut(),
))?;
)
})?;
let mut words: Vec<u64> = Vec::with_capacity(word_count as usize);
let mut sign_bit = 0;
unsafe {
check_status!(sys::napi_get_value_bigint_words(
env,
napi_val,
@ -59,6 +63,7 @@ impl FromNapiValue for BigInt {
))?;
words.set_len(word_count as usize);
}
Ok(BigInt {
sign_bit: sign_bit == 1,
words,
@ -126,7 +131,8 @@ impl ToNapiValue for BigInt {
unsafe fn to_napi_value(env: sys::napi_env, val: Self) -> crate::Result<sys::napi_value> {
let mut raw_value = ptr::null_mut();
let len = val.words.len();
check_status!(sys::napi_create_bigint_words(
check_status!(unsafe {
sys::napi_create_bigint_words(
env,
match val.sign_bit {
true => 1,
@ -135,7 +141,8 @@ impl ToNapiValue for BigInt {
len,
val.words.as_ptr(),
&mut raw_value,
))?;
)
})?;
Ok(raw_value)
}
}
@ -145,13 +152,9 @@ impl ToNapiValue for i128 {
let mut raw_value = ptr::null_mut();
let sign_bit = if val > 0 { 0 } else { 1 };
let words = &val as *const i128 as *const u64;
check_status!(sys::napi_create_bigint_words(
env,
sign_bit,
2,
words,
&mut raw_value
))?;
check_status!(unsafe {
sys::napi_create_bigint_words(env, sign_bit, 2, words, &mut raw_value)
})?;
Ok(raw_value)
}
}
@ -160,13 +163,7 @@ impl ToNapiValue for u128 {
unsafe fn to_napi_value(env: sys::napi_env, val: Self) -> crate::Result<sys::napi_value> {
let mut raw_value = ptr::null_mut();
let words = &val as *const u128 as *const u64;
check_status!(sys::napi_create_bigint_words(
env,
0,
2,
words,
&mut raw_value
))?;
check_status!(unsafe { sys::napi_create_bigint_words(env, 0, 2, words, &mut raw_value) })?;
Ok(raw_value)
}
}
@ -174,7 +171,7 @@ impl ToNapiValue for u128 {
impl ToNapiValue for i64n {
unsafe fn to_napi_value(env: sys::napi_env, val: Self) -> crate::Result<sys::napi_value> {
let mut raw_value = ptr::null_mut();
check_status!(sys::napi_create_bigint_int64(env, val.0, &mut raw_value))?;
check_status!(unsafe { sys::napi_create_bigint_int64(env, val.0, &mut raw_value) })?;
Ok(raw_value)
}
}
@ -182,7 +179,7 @@ impl ToNapiValue for i64n {
impl ToNapiValue for u64 {
unsafe fn to_napi_value(env: sys::napi_env, val: Self) -> crate::Result<sys::napi_value> {
let mut raw_value = ptr::null_mut();
check_status!(sys::napi_create_bigint_uint64(env, val, &mut raw_value))?;
check_status!(unsafe { sys::napi_create_bigint_uint64(env, val, &mut raw_value) })?;
Ok(raw_value)
}
}
@ -190,11 +187,7 @@ impl ToNapiValue for u64 {
impl ToNapiValue for usize {
unsafe fn to_napi_value(env: sys::napi_env, val: Self) -> crate::Result<sys::napi_value> {
let mut raw_value = ptr::null_mut();
check_status!(sys::napi_create_bigint_uint64(
env,
val as u64,
&mut raw_value
))?;
check_status!(unsafe { sys::napi_create_bigint_uint64(env, val as u64, &mut raw_value) })?;
Ok(raw_value)
}
}
@ -202,11 +195,7 @@ impl ToNapiValue for usize {
impl ToNapiValue for isize {
unsafe fn to_napi_value(env: sys::napi_env, val: Self) -> crate::Result<sys::napi_value> {
let mut raw_value = ptr::null_mut();
check_status!(sys::napi_create_bigint_int64(
env,
val as i64,
&mut raw_value
))?;
check_status!(unsafe { sys::napi_create_bigint_int64(env, val as i64, &mut raw_value) })?;
Ok(raw_value)
}
}

View file

@ -21,7 +21,7 @@ impl ToNapiValue for bool {
let mut ptr = std::ptr::null_mut();
check_status!(
sys::napi_get_boolean(env, val, &mut ptr),
unsafe { sys::napi_get_boolean(env, val, &mut ptr) },
"Failed to convert rust type `bool` into napi value",
)?;
@ -34,7 +34,7 @@ impl FromNapiValue for bool {
let mut ret = false;
check_status!(
sys::napi_get_value_bool(env, napi_val, &mut ret),
unsafe { sys::napi_get_value_bool(env, napi_val, &mut ret) },
"Failed to convert napi value into rust type `bool`",
)?;

View file

@ -70,12 +70,12 @@ impl FromNapiValue for Buffer {
let mut len = 0;
check_status!(
sys::napi_get_buffer_info(env, napi_val, &mut buf, &mut len as *mut usize),
unsafe { sys::napi_get_buffer_info(env, napi_val, &mut buf, &mut len as *mut usize) },
"Failed to convert napi buffer into rust Vec<u8>"
)?;
Ok(Self {
inner: mem::ManuallyDrop::new(Vec::from_raw_parts(buf as *mut _, len, len)),
inner: mem::ManuallyDrop::new(unsafe { Vec::from_raw_parts(buf as *mut _, len, len) }),
})
}
}
@ -85,6 +85,7 @@ impl ToNapiValue for Buffer {
let len = val.inner.len();
let mut ret = ptr::null_mut();
check_status!(
unsafe {
sys::napi_create_external_buffer(
env,
len,
@ -92,7 +93,8 @@ impl ToNapiValue for Buffer {
Some(drop_buffer),
Box::into_raw(Box::new((len, val.inner.capacity()))) as *mut _,
&mut ret,
),
)
},
"Failed to create napi buffer"
)?;

View file

@ -21,8 +21,8 @@ impl<
/// Backward compatible with `Either` in **v1**
pub unsafe fn raw(&self) -> napi_sys::napi_value {
match &self {
Self::A(a) => a.raw(),
Self::B(b) => b.raw(),
Self::A(a) => unsafe { a.raw() },
Self::B(b) => unsafe { b.raw() },
}
}
}
@ -68,9 +68,9 @@ impl<A: TypeName + FromNapiValue + ToNapiValue, B: TypeName + FromNapiValue + To
debug_assert!(A::value_type() != B::value_type(), "{}", ERROR_MSG);
let js_type = type_of!(env, napi_val)?;
if js_type == A::value_type() {
A::from_napi_value(env, napi_val).map(Self::A)
unsafe { A::from_napi_value(env, napi_val).map(Self::A) }
} else if js_type == B::value_type() {
B::from_napi_value(env, napi_val).map(Self::B)
unsafe { B::from_napi_value(env, napi_val).map(Self::B) }
} else {
Err(crate::Error::new(
Status::InvalidArg,
@ -93,8 +93,8 @@ impl<A: TypeName + FromNapiValue + ToNapiValue, B: TypeName + FromNapiValue + To
value: Self,
) -> crate::Result<crate::sys::napi_value> {
match value {
Self::A(a) => A::to_napi_value(env, a),
Self::B(b) => B::to_napi_value(env, b),
Self::A(a) => unsafe { A::to_napi_value(env, a) },
Self::B(b) => unsafe { B::to_napi_value(env, b) },
}
}
}
@ -146,11 +146,11 @@ impl<
);
let js_type = type_of!(env, napi_val)?;
if js_type == A::value_type() {
A::from_napi_value(env, napi_val).map(Self::A)
unsafe { A::from_napi_value(env, napi_val).map(Self::A) }
} else if js_type == B::value_type() {
B::from_napi_value(env, napi_val).map(Self::B)
unsafe { B::from_napi_value(env, napi_val).map(Self::B) }
} else if js_type == C::value_type() {
C::from_napi_value(env, napi_val).map(Self::C)
unsafe { C::from_napi_value(env, napi_val).map(Self::C) }
} else {
Err(crate::Error::new(
Status::InvalidArg,
@ -177,9 +177,9 @@ impl<
value: Self,
) -> crate::Result<crate::sys::napi_value> {
match value {
Self::A(a) => A::to_napi_value(env, a),
Self::B(b) => B::to_napi_value(env, b),
Self::C(c) => C::to_napi_value(env, c),
Self::A(a) => unsafe { A::to_napi_value(env, a) },
Self::B(b) => unsafe { B::to_napi_value(env, b) },
Self::C(c) => unsafe { C::to_napi_value(env, c) },
}
}
}
@ -240,13 +240,13 @@ impl<
);
let js_type = type_of!(env, napi_val)?;
if js_type == A::value_type() {
A::from_napi_value(env, napi_val).map(Self::A)
unsafe { A::from_napi_value(env, napi_val).map(Self::A) }
} else if js_type == B::value_type() {
B::from_napi_value(env, napi_val).map(Self::B)
unsafe { B::from_napi_value(env, napi_val).map(Self::B) }
} else if js_type == C::value_type() {
C::from_napi_value(env, napi_val).map(Self::C)
unsafe { C::from_napi_value(env, napi_val).map(Self::C) }
} else if js_type == D::value_type() {
D::from_napi_value(env, napi_val).map(Self::D)
unsafe { D::from_napi_value(env, napi_val).map(Self::D) }
} else {
Err(crate::Error::new(
Status::InvalidArg,
@ -275,10 +275,10 @@ impl<
value: Self,
) -> crate::Result<crate::sys::napi_value> {
match value {
Self::A(a) => A::to_napi_value(env, a),
Self::B(b) => B::to_napi_value(env, b),
Self::C(c) => C::to_napi_value(env, c),
Self::D(d) => D::to_napi_value(env, d),
Self::A(a) => unsafe { A::to_napi_value(env, a) },
Self::B(b) => unsafe { B::to_napi_value(env, b) },
Self::C(c) => unsafe { C::to_napi_value(env, c) },
Self::D(d) => unsafe { D::to_napi_value(env, d) },
}
}
}
@ -344,15 +344,15 @@ impl<
);
let js_type = type_of!(env, napi_val)?;
if js_type == A::value_type() {
A::from_napi_value(env, napi_val).map(Self::A)
unsafe { A::from_napi_value(env, napi_val).map(Self::A) }
} else if js_type == B::value_type() {
B::from_napi_value(env, napi_val).map(Self::B)
unsafe { B::from_napi_value(env, napi_val).map(Self::B) }
} else if js_type == C::value_type() {
C::from_napi_value(env, napi_val).map(Self::C)
unsafe { C::from_napi_value(env, napi_val).map(Self::C) }
} else if js_type == D::value_type() {
D::from_napi_value(env, napi_val).map(Self::D)
unsafe { D::from_napi_value(env, napi_val).map(Self::D) }
} else if js_type == E::value_type() {
E::from_napi_value(env, napi_val).map(Self::E)
unsafe { E::from_napi_value(env, napi_val).map(Self::E) }
} else {
Err(crate::Error::new(
Status::InvalidArg,
@ -383,11 +383,11 @@ impl<
value: Self,
) -> crate::Result<crate::sys::napi_value> {
match value {
Self::A(a) => A::to_napi_value(env, a),
Self::B(b) => B::to_napi_value(env, b),
Self::C(c) => C::to_napi_value(env, c),
Self::D(d) => D::to_napi_value(env, d),
Self::E(e) => E::to_napi_value(env, e),
Self::A(a) => unsafe { A::to_napi_value(env, a) },
Self::B(b) => unsafe { B::to_napi_value(env, b) },
Self::C(c) => unsafe { C::to_napi_value(env, c) },
Self::D(d) => unsafe { D::to_napi_value(env, d) },
Self::E(e) => unsafe { E::to_napi_value(env, e) },
}
}
}

View file

@ -43,12 +43,12 @@ impl<T: 'static> FromNapiValue for External<T> {
) -> crate::Result<Self> {
let mut unknown_tagged_object = std::ptr::null_mut();
check_status!(
napi_sys::napi_get_value_external(env, napi_val, &mut unknown_tagged_object),
unsafe { napi_sys::napi_get_value_external(env, napi_val, &mut unknown_tagged_object) },
"Failed to get external value"
)?;
let type_id = unknown_tagged_object as *const TypeId;
if *type_id == TypeId::of::<T>() {
if unsafe { *type_id } == TypeId::of::<T>() {
let tagged_object = unknown_tagged_object as *mut TaggedObject<T>;
Ok(Self {
obj: tagged_object,
@ -97,13 +97,15 @@ impl<T: 'static> ToNapiValue for External<T> {
) -> crate::Result<napi_sys::napi_value> {
let mut napi_value = std::ptr::null_mut();
check_status!(
unsafe {
napi_sys::napi_create_external(
env,
val.obj as *mut _,
Some(crate::raw_finalize::<T>),
Box::into_raw(Box::new(Some(val.size_hint as i64))) as *mut _,
&mut napi_value
),
&mut napi_value,
)
},
"Create external value failed"
)?;
@ -111,16 +113,18 @@ impl<T: 'static> ToNapiValue for External<T> {
if val.size_hint != 0 {
check_status!(
unsafe {
napi_sys::napi_adjust_external_memory(
env,
val.size_hint as i64,
adjusted_external_memory_size.as_mut_ptr()
),
adjusted_external_memory_size.as_mut_ptr(),
)
},
"Adjust external memory failed"
)?;
};
val.adjusted_size = adjusted_external_memory_size.assume_init();
val.adjusted_size = unsafe { adjusted_external_memory_size.assume_init() };
Ok(napi_value)
}

View file

@ -25,7 +25,7 @@ where
obj.set(k.as_ref(), v)?;
}
Object::to_napi_value(raw_env, obj)
unsafe { Object::to_napi_value(raw_env, obj) }
}
}
@ -35,7 +35,7 @@ where
V: FromNapiValue,
{
unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result<Self> {
let obj = Object::from_napi_value(env, napi_val)?;
let obj = unsafe { Object::from_napi_value(env, napi_val)? };
let mut map = HashMap::new();
for key in Object::keys(&obj)?.into_iter() {
if let Some(val) = obj.get(&key)? {

View file

@ -38,7 +38,7 @@ impl ToNapiValue for Null {
let mut ret = ptr::null_mut();
check_status!(
sys::napi_get_null(env, &mut ret),
unsafe { sys::napi_get_null(env, &mut ret) },
"Failed to create napi null value"
)?;
@ -80,7 +80,7 @@ impl ToNapiValue for Undefined {
let mut ret = ptr::null_mut();
check_status!(
sys::napi_get_undefined(env, &mut ret),
unsafe { sys::napi_get_undefined(env, &mut ret) },
"Failed to create napi null value"
)?;

View file

@ -27,7 +27,7 @@ macro_rules! impl_number_conversions {
let mut ptr = std::ptr::null_mut();
check_status!(
sys::$create(env, val, &mut ptr),
unsafe { sys::$create(env, val, &mut ptr) },
"Failed to convert rust type `{}` into napi value",
$name,
)?;
@ -42,7 +42,7 @@ macro_rules! impl_number_conversions {
let mut ret = 0 as $t;
check_status!(
sys::$get(env, napi_val, &mut ret),
unsafe { sys::$get(env, napi_val, &mut ret) },
"Failed to convert napi value into rust type `{}`",
$name
)?;

View file

@ -22,9 +22,11 @@ impl<T: FromNapiValue> FromNapiValue for Promise<T> {
napi_val: napi_sys::napi_value,
) -> crate::Result<Self> {
let mut then = ptr::null_mut();
let then_c_string = CStr::from_bytes_with_nul_unchecked(b"then\0");
let then_c_string = unsafe { CStr::from_bytes_with_nul_unchecked(b"then\0") };
check_status!(
napi_sys::napi_get_named_property(env, napi_val, then_c_string.as_ptr(), &mut then,),
unsafe {
napi_sys::napi_get_named_property(env, napi_val, then_c_string.as_ptr(), &mut then)
},
"Failed to get then function"
)?;
let mut promise_after_then = ptr::null_mut();
@ -32,6 +34,7 @@ impl<T: FromNapiValue> FromNapiValue for Promise<T> {
let (tx, rx) = channel();
let tx_ptr = Box::into_raw(Box::new(tx));
check_status!(
unsafe {
napi_sys::napi_create_function(
env,
then_c_string.as_ptr(),
@ -39,10 +42,12 @@ impl<T: FromNapiValue> FromNapiValue for Promise<T> {
Some(then_callback::<T>),
tx_ptr as *mut _,
&mut then_js_cb,
),
)
},
"Failed to create then callback"
)?;
check_status!(
unsafe {
napi_sys::napi_call_function(
env,
napi_val,
@ -50,41 +55,48 @@ impl<T: FromNapiValue> FromNapiValue for Promise<T> {
1,
[then_js_cb].as_ptr(),
&mut promise_after_then,
),
)
},
"Failed to call then method"
)?;
let mut catch = ptr::null_mut();
let catch_c_string = CStr::from_bytes_with_nul_unchecked(b"catch\0");
let catch_c_string = unsafe { CStr::from_bytes_with_nul_unchecked(b"catch\0") };
check_status!(
unsafe {
napi_sys::napi_get_named_property(
env,
promise_after_then,
catch_c_string.as_ptr(),
&mut catch
),
&mut catch,
)
},
"Failed to get then function"
)?;
let mut catch_js_cb = ptr::null_mut();
check_status!(
unsafe {
napi_sys::napi_create_function(
env,
catch_c_string.as_ptr(),
5,
Some(catch_callback::<T>),
tx_ptr as *mut c_void,
&mut catch_js_cb
),
&mut catch_js_cb,
)
},
"Failed to create catch callback"
)?;
check_status!(
unsafe {
napi_sys::napi_call_function(
env,
promise_after_then,
catch,
1,
[catch_js_cb].as_ptr(),
ptr::null_mut()
),
ptr::null_mut(),
)
},
"Failed to call catch method"
)?;
Ok(Promise {
@ -114,20 +126,22 @@ unsafe extern "C" fn then_callback<T: FromNapiValue>(
let mut data = ptr::null_mut();
let mut resolved_value: [napi_sys::napi_value; 1] = [ptr::null_mut()];
let mut this = ptr::null_mut();
let get_cb_status = napi_sys::napi_get_cb_info(
let get_cb_status = unsafe {
napi_sys::napi_get_cb_info(
env,
info,
&mut 1,
resolved_value.as_mut_ptr(),
&mut this,
&mut data,
);
)
};
debug_assert!(
get_cb_status == napi_sys::Status::napi_ok,
"Get callback info from Promise::then failed"
);
let resolve_value_t = Box::new(T::from_napi_value(env, resolved_value[0]));
let sender = Box::from_raw(data as *mut Sender<*mut Result<T>>);
let resolve_value_t = Box::new(unsafe { T::from_napi_value(env, resolved_value[0]) });
let sender = unsafe { Box::from_raw(data as *mut Sender<*mut Result<T>>) };
sender
.send(Box::into_raw(resolve_value_t))
.expect("Send Promise resolved value error");
@ -142,26 +156,29 @@ unsafe extern "C" fn catch_callback<T: FromNapiValue>(
let mut rejected_value: [napi_sys::napi_value; 1] = [ptr::null_mut()];
let mut this = ptr::null_mut();
let mut argc = 1;
let get_cb_status = napi_sys::napi_get_cb_info(
let get_cb_status = unsafe {
napi_sys::napi_get_cb_info(
env,
info,
&mut argc,
rejected_value.as_mut_ptr(),
&mut this,
&mut data,
);
)
};
debug_assert!(
get_cb_status == napi_sys::Status::napi_ok,
"Get callback info from Promise::catch failed"
);
let rejected_value = rejected_value[0];
let mut error_ref = ptr::null_mut();
let create_ref_status = napi_sys::napi_create_reference(env, rejected_value, 1, &mut error_ref);
let create_ref_status =
unsafe { napi_sys::napi_create_reference(env, rejected_value, 1, &mut error_ref) };
debug_assert!(
create_ref_status == napi_sys::Status::napi_ok,
"Create Error reference failed"
);
let sender = Box::from_raw(data as *mut Sender<*mut Result<T>>);
let sender = unsafe { Box::from_raw(data as *mut Sender<*mut Result<T>>) };
sender
.send(Box::into_raw(Box::new(Err(Error::from(error_ref)))))
.expect("Send Promise resolved value error");

View file

@ -9,25 +9,25 @@ use super::{FromNapiValue, Object, ToNapiValue};
impl ToNapiValue for Value {
unsafe fn to_napi_value(env: sys::napi_env, val: Self) -> Result<sys::napi_value> {
match val {
Value::Null => Null::to_napi_value(env, Null),
Value::Bool(b) => bool::to_napi_value(env, b),
Value::Null => unsafe { Null::to_napi_value(env, Null) },
Value::Bool(b) => unsafe { bool::to_napi_value(env, b) },
Value::Number(n) => {
if n.is_i64() {
i64::to_napi_value(env, n.as_i64().unwrap())
unsafe { i64::to_napi_value(env, n.as_i64().unwrap()) }
} else if n.is_f64() {
f64::to_napi_value(env, n.as_f64().unwrap())
unsafe { f64::to_napi_value(env, n.as_f64().unwrap()) }
} else {
let n = n.as_u64().unwrap();
if n > u32::MAX as u64 {
todo!("impl BigInt")
} else {
u32::to_napi_value(env, n as u32)
unsafe { u32::to_napi_value(env, n as u32) }
}
}
}
Value::String(s) => String::to_napi_value(env, s),
Value::Array(arr) => Vec::<Value>::to_napi_value(env, arr),
Value::Object(obj) => Map::to_napi_value(env, obj),
Value::String(s) => unsafe { String::to_napi_value(env, s) },
Value::Array(arr) => unsafe { Vec::<Value>::to_napi_value(env, arr) },
Value::Object(obj) => unsafe { Map::to_napi_value(env, obj) },
}
}
}
@ -36,25 +36,25 @@ impl FromNapiValue for Value {
unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result<Self> {
let ty = type_of!(env, napi_val)?;
let val = match ty {
ValueType::Boolean => Value::Bool(bool::from_napi_value(env, napi_val)?),
ValueType::Boolean => Value::Bool(unsafe { bool::from_napi_value(env, napi_val)? }),
ValueType::Number => {
return Err(Error::new(
Status::InvalidArg,
"Js Number is not be able to convert to rust.".to_owned(),
));
}
ValueType::String => Value::String(String::from_napi_value(env, napi_val)?),
ValueType::String => Value::String(unsafe { String::from_napi_value(env, napi_val)? }),
ValueType::Object => {
let mut is_arr = false;
check_status!(
sys::napi_is_array(env, napi_val, &mut is_arr),
unsafe { sys::napi_is_array(env, napi_val, &mut is_arr) },
"Failed to detect whether given js is an array"
)?;
if is_arr {
Value::Array(Vec::<Value>::from_napi_value(env, napi_val)?)
Value::Array(unsafe { Vec::<Value>::from_napi_value(env, napi_val)? })
} else {
Value::Object(Map::<String, Value>::from_napi_value(env, napi_val)?)
Value::Object(unsafe { Map::<String, Value>::from_napi_value(env, napi_val)? })
}
}
#[cfg(feature = "napi6")]
@ -74,7 +74,7 @@ impl ToNapiValue for Map<String, Value> {
obj.set(k, v)?;
}
Object::to_napi_value(env, obj)
unsafe { Object::to_napi_value(env, obj) }
}
}

View file

@ -22,7 +22,7 @@ impl ToNapiValue for String {
let mut ptr = ptr::null_mut();
check_status!(
sys::napi_create_string_utf8(env, val.as_ptr() as *const _, val.len(), &mut ptr),
unsafe { sys::napi_create_string_utf8(env, val.as_ptr() as *const _, val.len(), &mut ptr) },
"Failed to convert rust `String` into napi `string`"
)?;
@ -35,7 +35,7 @@ impl FromNapiValue for String {
let mut len = 0;
check_status!(
sys::napi_get_value_string_utf8(env, napi_val, ptr::null_mut(), 0, &mut len),
unsafe { sys::napi_get_value_string_utf8(env, napi_val, ptr::null_mut(), 0, &mut len) },
"Failed to convert napi `string` into rust type `String`",
)?;
@ -47,11 +47,13 @@ impl FromNapiValue for String {
let mut written_char_count = 0;
check_status!(
sys::napi_get_value_string_utf8(env, napi_val, buf_ptr, len, &mut written_char_count),
unsafe {
sys::napi_get_value_string_utf8(env, napi_val, buf_ptr, len, &mut written_char_count)
},
"Failed to convert napi `string` into rust type `String`"
)?;
match CStr::from_ptr(buf_ptr).to_str() {
match unsafe { CStr::from_ptr(buf_ptr) }.to_str() {
Err(e) => Err(Error::new(
Status::InvalidArg,
format!("Failed to read utf8 string, {}", e),
@ -76,7 +78,7 @@ impl FromNapiValue for &str {
let mut len = 0;
check_status!(
sys::napi_get_value_string_utf8(env, napi_val, ptr::null_mut(), 0, &mut len),
unsafe { sys::napi_get_value_string_utf8(env, napi_val, ptr::null_mut(), 0, &mut len) },
"Failed to convert napi `string` into rust type `String`",
)?;
@ -87,7 +89,9 @@ impl FromNapiValue for &str {
let mut written_char_count = 0;
check_status!(
sys::napi_get_value_string_utf8(env, napi_val, buf_ptr, len, &mut written_char_count),
unsafe {
sys::napi_get_value_string_utf8(env, napi_val, buf_ptr, len, &mut written_char_count)
},
"Failed to convert napi `string` into rust type `String`"
)?;
@ -98,16 +102,18 @@ impl FromNapiValue for &str {
// So we can safely forget the `Vec<u8>` here which could fix the memory issue here.
// FIXME: This implementation should be removed in next major release.
let mut temporary_external_object = ptr::null_mut();
check_status!(sys::napi_create_external(
check_status!(unsafe {
sys::napi_create_external(
env,
buf_ptr as *mut c_void,
Some(release_string),
Box::into_raw(Box::new(len)) as *mut c_void,
&mut temporary_external_object,
))?;
)
})?;
std::mem::forget(ret);
match CStr::from_ptr(buf_ptr).to_str() {
match unsafe { CStr::from_ptr(buf_ptr) }.to_str() {
Err(e) => Err(Error::new(
Status::InvalidArg,
format!("Failed to read utf8 string, {}", e),
@ -119,7 +125,7 @@ impl FromNapiValue for &str {
impl ToNapiValue for &str {
unsafe fn to_napi_value(env: sys::napi_env, val: Self) -> Result<sys::napi_value> {
String::to_napi_value(env, val.to_owned())
unsafe { String::to_napi_value(env, val.to_owned()) }
}
}
@ -161,7 +167,7 @@ impl FromNapiValue for Utf16String {
let mut len = 0;
check_status!(
sys::napi_get_value_string_utf16(env, napi_val, ptr::null_mut(), 0, &mut len),
unsafe { sys::napi_get_value_string_utf16(env, napi_val, ptr::null_mut(), 0, &mut len) },
"Failed to convert napi `utf16 string` into rust type `String`",
)?;
@ -171,13 +177,15 @@ impl FromNapiValue for Utf16String {
let mut written_char_count = 0;
check_status!(
unsafe {
sys::napi_get_value_string_utf16(
env,
napi_val,
ret.as_mut_ptr(),
len,
&mut written_char_count
),
&mut written_char_count,
)
},
"Failed to convert napi `utf16 string` into rust type `String`",
)?;
@ -200,7 +208,9 @@ impl ToNapiValue for Utf16String {
let encoded = val.0.encode_utf16().collect::<Vec<_>>();
check_status!(
sys::napi_create_string_utf16(env, encoded.as_ptr() as *const _, encoded.len(), &mut ptr),
unsafe {
sys::napi_create_string_utf16(env, encoded.as_ptr() as *const _, encoded.len(), &mut ptr)
},
"Failed to convert napi `string` into rust type `String`"
)?;
@ -250,7 +260,7 @@ pub mod latin1_string {
let mut len = 0;
check_status!(
sys::napi_get_value_string_latin1(env, napi_val, ptr::null_mut(), 0, &mut len),
unsafe { sys::napi_get_value_string_latin1(env, napi_val, ptr::null_mut(), 0, &mut len) },
"Failed to convert napi `latin1 string` into rust type `String`",
)?;
@ -264,17 +274,22 @@ pub mod latin1_string {
mem::forget(buf);
check_status!(
sys::napi_get_value_string_latin1(env, napi_val, buf_ptr, len, &mut written_char_count),
unsafe {
sys::napi_get_value_string_latin1(env, napi_val, buf_ptr, len, &mut written_char_count)
},
"Failed to convert napi `latin1 string` into rust type `String`"
)?;
let buf = Vec::from_raw_parts(buf_ptr as *mut _, written_char_count, written_char_count);
let buf =
unsafe { Vec::from_raw_parts(buf_ptr as *mut _, written_char_count, written_char_count) };
let mut dst_slice = vec![0; buf.len() * 2];
let written =
encoding_rs::mem::convert_latin1_to_utf8(buf.as_slice(), dst_slice.as_mut_slice());
dst_slice.truncate(written);
Ok(Latin1String(String::from_utf8_unchecked(dst_slice)))
Ok(Latin1String(unsafe {
String::from_utf8_unchecked(dst_slice)
}))
}
}
@ -286,7 +301,9 @@ pub mod latin1_string {
encoding_rs::mem::convert_utf8_to_latin1_lossy(val.0.as_bytes(), dst.as_mut_slice());
check_status!(
sys::napi_create_string_latin1(env, dst.as_ptr() as *const _, dst.len(), &mut ptr),
unsafe {
sys::napi_create_string_latin1(env, dst.as_ptr() as *const _, dst.len(), &mut ptr)
},
"Failed to convert rust type `String` into napi `latin1 string`"
)?;
@ -296,6 +313,6 @@ pub mod latin1_string {
}
unsafe extern "C" fn release_string(_env: sys::napi_env, data: *mut c_void, len: *mut c_void) {
let len = *Box::from_raw(len as *mut usize);
Vec::from_raw_parts(data as *mut u8, len, len);
let len = unsafe { *Box::from_raw(len as *mut usize) };
unsafe { Vec::from_raw_parts(data as *mut u8, len, len) };
}

View file

@ -24,7 +24,8 @@ impl ToNapiValue for Symbol {
val: Self,
) -> crate::Result<napi_sys::napi_value> {
let mut symbol_value = ptr::null_mut();
check_status!(napi_sys::napi_create_symbol(
check_status!(unsafe {
napi_sys::napi_create_symbol(
env,
match val.desc {
Some(desc) => {
@ -41,8 +42,9 @@ impl ToNapiValue for Symbol {
}
None => ptr::null_mut(),
},
&mut symbol_value
))?;
&mut symbol_value,
)
})?;
Ok(symbol_value)
}
}

View file

@ -56,7 +56,7 @@ impl FromNapiValue for AbortSignal {
env: napi_sys::napi_env,
napi_val: napi_sys::napi_value,
) -> crate::Result<Self> {
let mut signal = JsObject::from_raw_unchecked(env, napi_val);
let mut signal = unsafe { JsObject::from_raw_unchecked(env, napi_val) };
let async_work_inner: Rc<AtomicPtr<napi_sys::napi_async_work__>> =
Rc::new(AtomicPtr::new(ptr::null_mut()));
let raw_promise: Rc<AtomicPtr<napi_sys::napi_deferred__>> =
@ -67,15 +67,17 @@ impl FromNapiValue for AbortSignal {
raw_deferred: raw_promise.clone(),
status: task_status.clone(),
};
let js_env = Env::from_raw(env);
check_status!(napi_sys::napi_wrap(
let js_env = unsafe { Env::from_raw(env) };
check_status!(unsafe {
napi_sys::napi_wrap(
env,
signal.0.value,
Box::into_raw(Box::new(abort_controller)) as *mut _,
Some(async_task_abort_controller_finalize),
ptr::null_mut(),
ptr::null_mut(),
))?;
)
})?;
signal.set_named_property("onabort", js_env.create_function("onabort", on_abort)?)?;
Ok(AbortSignal {
raw_work: async_work_inner,
@ -162,5 +164,5 @@ unsafe extern "C" fn async_task_abort_controller_finalize(
finalize_data: *mut c_void,
_finalize_hint: *mut c_void,
) {
Box::from_raw(finalize_data as *mut AbortSignal);
unsafe { Box::from_raw(finalize_data as *mut AbortSignal) };
}

View file

@ -22,12 +22,12 @@ pub unsafe extern "C" fn raw_finalize_unchecked<T>(
finalize_hint: *mut c_void,
) {
let obj = finalize_data as *mut T;
Box::from_raw(obj);
unsafe { Box::from_raw(obj) };
if !finalize_hint.is_null() {
let size_hint = *Box::from_raw(finalize_hint as *mut Option<i64>);
let size_hint = unsafe { *Box::from_raw(finalize_hint as *mut Option<i64>) };
if let Some(changed) = size_hint {
let mut adjusted = 0i64;
let status = sys::napi_adjust_external_memory(env, -changed, &mut adjusted);
let status = unsafe { sys::napi_adjust_external_memory(env, -changed, &mut adjusted) };
debug_assert!(
status == sys::Status::napi_ok,
"Calling napi_adjust_external_memory failed"
@ -45,6 +45,8 @@ pub unsafe extern "C" fn drop_buffer(
finalize_hint: *mut c_void,
) {
let length_ptr = finalize_hint as *mut (usize, usize);
unsafe {
let (length, cap) = *Box::from_raw(length_ptr);
mem::drop(Vec::from_raw_parts(finalize_data as *mut u8, length, cap));
}
}

View file

@ -167,18 +167,20 @@ unsafe extern "C" fn napi_register_module_v1(
} else {
check_status_or_throw!(
env,
sys::napi_create_object(env, &mut exports_js_mod),
unsafe { sys::napi_create_object(env, &mut exports_js_mod) },
"Create export JavaScript Object [{}] failed",
js_mod_str
);
check_status_or_throw!(
env,
unsafe {
sys::napi_set_named_property(
env,
exports,
js_mod_str.as_ptr() as *const _,
exports_js_mod
),
exports_js_mod,
)
},
"Set exports Object [{}] into exports object failed",
js_mod_str
);
@ -186,7 +188,7 @@ unsafe extern "C" fn napi_register_module_v1(
}
}
for (name, callback) in items {
let js_name = CStr::from_bytes_with_nul_unchecked(name.as_bytes());
let js_name = unsafe { CStr::from_bytes_with_nul_unchecked(name.as_bytes()) };
unsafe {
if let Err(e) = callback(env).and_then(|v| {
check_status!(
@ -299,7 +301,10 @@ unsafe extern "C" fn napi_register_module_v1(
});
#[cfg(feature = "compat-mode")]
MODULE_EXPORTS.borrow_mut().iter().for_each(|callback| {
MODULE_EXPORTS
.borrow_mut()
.iter()
.for_each(|callback| unsafe {
if let Err(e) = callback(env, exports) {
JsError::from(e).throw_into(env);
}
@ -310,7 +315,9 @@ unsafe extern "C" fn napi_register_module_v1(
let _ = crate::tokio_runtime::RT.clone();
crate::tokio_runtime::TOKIO_RT_REF_COUNT.fetch_add(1, Ordering::Relaxed);
assert_eq!(
sys::napi_add_env_cleanup_hook(env, Some(crate::shutdown_tokio_rt), ptr::null_mut()),
unsafe {
sys::napi_add_env_cleanup_hook(env, Some(crate::shutdown_tokio_rt), ptr::null_mut())
},
sys::Status::napi_ok
);
}
@ -323,6 +330,7 @@ pub(crate) unsafe extern "C" fn noop(
_info: sys::napi_callback_info,
) -> sys::napi_value {
if !crate::bindgen_runtime::___CALL_FROM_FACTORY.load(std::sync::atomic::Ordering::Relaxed) {
unsafe {
sys::napi_throw_error(
env,
ptr::null_mut(),
@ -330,5 +338,6 @@ pub(crate) unsafe extern "C" fn noop(
.as_ptr(),
);
}
}
ptr::null_mut()
}

View file

@ -169,13 +169,8 @@ impl Env {
len: usize,
) -> Result<JsString> {
let mut raw_value = ptr::null_mut();
check_status!(sys::napi_create_string_utf8(
self.0,
data_ptr,
len,
&mut raw_value
))?;
Ok(JsString::from_raw_unchecked(self.0, raw_value))
check_status!(unsafe { sys::napi_create_string_utf8(self.0, data_ptr, len, &mut raw_value) })?;
Ok(unsafe { JsString::from_raw_unchecked(self.0, raw_value) })
}
pub fn create_string_utf16(&self, chars: &[u16]) -> Result<JsString> {
@ -301,7 +296,8 @@ impl Env {
Finalize: FnOnce(Hint, Env),
{
let mut raw_value = ptr::null_mut();
check_status!(sys::napi_create_external_buffer(
check_status!(unsafe {
sys::napi_create_external_buffer(
self.0,
length,
data as *mut c_void,
@ -311,18 +307,19 @@ impl Env {
env: sys::napi_env,
finalize_data: *mut c_void,
finalize_hint: *mut c_void,
)
),
),
Box::into_raw(Box::new((hint, finalize_callback))) as *mut c_void,
&mut raw_value,
))?;
)
})?;
Ok(JsBufferValue::new(
JsBuffer(Value {
env: self.0,
value: raw_value,
value_type: ValueType::Object,
}),
mem::ManuallyDrop::new(Vec::from_raw_parts(data as *mut u8, length, length)),
mem::ManuallyDrop::new(unsafe { Vec::from_raw_parts(data as *mut u8, length, length) }),
))
}
@ -426,7 +423,8 @@ impl Env {
Finalize: FnOnce(Hint, Env),
{
let mut raw_value = ptr::null_mut();
check_status!(sys::napi_create_external_arraybuffer(
check_status!(unsafe {
sys::napi_create_external_arraybuffer(
self.0,
data as *mut c_void,
length,
@ -436,11 +434,12 @@ impl Env {
env: sys::napi_env,
finalize_data: *mut c_void,
finalize_hint: *mut c_void,
)
),
),
Box::into_raw(Box::new((hint, finalize_callback))) as *mut c_void,
&mut raw_value,
))?;
)
})?;
Ok(JsArrayBufferValue::new(
JsArrayBuffer(Value {
env: self.0,
@ -505,14 +504,16 @@ impl Env {
let (raw_this, ref raw_args, closure_data_ptr) = {
let argc = {
let mut argc = 0;
let status = sys::napi_get_cb_info(
let status = unsafe {
sys::napi_get_cb_info(
raw_env,
cb_info,
&mut argc,
ptr::null_mut(),
ptr::null_mut(),
ptr::null_mut(),
);
)
};
debug_assert!(
Status::from(status) == Status::Ok,
"napi_get_cb_info failed"
@ -523,14 +524,16 @@ impl Env {
let mut raw_this = ptr::null_mut();
let mut closure_data_ptr = ptr::null_mut();
let status = sys::napi_get_cb_info(
let status = unsafe {
sys::napi_get_cb_info(
raw_env,
cb_info,
&mut { argc },
raw_args.as_mut_ptr(),
&mut raw_this,
&mut closure_data_ptr,
);
)
};
debug_assert!(
Status::from(status) == Status::Ok,
"napi_get_cb_info failed"
@ -538,13 +541,15 @@ impl Env {
(raw_this, raw_args, closure_data_ptr)
};
let closure: &F = closure_data_ptr
let closure: &F = unsafe {
closure_data_ptr
.cast::<F>()
.as_ref()
.expect("`napi_get_cb_info` should have yielded non-`NULL` assoc data");
let env = &mut Env::from_raw(raw_env);
.expect("`napi_get_cb_info` should have yielded non-`NULL` assoc data")
};
let env = &mut unsafe { Env::from_raw(raw_env) };
let ctx = CallContext::new(env, cb_info, raw_this, raw_args, raw_args.len());
closure(ctx).map(|ret: R| ret.raw())
closure(ctx).map(|ret: R| unsafe { ret.raw() })
}))
.map_err(|e| {
Error::from_reason(format!(
@ -560,7 +565,7 @@ impl Env {
})
.and_then(|v| v)
.unwrap_or_else(|e| {
JsError::from(e).throw_into(raw_env);
unsafe { JsError::from(e).throw_into(raw_env) };
ptr::null_mut()
})
}
@ -591,7 +596,7 @@ impl Env {
closure_data_ptr: *mut c_void,
_finalize_hint: *mut c_void,
) {
drop(Box::<F>::from_raw(closure_data_ptr.cast()))
drop(unsafe { Box::<F>::from_raw(closure_data_ptr.cast()) })
}
finalize_box_trampoline::<F>
@ -1282,8 +1287,8 @@ unsafe extern "C" fn drop_buffer(
hint: *mut c_void,
) {
let length_ptr = hint as *mut (usize, usize);
let (length, cap) = *Box::from_raw(length_ptr);
mem::drop(Vec::from_raw_parts(finalize_data as *mut u8, length, cap));
let (length, cap) = unsafe { *Box::from_raw(length_ptr) };
mem::drop(unsafe { Vec::from_raw_parts(finalize_data as *mut u8, length, cap) });
}
pub(crate) unsafe extern "C" fn raw_finalize<T>(
@ -1292,13 +1297,13 @@ pub(crate) unsafe extern "C" fn raw_finalize<T>(
finalize_hint: *mut c_void,
) {
let tagged_object = finalize_data as *mut TaggedObject<T>;
Box::from_raw(tagged_object);
unsafe { Box::from_raw(tagged_object) };
if !finalize_hint.is_null() {
let size_hint = *Box::from_raw(finalize_hint as *mut Option<i64>);
let size_hint = unsafe { *Box::from_raw(finalize_hint as *mut Option<i64>) };
if let Some(changed) = size_hint {
if changed != 0 {
let mut adjusted = 0i64;
let status = sys::napi_adjust_external_memory(env, -changed, &mut adjusted);
let status = unsafe { sys::napi_adjust_external_memory(env, -changed, &mut adjusted) };
debug_assert!(
status == sys::Status::napi_ok,
"Calling napi_adjust_external_memory failed"
@ -1318,9 +1323,9 @@ unsafe extern "C" fn set_instance_finalize_callback<T, Hint, F>(
Hint: 'static,
F: FnOnce(FinalizeContext<T, Hint>),
{
let (value, callback) = *Box::from_raw(finalize_data as *mut (TaggedObject<T>, F));
let hint = *Box::from_raw(finalize_hint as *mut Hint);
let env = Env::from_raw(raw_env);
let (value, callback) = unsafe { *Box::from_raw(finalize_data as *mut (TaggedObject<T>, F)) };
let hint = unsafe { *Box::from_raw(finalize_hint as *mut Hint) };
let env = unsafe { Env::from_raw(raw_env) };
callback(FinalizeContext {
value: value.object.unwrap(),
hint,
@ -1330,7 +1335,7 @@ unsafe extern "C" fn set_instance_finalize_callback<T, Hint, F>(
#[cfg(feature = "napi3")]
unsafe extern "C" fn cleanup_env<T: 'static>(hook_data: *mut c_void) {
let cleanup_env_hook = Box::from_raw(hook_data as *mut CleanupEnvHookData<T>);
let cleanup_env_hook = unsafe { Box::from_raw(hook_data as *mut CleanupEnvHookData<T>) };
(cleanup_env_hook.hook)(cleanup_env_hook.data);
}
@ -1341,8 +1346,8 @@ unsafe extern "C" fn raw_finalize_with_custom_callback<Hint, Finalize>(
) where
Finalize: FnOnce(Hint, Env),
{
let (hint, callback) = *Box::from_raw(finalize_hint as *mut (Hint, Finalize));
callback(hint, Env::from_raw(env));
let (hint, callback) = unsafe { *Box::from_raw(finalize_hint as *mut (Hint, Finalize)) };
callback(hint, unsafe { Env::from_raw(env) });
}
#[cfg(feature = "napi8")]
@ -1353,10 +1358,10 @@ unsafe extern "C" fn async_finalize<Arg, F>(
Arg: 'static,
F: FnOnce(Arg),
{
let (arg, callback) = *Box::from_raw(data as *mut (Arg, F));
let (arg, callback) = unsafe { *Box::from_raw(data as *mut (Arg, F)) };
callback(arg);
if !handle.is_null() {
let status = sys::napi_remove_async_cleanup_hook(handle);
let status = unsafe { sys::napi_remove_async_cleanup_hook(handle) };
assert!(
status == sys::Status::napi_ok,
"Remove async cleanup hook failed after async cleanup callback"

View file

@ -176,17 +176,15 @@ macro_rules! impl_object_methods {
let mut error_code = ptr::null_mut();
let mut reason_string = ptr::null_mut();
let mut js_error = ptr::null_mut();
let create_code_status = sys::napi_create_string_utf8(
env,
error_code_string.as_ptr(),
status_len,
&mut error_code,
);
let create_code_status = unsafe {
sys::napi_create_string_utf8(env, error_code_string.as_ptr(), status_len, &mut error_code)
};
debug_assert!(create_code_status == sys::Status::napi_ok);
let create_reason_status =
sys::napi_create_string_utf8(env, reason.as_ptr(), reason_len, &mut reason_string);
let create_reason_status = unsafe {
sys::napi_create_string_utf8(env, reason.as_ptr(), reason_len, &mut reason_string)
};
debug_assert!(create_reason_status == sys::Status::napi_ok);
let create_error_status = $kind(env, error_code, reason_string, &mut js_error);
let create_error_status = unsafe { $kind(env, error_code, reason_string, &mut js_error) };
debug_assert!(create_error_status == sys::Status::napi_ok);
js_error
}
@ -201,10 +199,10 @@ macro_rules! impl_object_methods {
if status == Status::PendingException {
return;
}
let js_error = self.into_value(env);
let js_error = unsafe { self.into_value(env) };
#[cfg(debug_assertions)]
let throw_status = sys::napi_throw(env, js_error);
sys::napi_throw(env, js_error);
let throw_status = unsafe { sys::napi_throw(env, js_error) };
unsafe { sys::napi_throw(env, js_error) };
#[cfg(debug_assertions)]
assert!(
throw_status == sys::Status::napi_ok,

View file

@ -136,13 +136,15 @@ impl<'env> NapiRaw for &'env JsBigInt {
impl NapiValue for JsBigInt {
unsafe fn from_raw(env: sys::napi_env, value: sys::napi_value) -> Result<Self> {
let mut word_count = 0usize;
check_status!(sys::napi_get_value_bigint_words(
check_status!(unsafe {
sys::napi_get_value_bigint_words(
env,
value,
ptr::null_mut(),
&mut word_count,
ptr::null_mut(),
))?;
)
})?;
Ok(JsBigInt {
raw: Value {
env,
@ -155,13 +157,15 @@ impl NapiValue for JsBigInt {
unsafe fn from_raw_unchecked(env: sys::napi_env, value: sys::napi_value) -> Self {
let mut word_count = 0usize;
let status = sys::napi_get_value_bigint_words(
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"

View file

@ -681,6 +681,6 @@ impl JsUnknown {
where
V: NapiValue,
{
V::from_raw_unchecked(self.0.env, self.0.value)
unsafe { V::from_raw_unchecked(self.0.env, self.0.value) }
}
}

View file

@ -73,12 +73,13 @@ unsafe extern "C" fn finalize_callback<T, Hint, F>(
Hint: 'static,
F: FnOnce(FinalizeContext<T, Hint>),
{
let (value, callback, raw_ref) = *Box::from_raw(finalize_data as *mut (T, F, sys::napi_ref));
let hint = *Box::from_raw(finalize_hint as *mut Hint);
let env = Env::from_raw(raw_env);
let (value, callback, raw_ref) =
unsafe { *Box::from_raw(finalize_data as *mut (T, F, sys::napi_ref)) };
let hint = unsafe { *Box::from_raw(finalize_hint as *mut Hint) };
let env = unsafe { Env::from_raw(raw_env) };
callback(FinalizeContext { env, value, hint });
if !raw_ref.is_null() {
let status = sys::napi_delete_reference(raw_env, raw_ref);
let status = unsafe { sys::napi_delete_reference(raw_env, raw_ref) };
debug_assert!(
status == sys::Status::napi_ok,
"Delete reference in finalize callback failed"

View file

@ -1,4 +1,5 @@
#![deny(clippy::all)]
#![forbid(unsafe_op_in_unsafe_fn)]
//! High level Node.js [N-API](https://nodejs.org/api/n-api.html) binding
//!
@ -130,7 +131,8 @@ pub type ContextlessResult<T> = Result<Option<T>>;
macro_rules! type_of {
($env:expr, $value:expr) => {{
let mut value_type = 0;
check_status!($crate::sys::napi_typeof($env, $value, &mut value_type))
#[allow(unused_unsafe)]
check_status!(unsafe { $crate::sys::napi_typeof($env, $value, &mut value_type) })
.and_then(|_| Ok($crate::ValueType::from(value_type)))
}};
}
@ -166,13 +168,16 @@ pub(crate) unsafe fn log_js_value<V: AsRef<[sys::napi_value]>>(
use std::ptr;
let mut g = ptr::null_mut();
sys::napi_get_global(env, &mut g);
unsafe { sys::napi_get_global(env, &mut g) };
let mut console = ptr::null_mut();
let console_c_string = CString::new("console").unwrap();
let method_c_string = CString::new(method).unwrap();
sys::napi_get_named_property(env, g, console_c_string.as_ptr(), &mut console);
unsafe { sys::napi_get_named_property(env, g, console_c_string.as_ptr(), &mut console) };
let mut method_js_fn = ptr::null_mut();
sys::napi_get_named_property(env, console, method_c_string.as_ptr(), &mut method_js_fn);
unsafe {
sys::napi_get_named_property(env, console, method_c_string.as_ptr(), &mut method_js_fn)
};
unsafe {
sys::napi_call_function(
env,
console,
@ -180,7 +185,8 @@ pub(crate) unsafe fn log_js_value<V: AsRef<[sys::napi_value]>>(
values.as_ref().len(),
values.as_ref().as_ptr(),
ptr::null_mut(),
);
)
};
}
pub use crate::bindgen_runtime::ctor as module_init;

View file

@ -97,18 +97,19 @@ unsafe extern "C" fn call_js_cb<
context: *mut c_void,
data: *mut c_void,
) {
let future_promise = Box::from_raw(context as *mut FuturePromise<Data, Resolver>);
let value = Box::from_raw(data as *mut Result<Data>);
let future_promise = unsafe { Box::from_raw(context as *mut FuturePromise<Data, Resolver>) };
let value = unsafe { Box::from_raw(data as *mut Result<Data>) };
let resolver = future_promise.resolver;
let deferred = future_promise.deferred;
let js_value_to_resolve = value.and_then(move |v| (resolver)(env, v));
match js_value_to_resolve {
Ok(v) => {
let status = sys::napi_resolve_deferred(env, deferred, v);
let status = unsafe { sys::napi_resolve_deferred(env, deferred, v) };
debug_assert!(status == sys::Status::napi_ok, "Resolve promise failed");
}
Err(e) => {
let status = sys::napi_reject_deferred(
let status = unsafe {
sys::napi_reject_deferred(
env,
deferred,
if e.maybe_raw.is_null() {
@ -127,7 +128,8 @@ unsafe extern "C" fn call_js_cb<
);
err
},
);
)
};
debug_assert!(status == sys::Status::napi_ok, "Reject promise failed");
}
};

View file

@ -329,7 +329,7 @@ unsafe extern "C" fn thread_finalize_cb<T: 'static, V: NapiRaw, R>(
R: 'static + Send + FnMut(ThreadSafeCallContext<T>) -> Result<Vec<V>>,
{
// cleanup
drop(Box::<R>::from_raw(finalize_data.cast()));
drop(unsafe { Box::<R>::from_raw(finalize_data.cast()) });
}
unsafe extern "C" fn call_js_cb<T: 'static, V: NapiRaw, R, ES>(
@ -341,18 +341,20 @@ unsafe extern "C" fn call_js_cb<T: 'static, V: NapiRaw, R, ES>(
R: 'static + Send + FnMut(ThreadSafeCallContext<T>) -> Result<Vec<V>>,
ES: ErrorStrategy::T,
{
let ctx: &mut R = &mut *context.cast::<R>();
let val: Result<T> = match ES::VALUE {
let ctx: &mut R = unsafe { &mut *context.cast::<R>() };
let val: Result<T> = unsafe {
match ES::VALUE {
ErrorStrategy::CalleeHandled::VALUE => *Box::<Result<T>>::from_raw(data.cast()),
ErrorStrategy::Fatal::VALUE => Ok(*Box::<T>::from_raw(data.cast())),
}
};
let mut recv = ptr::null_mut();
sys::napi_get_undefined(raw_env, &mut recv);
unsafe { sys::napi_get_undefined(raw_env, &mut recv) };
let ret = val.and_then(|v| {
(ctx)(ThreadSafeCallContext {
env: Env::from_raw(raw_env),
env: unsafe { Env::from_raw(raw_env) },
value: v,
})
});
@ -364,35 +366,39 @@ unsafe extern "C" fn call_js_cb<T: 'static, V: NapiRaw, R, ES>(
// If the Result is an error, pass that as the first argument.
match ret {
Ok(values) => {
let values = values.iter().map(|v| v.raw());
let values = values.iter().map(|v| unsafe { v.raw() });
let args: Vec<sys::napi_value> = if ES::VALUE == ErrorStrategy::CalleeHandled::VALUE {
let mut js_null = ptr::null_mut();
sys::napi_get_null(raw_env, &mut js_null);
unsafe { sys::napi_get_null(raw_env, &mut js_null) };
::core::iter::once(js_null).chain(values).collect()
} else {
values.collect()
};
status = sys::napi_call_function(
status = unsafe {
sys::napi_call_function(
raw_env,
recv,
js_callback,
args.len(),
args.as_ptr(),
ptr::null_mut(),
);
)
};
}
Err(e) if ES::VALUE == ErrorStrategy::Fatal::VALUE => {
status = sys::napi_fatal_exception(raw_env, JsError::from(e).into_value(raw_env));
status = unsafe { sys::napi_fatal_exception(raw_env, JsError::from(e).into_value(raw_env)) };
}
Err(e) => {
status = sys::napi_call_function(
status = unsafe {
sys::napi_call_function(
raw_env,
recv,
js_callback,
1,
[JsError::from(e).into_value(raw_env)].as_mut_ptr(),
ptr::null_mut(),
);
)
};
}
}
if status == sys::Status::napi_ok {
@ -401,11 +407,11 @@ unsafe extern "C" fn call_js_cb<T: 'static, V: NapiRaw, R, ES>(
if status == sys::Status::napi_pending_exception {
let mut error_result = ptr::null_mut();
assert_eq!(
sys::napi_get_and_clear_last_exception(raw_env, &mut error_result),
unsafe { sys::napi_get_and_clear_last_exception(raw_env, &mut error_result) },
sys::Status::napi_ok
);
assert_eq!(
sys::napi_fatal_exception(raw_env, error_result),
unsafe { sys::napi_fatal_exception(raw_env, error_result) },
sys::Status::napi_ok
);
} else {
@ -413,32 +419,38 @@ unsafe extern "C" fn call_js_cb<T: 'static, V: NapiRaw, R, ES>(
let error_code_string = format!("{:?}", error_code);
let mut error_code_value = ptr::null_mut();
assert_eq!(
unsafe {
sys::napi_create_string_utf8(
raw_env,
error_code_string.as_ptr() as *const _,
error_code_string.len(),
&mut error_code_value
),
&mut error_code_value,
)
},
sys::Status::napi_ok,
);
let error_msg = "Call JavaScript callback failed in thread safe function";
let mut error_msg_value = ptr::null_mut();
assert_eq!(
unsafe {
sys::napi_create_string_utf8(
raw_env,
error_msg.as_ptr() as *const _,
error_msg.len(),
&mut error_msg_value,
),
)
},
sys::Status::napi_ok,
);
let mut error_value = ptr::null_mut();
assert_eq!(
sys::napi_create_error(raw_env, error_code_value, error_msg_value, &mut error_value),
unsafe {
sys::napi_create_error(raw_env, error_code_value, error_msg_value, &mut error_value)
},
sys::Status::napi_ok,
);
assert_eq!(
sys::napi_fatal_exception(raw_env, error_value),
unsafe { sys::napi_fatal_exception(raw_env, error_value) },
sys::Status::napi_ok
);
}

View file

@ -27,7 +27,7 @@ unsafe extern "C" fn load_exe_hook(event: u32, info: *const DELAYLOAD_INFO) -> H
return HINSTANCE::default();
}
let dll_name = CStr::from_ptr((*info).TargetDllName.0 as *mut i8);
let dll_name = unsafe { CStr::from_ptr((*info).TargetDllName.0 as *mut i8) };
if !HOST_BINARIES
.iter()
.any(|&host_name| host_name == dll_name.to_bytes())
@ -35,7 +35,7 @@ unsafe extern "C" fn load_exe_hook(event: u32, info: *const DELAYLOAD_INFO) -> H
return HINSTANCE::default();
}
GetModuleHandleA(PSTR::default())
unsafe { GetModuleHandleA(PSTR::default()) }
}
#[no_mangle]