Skip to content

Commit b459554

Browse files
v0.1.6 | Fix dyn_spawn_blocking() panicking for cancelled tasks & nits (#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
1 parent 370f8b0 commit b459554

8 files changed

Lines changed: 57 additions & 35 deletions

File tree

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ path = "src/_lib.rs"
33

44
[package]
55
name = "safer-ffi"
6-
version = "0.1.5" # Keep in sync
6+
version = "0.1.6" # Keep in sync
77
authors = [
88
"Daniel Henry-Mantilla <daniel.henry.mantilla@gmail.com>",
99
]
@@ -164,7 +164,7 @@ version = "0.0.3"
164164

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

169169
[workspace]
170170
members = [

ffi_tests/Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

js_tests/Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/dyn_traits/futures/executor.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@ match_! {([] [Send + Sync]) {( $([ $($SendSync:tt)* ])* ) => (
7474
fn spawn_blocking<R : 'static + Send> (
7575
self: &'_ Self,
7676
action: impl 'static + Send + FnOnce() -> R,
77-
) -> impl Future<Output = Result<R, ::futures::channel::oneshot::Canceled>>
77+
) -> impl Future<Output =
78+
Result<R, ::futures::channel::oneshot::Canceled>
79+
>
7880
{
7981
let (tx, rx) = ::futures::channel::oneshot::channel();
8082
let mut action = Some(move || {
@@ -84,7 +86,8 @@ match_! {([] [Send + Sync]) {( $([ $($SendSync:tt)* ])* ) => (
8486
action
8587
.take()
8688
.expect("\
87-
executor called the `.spawn_blocking()` closure more than once\
89+
executor called the `.spawn_blocking()` closure \
90+
more than once\
8891
")
8992
()
9093
};
@@ -170,8 +173,11 @@ match_cfg!(feature = "tokio" => {
170173
let fut = self.spawn_blocking(|| { action }.call());
171174
let fut = async {
172175
fut .await
173-
.unwrap_or_else(|caught_panic| {
174-
::std::panic::resume_unwind(caught_panic.into_panic())
176+
.unwrap_or_else(|err| match err.try_into_panic() {
177+
Ok(caught_panic) => {
178+
::std::panic::resume_unwind(caught_panic);
179+
},
180+
Err(err) => debug_assert!(err.is_cancelled()),
175181
})
176182
};
177183
Box::pin(fut)

src/js/ffi_helpers.rs

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ use super::{*,
55
use crate::prelude::*;
66
use ::core::convert::TryFrom;
77

8+
type JsOf<T> = <crate::layout::CLayoutOf<T> as ReprNapi>::NapiValue;
9+
type JsOfCSliceRef<T> = JsOf<c_slice::Ref<'static, T>>;
10+
811
#[js_export(js_name = withCString, __skip_napi_import)]
912
pub
1013
fn with_js_string_as_utf8 (
@@ -209,6 +212,29 @@ fn slice_box_uint8_t_to_js_buffer (
209212
}
210213
})}
211214

215+
#[js_export(js_name = refCBytesIntoBuffer, __skip_napi_import)]
216+
pub
217+
fn slice_ref_uint8_t_to_js_buffer (
218+
arg: JsOfCSliceRef<u8>,
219+
) -> Result<JsUnknown>
220+
{Ok({
221+
let ctx = ::safer_ffi::js::derive::__js_ctx!();
222+
let fat = crate::slice::slice_ref_Layout::<'_, u8>::from_napi_value(ctx.env, arg)?;
223+
if fat.ptr.is_null() {
224+
ctx .env
225+
.get_null()?
226+
.into_unknown()
227+
} else {
228+
let p: crate::prelude::c_slice::Ref<'_, u8> = unsafe {
229+
crate::layout::from_raw_unchecked(fat)
230+
};
231+
ctx .env
232+
.create_buffer_copy(p.as_slice())?
233+
.into_unknown()
234+
}
235+
})}
236+
237+
212238
#[js_export(js_name = withOutBoolean, __skip_napi_import)]
213239
pub
214240
fn with_out_bool (cb: JsFunction)
@@ -260,24 +286,6 @@ fn wrap_ptr (env: &'_ Env, p: *mut (), ty: &'_ str)
260286
Ok(obj.into_unknown())
261287
}
262288

263-
#[js_export(js_name = withOutPtr, __skip_napi_import)]
264-
pub
265-
fn with_out_ptr (
266-
ty: JsString,
267-
cb: JsFunction,
268-
) -> Result<JsUnknown>
269-
{Ok({
270-
let ctx = ::safer_ffi::js::derive::__js_ctx!();
271-
let ref ty: String = ty.into_utf8()?.into_owned()?;
272-
let mut p: *mut () = NULL!();
273-
let out_p = &mut p;
274-
cb.call(None, &[
275-
wrap_ptr(ctx.env, <*mut _>::cast(out_p), &format!("{} *", ty))?
276-
])?;
277-
wrap_ptr(ctx.env, p, ty)?
278-
.into_unknown()
279-
})}
280-
281289
#[js_export(js_name = withOutBoxCBytes, __skip_napi_import)]
282290
pub
283291
fn with_out_byte_slice (cb: JsFunction)
@@ -376,7 +384,6 @@ fn vec_char_ptr_to_js_string_array (
376384
// "refCStringToString": char_p_ref_to_js_string,
377385
// "withCBytes": with_js_buffer_as_slice_uint8_t_ref,
378386
// "boxCBytesIntoBuffer": slice_box_uint8_t_to_js_buffer,
379-
// "withOutPtr": with_out_ptr,
380387
// "withOutBoolean": with_out_bool,
381388
// "withOutU64": with_out_u64,
382389
// "withOutBoxCBytes": with_out_byte_slice,

src/js/impls.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,19 @@ match_! {(
129129
env: &'_ Env,
130130
) -> Result<JsUnknown>
131131
{
132-
const MIN: i128 = 0 - ((1 << 53) - 1);
133-
const MAX: i128 = 0 + ((1 << 53) - 1);
132+
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER
133+
const MIN_SAFE_INTEGER: i128 = 0 - ((1 << 53) - 1);
134+
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER
135+
const MAX_SAFE_INTEGER: i128 = 0 + ((1 << 53) - 1);
136+
// Based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger#description
137+
// we ought not to use the `number` type for integers
138+
// outside of this range lest we expose js code to
139+
// non-"safe integers", _i.e._, integers which break
140+
// mathematical properties such as `x ≠ x + 1`.
141+
//
142+
// See also: https://nodejs.org/api/n-api.html#napi_create_int64
134143
match self as i128 {
135-
| MIN ..= MAX => {
144+
| MIN_SAFE_INTEGER ..= MAX_SAFE_INTEGER => {
136145
env .create_int64(
137146
self.try_into()
138147
.expect("Unreachable")

src/proc_macro/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ proc-macro = true
44

55
[package]
66
name = "safer_ffi-proc_macros"
7-
version = "0.1.5" # Keep in sync
7+
version = "0.1.6" # Keep in sync
88
authors = ["Daniel Henry-Mantilla <daniel.henry.mantilla@gmail.com>"]
99
edition = "2021"
1010

0 commit comments

Comments
 (0)