diff --git a/src/read/cfi.rs b/src/read/cfi.rs index 25abc1cb..b092fb61 100644 --- a/src/read/cfi.rs +++ b/src/read/cfi.rs @@ -1,5 +1,5 @@ #[cfg(feature = "read")] -use alloc::vec::Vec; +use alloc::boxed::Box; use core::cmp::{Ord, Ordering}; use core::fmt::{self, Debug}; @@ -1894,11 +1894,13 @@ pub trait UnwindContextStorage: Sized { #[cfg(feature = "read")] const MAX_RULES: usize = 192; +#[cfg(feature = "read")] +const MAX_UNWIND_STACK_DEPTH: usize = 4; #[cfg(feature = "read")] impl UnwindContextStorage for StoreOnHeap { type Rules = [(Register, RegisterRule); MAX_RULES]; - type Stack = Vec>; + type Stack = Box<[UnwindTableRow; MAX_UNWIND_STACK_DEPTH]>; } /// Common context needed when evaluating the call frame unwinding information. diff --git a/src/read/util.rs b/src/read/util.rs index 747418ba..041ca5af 100644 --- a/src/read/util.rs +++ b/src/read/util.rs @@ -71,7 +71,39 @@ macro_rules! impl_array { } } +#[cfg(feature = "read")] +macro_rules! impl_box { + () => {}; + ($n:literal $($rest:tt)*) => { + // SAFETY: does not modify the content in storage. + unsafe impl Sealed for Box<[T; $n]> { + type Storage = Box<[MaybeUninit; $n]>; + + fn new_storage() -> Self::Storage { + // SAFETY: An uninitialized `[MaybeUninit<_>; _]` is valid. + Box::new(unsafe { MaybeUninit::uninit().assume_init() }) + } + } + + impl ArrayLike for Box<[T; $n]> { + type Item = T; + + fn as_slice(storage: &Self::Storage) -> &[MaybeUninit] { + &storage[..] + } + + fn as_mut_slice(storage: &mut Self::Storage) -> &mut [MaybeUninit] { + &mut storage[..] + } + } + + impl_box!($($rest)*); + } +} + impl_array!(0 1 2 3 4 8 16 32 64 128 192); +#[cfg(feature = "read")] +impl_box!(0 1 2 3 4 8 16 32 64 128 192); #[cfg(feature = "read")] unsafe impl Sealed for Vec {