use crate::core::UntypedVal;
use core::{
fmt::{self, Display},
mem::size_of,
};
const DEFAULT_MIN_VALUE_STACK_HEIGHT: usize = 1024;
const DEFAULT_MAX_VALUE_STACK_HEIGHT: usize = 1024 * DEFAULT_MIN_VALUE_STACK_HEIGHT;
const DEFAULT_MAX_RECURSION_DEPTH: usize = 1024;
#[derive(Debug, Copy, Clone)]
pub struct StackLimits {
pub initial_value_stack_height: usize,
pub maximum_value_stack_height: usize,
pub maximum_recursion_depth: usize,
}
#[derive(Debug)]
pub enum LimitsError {
InitialValueStackExceedsMaximum,
}
#[cfg(feature = "std")]
impl std::error::Error for LimitsError {}
impl Display for LimitsError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
LimitsError::InitialValueStackExceedsMaximum => {
write!(f, "initial value stack height exceeds maximum stack height")
}
}
}
}
impl StackLimits {
pub fn new(
initial_value_stack_height: usize,
maximum_value_stack_height: usize,
maximum_recursion_depth: usize,
) -> Result<Self, LimitsError> {
if initial_value_stack_height > maximum_value_stack_height {
return Err(LimitsError::InitialValueStackExceedsMaximum);
}
Ok(Self {
initial_value_stack_height,
maximum_value_stack_height,
maximum_recursion_depth,
})
}
}
impl Default for StackLimits {
fn default() -> Self {
let register_len = size_of::<UntypedVal>();
let initial_value_stack_height = DEFAULT_MIN_VALUE_STACK_HEIGHT / register_len;
let maximum_value_stack_height = DEFAULT_MAX_VALUE_STACK_HEIGHT / register_len;
Self {
initial_value_stack_height,
maximum_value_stack_height,
maximum_recursion_depth: DEFAULT_MAX_RECURSION_DEPTH,
}
}
}