wasmtime_winch/
builder.rs

1use crate::compiler::Compiler;
2use anyhow::{Result, bail};
3use std::sync::Arc;
4use target_lexicon::Triple;
5use wasmtime_cranelift::isa_builder::IsaBuilder;
6use wasmtime_environ::{CompilerBuilder, Setting, Tunables};
7use winch_codegen::{TargetIsa, isa};
8
9/// Compiler builder.
10struct Builder {
11    inner: IsaBuilder<Result<Box<dyn TargetIsa>>>,
12    cranelift: Box<dyn CompilerBuilder>,
13    tunables: Option<Tunables>,
14}
15
16pub fn builder(triple: Option<Triple>) -> Result<Box<dyn CompilerBuilder>> {
17    let inner = IsaBuilder::new(triple.clone(), |triple| isa::lookup(triple))?;
18    let cranelift = wasmtime_cranelift::builder(triple)?;
19    Ok(Box::new(Builder {
20        inner,
21        cranelift,
22        tunables: None,
23    }))
24}
25
26impl CompilerBuilder for Builder {
27    fn triple(&self) -> &target_lexicon::Triple {
28        self.inner.triple()
29    }
30
31    fn target(&mut self, target: target_lexicon::Triple) -> Result<()> {
32        self.inner.target(target.clone())?;
33        self.cranelift.target(target)?;
34        Ok(())
35    }
36
37    fn set(&mut self, name: &str, value: &str) -> Result<()> {
38        self.inner.set(name, value)?;
39        self.cranelift.set(name, value)?;
40        Ok(())
41    }
42
43    fn enable(&mut self, name: &str) -> Result<()> {
44        self.inner.enable(name)?;
45        self.cranelift.enable(name)?;
46        Ok(())
47    }
48
49    fn settings(&self) -> Vec<Setting> {
50        self.inner.settings()
51    }
52
53    fn set_tunables(&mut self, tunables: Tunables) -> Result<()> {
54        if !tunables.winch_callable {
55            bail!("Winch requires the winch calling convention");
56        }
57
58        if !tunables.table_lazy_init {
59            bail!("Winch requires the table-lazy-init option to be enabled");
60        }
61
62        if !tunables.signals_based_traps {
63            bail!("Winch requires the signals-based-traps option to be enabled");
64        }
65
66        if tunables.generate_native_debuginfo {
67            bail!("Winch does not currently support generating native debug information");
68        }
69
70        self.tunables = Some(tunables.clone());
71        self.cranelift.set_tunables(tunables)?;
72        Ok(())
73    }
74
75    fn build(&self) -> Result<Box<dyn wasmtime_environ::Compiler>> {
76        let isa = self.inner.build()?;
77        let cranelift = self.cranelift.build()?;
78        let tunables = self
79            .tunables
80            .as_ref()
81            .expect("set_tunables not called")
82            .clone();
83        Ok(Box::new(Compiler::new(isa, cranelift, tunables)))
84    }
85
86    fn enable_incremental_compilation(
87        &mut self,
88        _cache_store: Arc<dyn wasmtime_environ::CacheStore>,
89    ) -> Result<()> {
90        bail!("incremental compilation is not supported on this platform");
91    }
92}
93
94impl std::fmt::Debug for Builder {
95    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
96        write!(f, "Builder: {{ triple: {:?} }}", self.triple())
97    }
98}