use alloc::boxed::Box;
use crate::{rule_cache::RuleCache, unwind_rule::UnwindRule};
pub use crate::rule_cache::CacheStats;
pub trait AllocationPolicy {
type GimliUnwindContextStorage<R: gimli::ReaderOffset>: gimli::UnwindContextStorage<R>;
type GimliEvaluationStorage<R: gimli::Reader>: gimli::EvaluationStorage<R>;
}
pub struct MustNotAllocateDuringUnwind;
#[doc(hidden)]
pub struct StoreOnStack;
impl<RO: gimli::ReaderOffset> gimli::UnwindContextStorage<RO> for StoreOnStack {
type Rules = [(gimli::Register, gimli::RegisterRule<RO>); 192];
type Stack = [gimli::UnwindTableRow<RO, Self>; 4];
}
impl<R: gimli::Reader> gimli::EvaluationStorage<R> for StoreOnStack {
type Stack = [gimli::Value; 64];
type ExpressionStack = [(R, R); 4];
type Result = [gimli::Piece<R>; 1];
}
impl AllocationPolicy for MustNotAllocateDuringUnwind {
type GimliUnwindContextStorage<R: gimli::ReaderOffset> = StoreOnStack;
type GimliEvaluationStorage<R: gimli::Reader> = StoreOnStack;
}
pub struct MayAllocateDuringUnwind;
impl AllocationPolicy for MayAllocateDuringUnwind {
type GimliUnwindContextStorage<R: gimli::ReaderOffset> = gimli::StoreOnHeap;
type GimliEvaluationStorage<R: gimli::Reader> = gimli::StoreOnHeap;
}
pub struct Cache<R: UnwindRule, P: AllocationPolicy = MayAllocateDuringUnwind> {
pub(crate) gimli_unwind_context:
Box<gimli::UnwindContext<usize, P::GimliUnwindContextStorage<usize>>>,
pub(crate) rule_cache: RuleCache<R>,
}
impl<R: UnwindRule, P: AllocationPolicy> Cache<R, P> {
pub fn new() -> Self {
Self {
gimli_unwind_context: Box::new(gimli::UnwindContext::new_in()),
rule_cache: RuleCache::new(),
}
}
}
impl<R: UnwindRule, P: AllocationPolicy> Default for Cache<R, P> {
fn default() -> Self {
Self::new()
}
}