wasmtime_winch/
builder.rs

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