Skip to content

Commit 9438505

Browse files
chore: re-use stack allocations
Signed-off-by: Henry <mail@henrygressmann.de>
1 parent 02a5650 commit 9438505

File tree

16 files changed

+533
-543
lines changed

16 files changed

+533
-543
lines changed

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/tinywasm/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ log={workspace=true, optional=true}
2020
tinywasm-parser={version="0.9.0-alpha.0", path="../parser", default-features=false, optional=true}
2121
tinywasm-types={version="0.9.0-alpha.0", path="../types", default-features=false}
2222
libm={version="0.2", default-features=false}
23+
allocator-api2={version="0.4", optional=true}
2324

2425
[dev-dependencies]
2526
wasm-testsuite.workspace=true
@@ -48,6 +49,9 @@ archive=["tinywasm-types/archive"]
4849
# canonicalize all NaN values to a single representation
4950
canonicalize_nans=[]
5051

52+
# support for the allocator-api2 crate
53+
allocator-api2=["dep:allocator-api2"]
54+
5155
[[test]]
5256
name="test-wasm-1"
5357
harness=false

crates/tinywasm/src/config.rs

Lines changed: 0 additions & 115 deletions
This file was deleted.

crates/tinywasm/src/engine.rs

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
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

Comments
 (0)