|
| 1 | +use core::fmt::Debug; |
| 2 | + |
| 3 | +use alloc::sync::Arc; |
| 4 | + |
| 5 | +/// Global configuration for the WebAssembly interpreter |
| 6 | +/// |
| 7 | +/// Can be cheaply cloned and shared across multiple executions and threads. |
| 8 | +#[derive(Clone)] |
| 9 | +pub struct Engine { |
| 10 | + pub(crate) inner: Arc<EngineInner>, |
| 11 | +} |
| 12 | + |
| 13 | +impl Debug for Engine { |
| 14 | + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { |
| 15 | + f.debug_struct("Engine").finish() |
| 16 | + } |
| 17 | +} |
| 18 | + |
| 19 | +impl Engine { |
| 20 | + /// Create a new engine with the given configuration |
| 21 | + pub fn new(config: Config) -> Self { |
| 22 | + Self { inner: Arc::new(EngineInner { config }) } |
| 23 | + } |
| 24 | + |
| 25 | + /// Get a reference to the engine's configuration |
| 26 | + pub fn config(&self) -> &Config { |
| 27 | + &self.inner.config |
| 28 | + } |
| 29 | +} |
| 30 | + |
| 31 | +impl Default for Engine { |
| 32 | + fn default() -> Engine { |
| 33 | + Engine::new(Config::default()) |
| 34 | + } |
| 35 | +} |
| 36 | + |
| 37 | +pub(crate) struct EngineInner { |
| 38 | + pub(crate) config: Config, |
| 39 | + // pub(crate) allocator: Box<dyn Allocator + Send + Sync>, |
| 40 | +} |
| 41 | + |
| 42 | +// pub(crate) trait Allocator {} |
| 43 | +// pub(crate) struct DefaultAllocator; |
| 44 | +// impl Allocator for DefaultAllocator {} |
| 45 | + |
| 46 | +/// Default initial size for the 32-bit value stack (i32, f32 values). |
| 47 | +pub const DEFAULT_VALUE_STACK_32_INIT_SIZE: usize = 32 * 1024; // 32KB |
| 48 | + |
| 49 | +/// Default initial size for the 64-bit value stack (i64, f64 values). |
| 50 | +pub const DEFAULT_VALUE_STACK_64_INIT_SIZE: usize = 16 * 1024; // 16KB |
| 51 | + |
| 52 | +/// Default initial size for the 128-bit value stack (v128 values). |
| 53 | +pub const DEFAULT_VALUE_STACK_128_INIT_SIZE: usize = 8 * 1024; // 8KB |
| 54 | + |
| 55 | +/// Default initial size for the reference value stack (funcref, externref values). |
| 56 | +pub const DEFAULT_VALUE_STACK_REF_INIT_SIZE: usize = 1024; // 1KB |
| 57 | + |
| 58 | +/// Default initial size for the block stack. |
| 59 | +pub const DEFAULT_BLOCK_STACK_INIT_SIZE: usize = 128; |
| 60 | + |
| 61 | +/// Default initial size for the call stack. |
| 62 | +pub const DEFAULT_CALL_STACK_INIT_SIZE: usize = 128; |
| 63 | + |
| 64 | +/// Configuration for the WebAssembly interpreter |
| 65 | +#[derive(Debug, Clone)] |
| 66 | +#[non_exhaustive] |
| 67 | +pub struct Config { |
| 68 | + /// Initial size of the 32-bit value stack (i32, f32 values). |
| 69 | + pub stack_32_init_size: usize, |
| 70 | + /// Initial size of the 64-bit value stack (i64, f64 values). |
| 71 | + pub stack_64_init_size: usize, |
| 72 | + /// Initial size of the 128-bit value stack (v128 values). |
| 73 | + pub stack_128_init_size: usize, |
| 74 | + /// Initial size of the reference value stack (funcref, externref values). |
| 75 | + pub stack_ref_init_size: usize, |
| 76 | + /// Optional maximum sizes for the stacks. If set, the interpreter will enforce these limits and return an error if they are exceeded. |
| 77 | + pub stack_32_max_size: Option<usize>, |
| 78 | + /// Optional maximum sizes for the stacks. If set, the interpreter will enforce these limits and return an error if they are exceeded. |
| 79 | + pub stack_64_max_size: Option<usize>, |
| 80 | + /// Optional maximum sizes for the stacks. If set, the interpreter will enforce these limits and return an error if they are exceeded. |
| 81 | + pub stack_128_max_size: Option<usize>, |
| 82 | + /// Optional maximum sizes for the stacks. If set, the interpreter will enforce these limits and return an error if they are exceeded. |
| 83 | + pub stack_ref_max_size: Option<usize>, |
| 84 | + |
| 85 | + /// Initial size of the call stack. |
| 86 | + pub call_stack_init_size: usize, |
| 87 | + /// The maximum size of the call stack. If set, the interpreter will enforce this limit and return an error if it is exceeded. |
| 88 | + pub call_stack_max_size: Option<usize>, |
| 89 | + |
| 90 | + /// Initial size of the control stack (block stack). |
| 91 | + pub block_stack_init_size: usize, |
| 92 | + /// Optional maximum size for the control stack (block stack). If set, the interpreter will enforce this limit and return an error if it is exceeded. |
| 93 | + pub block_stack_max_size: Option<usize>, |
| 94 | +} |
| 95 | + |
| 96 | +impl Config { |
| 97 | + /// Create a new stack configuration with default settings. |
| 98 | + pub fn new() -> Self { |
| 99 | + Self::default() |
| 100 | + } |
| 101 | + |
| 102 | + /// Set the same maximum size for all stacks. If set, the interpreter will enforce this limit and return an error if it is exceeded. |
| 103 | + pub fn with_max_stack_size(mut self, max_size: usize) -> Self { |
| 104 | + self.stack_32_max_size = Some(max_size); |
| 105 | + self.stack_64_max_size = Some(max_size); |
| 106 | + self.stack_128_max_size = Some(max_size); |
| 107 | + self.stack_ref_max_size = Some(max_size); |
| 108 | + self.block_stack_max_size = Some(max_size); |
| 109 | + self |
| 110 | + } |
| 111 | + |
| 112 | + /// Set the same initial size for all stacks. |
| 113 | + pub fn with_initial_stack_size(mut self, init_size: usize) -> Self { |
| 114 | + self.stack_32_init_size = init_size; |
| 115 | + self.stack_64_init_size = init_size; |
| 116 | + self.stack_128_init_size = init_size; |
| 117 | + self.stack_ref_init_size = init_size; |
| 118 | + self.block_stack_init_size = init_size; |
| 119 | + self |
| 120 | + } |
| 121 | +} |
| 122 | + |
| 123 | +impl Default for Config { |
| 124 | + fn default() -> Self { |
| 125 | + Self { |
| 126 | + stack_32_init_size: DEFAULT_VALUE_STACK_32_INIT_SIZE, |
| 127 | + stack_64_init_size: DEFAULT_VALUE_STACK_64_INIT_SIZE, |
| 128 | + stack_128_init_size: DEFAULT_VALUE_STACK_128_INIT_SIZE, |
| 129 | + stack_ref_init_size: DEFAULT_VALUE_STACK_REF_INIT_SIZE, |
| 130 | + block_stack_init_size: DEFAULT_BLOCK_STACK_INIT_SIZE, |
| 131 | + call_stack_init_size: DEFAULT_CALL_STACK_INIT_SIZE, |
| 132 | + call_stack_max_size: None, |
| 133 | + stack_32_max_size: None, |
| 134 | + stack_64_max_size: None, |
| 135 | + stack_128_max_size: None, |
| 136 | + stack_ref_max_size: None, |
| 137 | + block_stack_max_size: None, |
| 138 | + } |
| 139 | + } |
| 140 | +} |
0 commit comments