@@ -54,23 +54,50 @@ pub const DEFAULT_VALUE_STACK_128_SIZE: usize = 4 * 1024; // 4k slots
5454/// Default maximum size for the call stack (function frames).
5555pub const DEFAULT_MAX_CALL_STACK_SIZE : usize = 1024 ; // 1024 frames
5656
57+ /// Stack allocation policy.
58+ #[ derive( Clone , Copy , PartialEq , Eq ) ]
59+ #[ cfg_attr( feature = "debug" , derive( Debug ) ) ]
60+ pub struct StackConfig {
61+ /// Initial reserved capacity for the stack.
62+ pub initial_size : usize ,
63+ /// Maximum number of elements the stack may contain.
64+ pub max_size : usize ,
65+ /// Whether the stack may grow past its initial capacity.
66+ pub dynamic : bool ,
67+ }
68+
69+ impl StackConfig {
70+ /// Creates a fixed-capacity stack that reserves all space up front.
71+ pub const fn fixed ( size : usize ) -> Self {
72+ Self { initial_size : size, max_size : size, dynamic : false }
73+ }
74+
75+ /// Creates a dynamically growing stack with the given initial and maximum sizes.
76+ pub const fn dynamic ( initial_size : usize , max_size : usize ) -> Self {
77+ assert ! ( initial_size <= max_size, "initial_size must be less than or equal to max_size" ) ;
78+ Self { initial_size, max_size, dynamic : true }
79+ }
80+ }
81+
5782/// Configuration for the WebAssembly interpreter
5883#[ derive( Clone ) ]
5984#[ cfg_attr( feature = "debug" , derive( Debug ) ) ]
6085#[ non_exhaustive]
6186pub struct Config {
62- /// Size of the 32-bit value stack (i32, f32, ref values).
63- pub stack_32_size : usize ,
64- /// Size of the 64-bit value stack (i64, f64 values).
65- pub stack_64_size : usize ,
66- /// Size of the 128-bit value stack (v128 values).
67- pub stack_128_size : usize ,
68- /// Maximum size of the call stack
69- pub max_call_stack_size : usize ,
87+ /// Configuration for the 32-bit value stack (i32, f32, ref values).
88+ pub value_stack_32 : StackConfig ,
89+ /// Configuration for the 64-bit value stack (i64, f64 values).
90+ pub value_stack_64 : StackConfig ,
91+ /// Configuration for the 128-bit value stack (v128 values).
92+ pub value_stack_128 : StackConfig ,
93+ /// Configuration for the call stack.
94+ pub call_stack : StackConfig ,
7095 /// Fuel accounting policy used by budgeted execution.
7196 pub fuel_policy : FuelPolicy ,
7297 /// Backend used for runtime memories.
7398 pub memory_backend : MemoryBackend ,
99+ /// Whether memory and stack allocation failures should trap instead of degrading into normal operation failure modes.
100+ pub trap_on_oom : bool ,
74101}
75102
76103impl Config {
@@ -91,6 +118,44 @@ impl Config {
91118 self
92119 }
93120
121+ /// Set the configuration used for the 32-bit value stack.
122+ pub fn with_value_stack_32 ( mut self , stack : StackConfig ) -> Self {
123+ self . value_stack_32 = stack;
124+ self
125+ }
126+
127+ /// Set the same configuration for all value stack lanes.
128+ pub fn with_value_stack ( mut self , stack : StackConfig ) -> Self {
129+ self . value_stack_32 = stack;
130+ self . value_stack_64 = stack;
131+ self . value_stack_128 = stack;
132+ self
133+ }
134+
135+ /// Set the configuration used for the 64-bit value stack.
136+ pub fn with_value_stack_64 ( mut self , stack : StackConfig ) -> Self {
137+ self . value_stack_64 = stack;
138+ self
139+ }
140+
141+ /// Set the configuration used for the 128-bit value stack.
142+ pub fn with_value_stack_128 ( mut self , stack : StackConfig ) -> Self {
143+ self . value_stack_128 = stack;
144+ self
145+ }
146+
147+ /// Set the configuration used for the call stack.
148+ pub fn with_call_stack ( mut self , stack : StackConfig ) -> Self {
149+ self . call_stack = stack;
150+ self
151+ }
152+
153+ /// Configure whether memory and stack allocation failures trap immediately.
154+ pub fn with_trap_on_oom ( mut self , trap_on_oom : bool ) -> Self {
155+ self . trap_on_oom = trap_on_oom;
156+ self
157+ }
158+
94159 /// Get the current fuel policy
95160 pub fn fuel_policy ( & self ) -> FuelPolicy {
96161 self . fuel_policy
@@ -100,17 +165,22 @@ impl Config {
100165 pub fn memory_backend ( & self ) -> & MemoryBackend {
101166 & self . memory_backend
102167 }
168+
169+ pub ( crate ) const fn trap_on_oom ( & self ) -> bool {
170+ self . trap_on_oom
171+ }
103172}
104173
105174impl Default for Config {
106175 fn default ( ) -> Self {
107176 Self {
108- stack_32_size : DEFAULT_VALUE_STACK_32_SIZE ,
109- stack_64_size : DEFAULT_VALUE_STACK_64_SIZE ,
110- stack_128_size : DEFAULT_VALUE_STACK_128_SIZE ,
111- max_call_stack_size : DEFAULT_MAX_CALL_STACK_SIZE ,
177+ value_stack_32 : StackConfig :: fixed ( DEFAULT_VALUE_STACK_32_SIZE ) ,
178+ value_stack_64 : StackConfig :: fixed ( DEFAULT_VALUE_STACK_64_SIZE ) ,
179+ value_stack_128 : StackConfig :: fixed ( DEFAULT_VALUE_STACK_128_SIZE ) ,
180+ call_stack : StackConfig :: fixed ( DEFAULT_MAX_CALL_STACK_SIZE ) ,
112181 fuel_policy : FuelPolicy :: default ( ) ,
113182 memory_backend : MemoryBackend :: default ( ) ,
183+ trap_on_oom : false ,
114184 }
115185 }
116186}
0 commit comments