wasmi/engine/limits/
stack.rs1use core::{
2 error::Error,
3 fmt::{self, Display},
4};
5
6const DEFAULT_MAX_RECURSION_DEPTH: usize = 1000;
8
9const DEFAULT_MIN_STACK_HEIGHT: usize = 1_000;
11
12const DEFAULT_MAX_STACK_HEIGHT: usize = 1_000_000;
14
15const DEFAULT_MAX_CACHED_STACKS: usize = 2;
17
18#[derive(Debug)]
20pub enum StackConfigError {
21 MinStackHeightExceedsMax,
23}
24
25impl Error for StackConfigError {}
26
27impl Display for StackConfigError {
28 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29 match self {
30 StackConfigError::MinStackHeightExceedsMax => {
31 write!(f, "minimum value stack height exceeds maximum stack height")
32 }
33 }
34 }
35}
36
37#[derive(Debug, Copy, Clone)]
41pub struct StackConfig {
42 max_recursion_depth: usize,
44 min_stack_height: usize,
46 max_stack_height: usize,
48 max_cached_stacks: usize,
50}
51
52impl Default for StackConfig {
53 fn default() -> Self {
54 Self {
55 max_recursion_depth: DEFAULT_MAX_RECURSION_DEPTH,
56 min_stack_height: DEFAULT_MIN_STACK_HEIGHT,
57 max_stack_height: DEFAULT_MAX_STACK_HEIGHT,
58 max_cached_stacks: DEFAULT_MAX_CACHED_STACKS,
59 }
60 }
61}
62
63impl StackConfig {
64 pub fn set_max_recursion_depth(&mut self, value: usize) {
66 self.max_recursion_depth = value;
67 }
68
69 pub fn set_min_stack_height(&mut self, value: usize) -> Result<(), StackConfigError> {
75 if value > self.max_stack_height {
76 return Err(StackConfigError::MinStackHeightExceedsMax);
77 }
78 self.min_stack_height = value;
79 Ok(())
80 }
81
82 pub fn set_max_stack_height(&mut self, value: usize) -> Result<(), StackConfigError> {
88 if value < self.max_stack_height {
89 return Err(StackConfigError::MinStackHeightExceedsMax);
90 }
91 self.max_stack_height = value;
92 Ok(())
93 }
94
95 pub fn set_max_cached_stacks(&mut self, value: usize) {
99 self.max_recursion_depth = value;
100 }
101
102 pub fn max_recursion_depth(&self) -> usize {
104 self.max_recursion_depth
105 }
106
107 pub fn min_stack_height(&self) -> usize {
109 self.min_stack_height
110 }
111
112 pub fn max_stack_height(&self) -> usize {
114 self.max_stack_height
115 }
116
117 pub fn max_cached_stacks(&mut self) -> usize {
121 self.max_cached_stacks
122 }
123}
124
125#[deprecated(
127 since = "0.51.0",
128 note = "\
129 use `Config::set_{min,max}_stack_height`, \
130 `Config::max_recursion_depth` and \
131 `Config::set_max_cached_stacks` instead"
132)]
133#[derive(Debug, Copy, Clone)]
134pub struct StackLimits {
135 pub initial_value_stack_height: usize,
137 pub maximum_value_stack_height: usize,
139 pub maximum_recursion_depth: usize,
141}
142
143#[expect(deprecated)]
144impl StackLimits {
145 pub fn new(
151 initial_value_stack_height: usize,
152 maximum_value_stack_height: usize,
153 maximum_recursion_depth: usize,
154 ) -> Result<Self, StackConfigError> {
155 if initial_value_stack_height > maximum_value_stack_height {
156 return Err(StackConfigError::MinStackHeightExceedsMax);
157 }
158 Ok(Self {
159 initial_value_stack_height,
160 maximum_value_stack_height,
161 maximum_recursion_depth,
162 })
163 }
164}
165
166#[expect(deprecated)]
167impl Default for StackLimits {
168 fn default() -> Self {
169 let register_len = size_of::<u64>();
170 let initial_value_stack_height = DEFAULT_MIN_STACK_HEIGHT / register_len;
171 let maximum_value_stack_height = DEFAULT_MAX_STACK_HEIGHT / register_len;
172 Self {
173 initial_value_stack_height,
174 maximum_value_stack_height,
175 maximum_recursion_depth: DEFAULT_MAX_RECURSION_DEPTH,
176 }
177 }
178}