From dc421e002b191fe9b4dab1a31c46da00a52b6a80 Mon Sep 17 00:00:00 2001 From: Parker TenBroeck <51721964+ParkerTenBroeck@users.noreply.github.com> Date: Mon, 13 Jun 2022 13:44:40 -0400 Subject: [PATCH 1/4] added optional no_std feature --- Cargo.toml | 4 ++++ src/ffi.rs | 2 +- src/lib.rs | 49 ++++++++++++++++++++++++++++++++++++------------- 3 files changed, 41 insertions(+), 14 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5ed1a15..e9a2a85 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,3 +15,7 @@ lazy_static = "1.4.0" [build-dependencies] cc = "1.0" rustc_version = "0.2" + +[features] +default = [] +no_std = [] diff --git a/src/ffi.rs b/src/ffi.rs index 0f6b49b..b417b56 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -1,4 +1,4 @@ -use std::ffi::c_void; +use core::ffi::c_void; pub type CallbackRaw = unsafe extern "C" fn (ptr: *mut c_void, data: *mut c_void)->(); diff --git a/src/lib.rs b/src/lib.rs index b35218c..ee9c8d5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -85,13 +85,17 @@ //! # License //! MIT licensed -#![cfg_attr(nightly, feature(test))] + +#![cfg_attr(all(nightly, not(feature = "no_std")), feature(test))] #![allow(dead_code)] -#[cfg(nightly)] extern crate test; +#![cfg_attr(all(feature = "no_std", not(test)), no_std)] + +#[cfg(all(nightly, not(feature = "no_std"), not(test)))] extern crate test; -use std::{ +#[allow(unused)] +use core::{ mem::{ self, MaybeUninit, @@ -106,7 +110,13 @@ use std::{ ptr, }; -pub mod avec; pub use avec::AVec; +#[cfg(test)] +mod tests; + +#[cfg(not(feature = "no_std"))] +pub mod avec; +#[cfg(not(feature = "no_std"))] +pub use avec::AVec; mod ffi; /// Allocate a runtime length uninitialised byte buffer on the stack, call `callback` with this buffer, and then deallocate the buffer. @@ -157,7 +167,15 @@ where F: FnOnce(&mut [MaybeUninit]) -> T unsafe { let slice = slice::from_raw_parts_mut(allocad_ptr as *mut MaybeUninit, size); let callback = ManuallyDrop::take(&mut callback); - rval = MaybeUninit::new(panic::catch_unwind(AssertUnwindSafe(move || callback(slice)))); + + #[cfg(feature = "no_std")] + { + rval = MaybeUninit::new(callback(slice)); + } + #[cfg(not(feature = "no_std"))] + { + rval = MaybeUninit::new(std::panic::catch_unwind(AssertUnwindSafe(move || callback(slice)))); + } } }; @@ -177,12 +195,18 @@ where F: FnOnce(&mut [MaybeUninit]) -> T ffi::alloca_trampoline(size, create_trampoline(&callback), &mut callback as *mut _ as *mut c_void); rval.assume_init() }; - - match rval + #[cfg(feature = "no_std")] { - Ok(v) => v, - Err(pan) => panic::resume_unwind(pan), + return rval } + #[cfg(not(feature = "no_std"))] + { + match rval { + Ok(v) => v, + Err(pan) => std::panic::resume_unwind(pan), + } + } + } /// A module of helper functions for slice memory manipulation @@ -192,7 +216,7 @@ pub mod helpers { use super::*; #[inline(always)] pub(crate) fn align_buffer_to(ptr: *mut u8) -> *mut T { - use std::mem::align_of; + use core::mem::align_of; ((ptr as usize) + align_of::() - (ptr as usize) % align_of::()) as *mut T } @@ -245,7 +269,7 @@ where F: FnOnce(&mut [u8]) -> T #[inline] pub fn stackalloc_uninit(size: usize, callback: F) -> U where F: FnOnce(&mut [MaybeUninit]) -> U { - let size_bytes = (std::mem::size_of::() * size) + std::mem::align_of::(); + let size_bytes = (core::mem::size_of::() * size) + core::mem::align_of::(); alloca(size_bytes, move |buf| { let abuf = align_buffer_to::>(buf.as_mut_ptr() as *mut u8); debug_assert!(buf.as_ptr_range().contains(&(abuf as *const _ as *const MaybeUninit))); @@ -379,5 +403,4 @@ where F: FnOnce(&mut [T]) -> U, } -#[cfg(test)] -mod tests; + From 58ee35daadf2650e6b20769f380f660468cf7f10 Mon Sep 17 00:00:00 2001 From: Parker TenBroeck <51721964+ParkerTenBroeck@users.noreply.github.com> Date: Mon, 13 Jun 2022 17:39:31 -0400 Subject: [PATCH 2/4] fixed test dependency not being present for tests on nightly --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index ee9c8d5..42e9121 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -92,7 +92,7 @@ #![cfg_attr(all(feature = "no_std", not(test)), no_std)] -#[cfg(all(nightly, not(feature = "no_std"), not(test)))] extern crate test; +#[cfg(all(nightly, test))] extern crate test; #[allow(unused)] use core::{ From 72d2860851657ae5c48c638aaca8a3bd4f508d29 Mon Sep 17 00:00:00 2001 From: Parker TenBroeck <51721964+ParkerTenBroeck@users.noreply.github.com> Date: Mon, 13 Jun 2022 17:49:19 -0400 Subject: [PATCH 3/4] fixed test feature not being enabled for nightly no_std --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 42e9121..25120a2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -86,7 +86,7 @@ //! MIT licensed -#![cfg_attr(all(nightly, not(feature = "no_std")), feature(test))] +#![cfg_attr(all(nightly, test), feature(test))] #![allow(dead_code)] From 84255549df283fbe8ec674ae49b47801070c0415 Mon Sep 17 00:00:00 2001 From: Parker TenBroeck <51721964+ParkerTenBroeck@users.noreply.github.com> Date: Tue, 14 Jun 2022 19:54:36 -0400 Subject: [PATCH 4/4] Added catch_unwind for no_std added catch_unwind functionality for no_std where unwinding panics are turned into aborting panics --- src/lib.rs | 77 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 57 insertions(+), 20 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 25120a2..bfc5e32 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -85,12 +85,13 @@ //! # License //! MIT licensed - -#![cfg_attr(all(nightly, test), feature(test))] +#![cfg_attr(nightly, feature(test))] #![allow(dead_code)] + #![cfg_attr(all(feature = "no_std", not(test)), no_std)] +#![cfg_attr(all(feature = "no_std"), feature(core_intrinsics))] #[cfg(all(nightly, test))] extern crate test; @@ -110,13 +111,7 @@ use core::{ ptr, }; -#[cfg(test)] -mod tests; - -#[cfg(not(feature = "no_std"))] -pub mod avec; -#[cfg(not(feature = "no_std"))] -pub use avec::AVec; +pub mod avec; pub use avec::AVec; mod ffi; /// Allocate a runtime length uninitialised byte buffer on the stack, call `callback` with this buffer, and then deallocate the buffer. @@ -170,7 +165,7 @@ where F: FnOnce(&mut [MaybeUninit]) -> T #[cfg(feature = "no_std")] { - rval = MaybeUninit::new(callback(slice)); + rval = MaybeUninit::new(catch_unwind(move||{callback(slice)})); } #[cfg(not(feature = "no_std"))] { @@ -192,21 +187,62 @@ where F: FnOnce(&mut [MaybeUninit]) -> T } let rval = unsafe { - ffi::alloca_trampoline(size, create_trampoline(&callback), &mut callback as *mut _ as *mut c_void); - rval.assume_init() + ffi::alloca_trampoline(size, create_trampoline(&callback), &mut callback as *mut _ as *mut c_void); + rval.assume_init() }; - #[cfg(feature = "no_std")] - { - return rval - } + #[cfg(not(feature = "no_std"))] + match rval { - match rval { - Ok(v) => v, - Err(pan) => std::panic::resume_unwind(pan), + Ok(v) => v, + Err(pan) => std::panic::resume_unwind(pan), + } + #[cfg(feature = "no_std")] + return match rval{ + Ok(v) => v, + Err(()) => core::panic!(), + } +} + + + +#[cfg(feature = "no_std")] +unsafe fn catch_unwind R>(f: F) -> Result{ + + union Data { + f: ManuallyDrop, + r: ManuallyDrop, + p: (), + } + + #[inline] + fn do_call R, R>(data: *mut u8) { + unsafe { + let data = data as *mut Data; + let data = &mut (*data); + let f = ManuallyDrop::take(&mut data.f); + data.r = ManuallyDrop::new(f()); + } + } + + #[inline] + fn do_catch R, R>(data: *mut u8, _payload: *mut u8) { + unsafe { + let data = data as *mut Data; + let data = &mut (*data); + data.p = () } } + let mut data = Data { f: ManuallyDrop::new(f) }; + let data_ptr = &mut data as *mut _ as *mut u8; + + + if core::intrinsics::r#try(do_call::, data_ptr, do_catch::) == 0{ + Result::Ok(ManuallyDrop::into_inner(data.r)) + }else{ + Result::Err(()) + } } /// A module of helper functions for slice memory manipulation @@ -403,4 +439,5 @@ where F: FnOnce(&mut [T]) -> U, } - +#[cfg(test)] +mod tests;