Skip to content

Commit

Permalink
v0.1.6 | Fix dyn_spawn_blocking() panicking for cancelled tasks & n…
Browse files Browse the repository at this point in the history
…its (#209)

* Fix `dyn_spawn_blocking` panicking for cancelled tasks

* Remove the unused `withOutPtr` js helper

* Add `refCBytesIntoBuffer()` js helper

* Explain the exact choice of `{MIN,MAX}_SAFE_INTEGER` in js N-API conversions

* Version 0.1.6
  • Loading branch information
danielhenrymantilla authored Mar 29, 2024
1 parent 370f8b0 commit b459554
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 35 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ path = "src/_lib.rs"

[package]
name = "safer-ffi"
version = "0.1.5" # Keep in sync
version = "0.1.6" # Keep in sync
authors = [
"Daniel Henry-Mantilla <[email protected]>",
]
Expand Down Expand Up @@ -164,7 +164,7 @@ version = "0.0.3"

[dependencies.safer_ffi-proc_macros]
path = "src/proc_macro"
version = "=0.1.5" # Keep in sync
version = "=0.1.6" # Keep in sync

[workspace]
members = [
Expand Down
4 changes: 2 additions & 2 deletions ffi_tests/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions js_tests/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 10 additions & 4 deletions src/dyn_traits/futures/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ match_! {([] [Send + Sync]) {( $([ $($SendSync:tt)* ])* ) => (
fn spawn_blocking<R : 'static + Send> (
self: &'_ Self,
action: impl 'static + Send + FnOnce() -> R,
) -> impl Future<Output = Result<R, ::futures::channel::oneshot::Canceled>>
) -> impl Future<Output =
Result<R, ::futures::channel::oneshot::Canceled>
>
{
let (tx, rx) = ::futures::channel::oneshot::channel();
let mut action = Some(move || {
Expand All @@ -84,7 +86,8 @@ match_! {([] [Send + Sync]) {( $([ $($SendSync:tt)* ])* ) => (
action
.take()
.expect("\
executor called the `.spawn_blocking()` closure more than once\
executor called the `.spawn_blocking()` closure \
more than once\
")
()
};
Expand Down Expand Up @@ -170,8 +173,11 @@ match_cfg!(feature = "tokio" => {
let fut = self.spawn_blocking(|| { action }.call());
let fut = async {
fut .await
.unwrap_or_else(|caught_panic| {
::std::panic::resume_unwind(caught_panic.into_panic())
.unwrap_or_else(|err| match err.try_into_panic() {
Ok(caught_panic) => {
::std::panic::resume_unwind(caught_panic);
},
Err(err) => debug_assert!(err.is_cancelled()),
})
};
Box::pin(fut)
Expand Down
45 changes: 26 additions & 19 deletions src/js/ffi_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ use super::{*,
use crate::prelude::*;
use ::core::convert::TryFrom;

type JsOf<T> = <crate::layout::CLayoutOf<T> as ReprNapi>::NapiValue;
type JsOfCSliceRef<T> = JsOf<c_slice::Ref<'static, T>>;

#[js_export(js_name = withCString, __skip_napi_import)]
pub
fn with_js_string_as_utf8 (
Expand Down Expand Up @@ -209,6 +212,29 @@ fn slice_box_uint8_t_to_js_buffer (
}
})}

#[js_export(js_name = refCBytesIntoBuffer, __skip_napi_import)]
pub
fn slice_ref_uint8_t_to_js_buffer (
arg: JsOfCSliceRef<u8>,
) -> Result<JsUnknown>
{Ok({
let ctx = ::safer_ffi::js::derive::__js_ctx!();
let fat = crate::slice::slice_ref_Layout::<'_, u8>::from_napi_value(ctx.env, arg)?;
if fat.ptr.is_null() {
ctx .env
.get_null()?
.into_unknown()
} else {
let p: crate::prelude::c_slice::Ref<'_, u8> = unsafe {
crate::layout::from_raw_unchecked(fat)
};
ctx .env
.create_buffer_copy(p.as_slice())?
.into_unknown()
}
})}


#[js_export(js_name = withOutBoolean, __skip_napi_import)]
pub
fn with_out_bool (cb: JsFunction)
Expand Down Expand Up @@ -260,24 +286,6 @@ fn wrap_ptr (env: &'_ Env, p: *mut (), ty: &'_ str)
Ok(obj.into_unknown())
}

#[js_export(js_name = withOutPtr, __skip_napi_import)]
pub
fn with_out_ptr (
ty: JsString,
cb: JsFunction,
) -> Result<JsUnknown>
{Ok({
let ctx = ::safer_ffi::js::derive::__js_ctx!();
let ref ty: String = ty.into_utf8()?.into_owned()?;
let mut p: *mut () = NULL!();
let out_p = &mut p;
cb.call(None, &[
wrap_ptr(ctx.env, <*mut _>::cast(out_p), &format!("{} *", ty))?
])?;
wrap_ptr(ctx.env, p, ty)?
.into_unknown()
})}

#[js_export(js_name = withOutBoxCBytes, __skip_napi_import)]
pub
fn with_out_byte_slice (cb: JsFunction)
Expand Down Expand Up @@ -376,7 +384,6 @@ fn vec_char_ptr_to_js_string_array (
// "refCStringToString": char_p_ref_to_js_string,
// "withCBytes": with_js_buffer_as_slice_uint8_t_ref,
// "boxCBytesIntoBuffer": slice_box_uint8_t_to_js_buffer,
// "withOutPtr": with_out_ptr,
// "withOutBoolean": with_out_bool,
// "withOutU64": with_out_u64,
// "withOutBoxCBytes": with_out_byte_slice,
Expand Down
15 changes: 12 additions & 3 deletions src/js/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,19 @@ match_! {(
env: &'_ Env,
) -> Result<JsUnknown>
{
const MIN: i128 = 0 - ((1 << 53) - 1);
const MAX: i128 = 0 + ((1 << 53) - 1);
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER
const MIN_SAFE_INTEGER: i128 = 0 - ((1 << 53) - 1);
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER
const MAX_SAFE_INTEGER: i128 = 0 + ((1 << 53) - 1);
// Based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger#description
// we ought not to use the `number` type for integers
// outside of this range lest we expose js code to
// non-"safe integers", _i.e._, integers which break
// mathematical properties such as `x ≠ x + 1`.
//
// See also: https://nodejs.org/api/n-api.html#napi_create_int64
match self as i128 {
| MIN ..= MAX => {
| MIN_SAFE_INTEGER ..= MAX_SAFE_INTEGER => {
env .create_int64(
self.try_into()
.expect("Unreachable")
Expand Down
2 changes: 1 addition & 1 deletion src/proc_macro/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ proc-macro = true

[package]
name = "safer_ffi-proc_macros"
version = "0.1.5" # Keep in sync
version = "0.1.6" # Keep in sync
authors = ["Daniel Henry-Mantilla <[email protected]>"]
edition = "2021"

Expand Down

0 comments on commit b459554

Please sign in to comment.