xref: /wasmtime-44.0.1/crates/winch/src/builder.rs (revision 0f62967f)
1 use crate::compiler::Compiler;
2 use std::sync::Arc;
3 use target_lexicon::Triple;
4 use wasmtime_cranelift::isa_builder::IsaBuilder;
5 use wasmtime_environ::error::{Result, bail};
6 use wasmtime_environ::{CompilerBuilder, Setting, Tunables};
7 use winch_codegen::{TargetIsa, isa};
8 
9 /// Compiler builder.
10 struct Builder {
11     inner: IsaBuilder<Result<Box<dyn TargetIsa>>>,
12     cranelift: Box<dyn CompilerBuilder>,
13     tunables: Option<Tunables>,
14 }
15 
builder(triple: Option<Triple>) -> Result<Box<dyn CompilerBuilder>>16 pub 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 
26 impl CompilerBuilder for Builder {
triple(&self) -> &target_lexicon::Triple27     fn triple(&self) -> &target_lexicon::Triple {
28         self.inner.triple()
29     }
30 
target(&mut self, target: target_lexicon::Triple) -> Result<()>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 
set(&mut self, name: &str, value: &str) -> Result<()>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 
enable(&mut self, name: &str) -> Result<()>43     fn enable(&mut self, name: &str) -> Result<()> {
44         self.inner.enable(name)?;
45         self.cranelift.enable(name)?;
46         Ok(())
47     }
48 
settings(&self) -> Vec<Setting>49     fn settings(&self) -> Vec<Setting> {
50         self.inner.settings()
51     }
52 
set_tunables(&mut self, tunables: Tunables) -> Result<()>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.debug_native {
67             bail!("Winch does not currently support generating native debug information");
68         }
69 
70         if tunables.debug_guest {
71             bail!("Winch does not currently support guest-level debugging");
72         }
73 
74         self.tunables = Some(tunables.clone());
75         self.cranelift.set_tunables(tunables)?;
76         Ok(())
77     }
78 
tunables(&self) -> Option<&Tunables>79     fn tunables(&self) -> Option<&Tunables> {
80         self.cranelift.tunables()
81     }
82 
build(&self) -> Result<Box<dyn wasmtime_environ::Compiler>>83     fn build(&self) -> Result<Box<dyn wasmtime_environ::Compiler>> {
84         let isa = self.inner.build()?;
85         let cranelift = self.cranelift.build()?;
86         let tunables = self
87             .tunables
88             .as_ref()
89             .expect("set_tunables not called")
90             .clone();
91         Ok(Box::new(Compiler::new(isa, cranelift, tunables)))
92     }
93 
enable_incremental_compilation( &mut self, _cache_store: Arc<dyn wasmtime_environ::CacheStore>, ) -> Result<()>94     fn enable_incremental_compilation(
95         &mut self,
96         _cache_store: Arc<dyn wasmtime_environ::CacheStore>,
97     ) -> Result<()> {
98         bail!("incremental compilation is not supported on this platform");
99     }
100 }
101 
102 impl std::fmt::Debug for Builder {
fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result103     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
104         write!(f, "Builder: {{ triple: {:?} }}", self.triple())
105     }
106 }
107