wasmtime_cranelift_shared/
isa_builder.rs1use anyhow::Result;
2use cranelift_codegen::isa::IsaBuilder as Builder;
3use cranelift_codegen::settings::{self, Configurable, Flags, SetError};
4use target_lexicon::Triple;
5use wasmtime_environ::{Setting, SettingKind};
6
7pub struct IsaBuilder<T> {
13 shared_flags: settings::Builder,
15 inner: Builder<T>,
17 pub lookup: fn(Triple) -> Result<Builder<T>>,
19}
20
21impl<T> IsaBuilder<T> {
22 pub fn new(lookup: fn(Triple) -> Result<Builder<T>>) -> Self {
24 let mut flags = settings::builder();
25
26 flags
28 .set("enable_probestack", "false")
29 .expect("should be valid flag");
30
31 let mut isa_flags = lookup(Triple::host()).expect("host machine is not a supported target");
32 cranelift_native::infer_native_flags(&mut isa_flags).unwrap();
33
34 Self {
35 shared_flags: flags,
36 inner: isa_flags,
37 lookup,
38 }
39 }
40
41 pub fn triple(&self) -> &target_lexicon::Triple {
42 self.inner.triple()
43 }
44
45 pub fn target(&mut self, target: target_lexicon::Triple) -> Result<()> {
46 self.inner = (self.lookup)(target)?;
47 Ok(())
48 }
49
50 pub fn settings(&self) -> Vec<Setting> {
51 self.inner
52 .iter()
53 .map(|s| Setting {
54 description: s.description,
55 name: s.name,
56 values: s.values,
57 kind: match s.kind {
58 settings::SettingKind::Preset => SettingKind::Preset,
59 settings::SettingKind::Enum => SettingKind::Enum,
60 settings::SettingKind::Num => SettingKind::Num,
61 settings::SettingKind::Bool => SettingKind::Bool,
62 },
63 })
64 .collect()
65 }
66
67 pub fn set(&mut self, name: &str, value: &str) -> Result<()> {
68 if let Err(err) = self.shared_flags.set(name, value) {
69 match err {
70 SetError::BadName(_) => {
71 self.inner.set(name, value)?;
72 }
73 _ => return Err(err.into()),
74 }
75 }
76 Ok(())
77 }
78
79 pub fn enable(&mut self, name: &str) -> Result<()> {
80 if let Err(err) = self.shared_flags.enable(name) {
81 match err {
82 SetError::BadName(_) => {
83 self.inner.enable(name)?;
85 }
86 _ => return Err(err.into()),
87 }
88 }
89 Ok(())
90 }
91
92 pub fn build(&self) -> T {
93 self.inner
94 .finish(settings::Flags::new(self.shared_flags.clone()))
95 }
96
97 pub fn shared_flags(&self) -> Flags {
98 settings::Flags::new(self.shared_flags.clone())
99 }
100}