use anyhow::Result;
pub use compiler::OptLevel;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
#[non_exhaustive]
pub enum Strategy {
#[default]
Eager,
}
#[derive(Clone, Debug)]
pub struct Config {
pub strategy: Strategy,
pub opt_level: OptLevel,
pub memory_size: u64,
pub stack_size: u64,
pub interruptible: bool,
pub cache_dir: Option<std::path::PathBuf>,
}
impl Default for Config {
fn default() -> Self {
Config {
strategy: Strategy::default(),
opt_level: OptLevel::default(),
memory_size: rv::DEFAULT_MEMORY_SIZE,
stack_size: 1 << 20,
interruptible: true,
cache_dir: None,
}
}
}
impl Config {
pub fn new() -> Self {
Config::default()
}
pub fn strategy(&mut self, strategy: Strategy) -> &mut Self {
self.strategy = strategy;
self
}
pub fn opt_level(&mut self, level: OptLevel) -> &mut Self {
self.opt_level = level;
self
}
pub fn memory_size(&mut self, bytes: u64) -> &mut Self {
self.memory_size = bytes;
self
}
pub fn stack_size(&mut self, bytes: u64) -> &mut Self {
self.stack_size = bytes;
self
}
pub fn interruptible(&mut self, yes: bool) -> &mut Self {
self.interruptible = yes;
self
}
pub fn cache_dir(&mut self, dir: impl Into<std::path::PathBuf>) -> &mut Self {
self.cache_dir = Some(dir.into());
self
}
}
#[derive(Clone)]
pub struct Engine {
inner: compiler::Engine,
config: Config,
}
impl Engine {
pub fn new(config: &Config) -> Result<Self> {
let mut inner = compiler::Engine::new(config.opt_level)?;
if let Some(dir) = &config.cache_dir {
inner = inner.with_cache(dir)?;
}
Ok(Engine {
inner,
config: config.clone(),
})
}
pub fn config(&self) -> &Config {
&self.config
}
pub fn cache_stats(&self) -> (usize, usize) {
self.inner
.cache()
.map(|c| (c.hits(), c.misses()))
.unwrap_or((0, 0))
}
pub(crate) fn compiler(&self) -> &compiler::Engine {
&self.inner
}
}
impl Default for Engine {
fn default() -> Self {
Engine::new(&Config::default()).expect("the host target is supported")
}
}