use std::path::PathBuf;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum CompilationStrategy {
#[default]
Cranelift,
Winch,
}
#[derive(Clone, Debug)]
pub struct WasmtimeEngineConfig {
pub fuel_enabled: bool,
pub default_fuel: u64,
pub fuel_yield_interval: u64,
pub max_memory_bytes: usize,
pub max_table_elements: u32,
pub max_instances: u32,
pub strategy: CompilationStrategy,
pub simd_enabled: bool,
pub multi_memory: bool,
pub cache_dir: Option<PathBuf>,
pub compilation_threads: Option<usize>,
pub stack_size: usize,
}
impl Default for WasmtimeEngineConfig {
fn default() -> Self {
Self {
fuel_enabled: true,
default_fuel: 1_000_000,
fuel_yield_interval: 10_000,
max_memory_bytes: 16 * 1024 * 1024, max_table_elements: 10_000,
max_instances: 10,
strategy: CompilationStrategy::default(),
simd_enabled: true,
multi_memory: false,
cache_dir: None,
compilation_threads: None,
stack_size: 1024 * 1024, }
}
}
impl WasmtimeEngineConfig {
pub fn validate(&self) -> Vec<String> {
let mut problems = Vec::new();
if self.fuel_enabled && self.default_fuel == 0 {
problems.push(
"default_fuel must be > 0 when fuel is enabled. \
Set a fuel budget (recommended: 1_000_000) or disable fuel."
.into(),
);
}
if self.max_memory_bytes == 0 {
problems.push("max_memory_bytes must be > 0.".into());
}
if self.stack_size < 64 * 1024 {
problems.push(
"stack_size is below 64 KiB — this will likely cause \
stack overflows in most components."
.into(),
);
}
problems
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_config_is_valid() {
let config = WasmtimeEngineConfig::default();
let problems = config.validate();
assert!(
problems.is_empty(),
"default config should be valid: {:?}",
problems
);
}
#[test]
fn test_default_config_values() {
let config = WasmtimeEngineConfig::default();
assert!(config.fuel_enabled);
assert_eq!(config.default_fuel, 1_000_000);
assert_eq!(config.max_memory_bytes, 16 * 1024 * 1024);
assert_eq!(config.strategy, CompilationStrategy::Cranelift);
assert!(config.simd_enabled);
}
#[test]
fn test_validation_catches_zero_fuel() {
let config = WasmtimeEngineConfig {
default_fuel: 0,
..WasmtimeEngineConfig::default()
};
let problems = config.validate();
assert_eq!(problems.len(), 1);
assert!(problems[0].contains("default_fuel"));
}
#[test]
fn test_validation_catches_zero_memory() {
let config = WasmtimeEngineConfig {
max_memory_bytes: 0,
..WasmtimeEngineConfig::default()
};
let problems = config.validate();
assert_eq!(problems.len(), 1);
assert!(problems[0].contains("max_memory_bytes"));
}
#[test]
fn test_validation_catches_small_stack() {
let config = WasmtimeEngineConfig {
stack_size: 1024, ..WasmtimeEngineConfig::default()
};
let problems = config.validate();
assert_eq!(problems.len(), 1);
assert!(problems[0].contains("stack_size"));
}
#[test]
fn test_validation_fuel_disabled_zero_ok() {
let config = WasmtimeEngineConfig {
fuel_enabled: false,
default_fuel: 0,
..WasmtimeEngineConfig::default()
};
let problems = config.validate();
assert!(
problems.is_empty(),
"zero fuel should be OK when fuel is disabled"
);
}
#[test]
fn test_compilation_strategy_default() {
assert_eq!(
CompilationStrategy::default(),
CompilationStrategy::Cranelift
);
}
}