wasmtime_internal_cranelift/
builder.rs1use crate::isa_builder::IsaBuilder;
7use anyhow::Result;
8use cranelift_codegen::{
9 CodegenResult,
10 isa::{self, OwnedTargetIsa},
11};
12use std::fmt;
13use std::path;
14use std::sync::Arc;
15use target_lexicon::Triple;
16use wasmtime_environ::{CacheStore, CompilerBuilder, Setting, Tunables};
17
18struct Builder {
19 tunables: Option<Tunables>,
20 inner: IsaBuilder<CodegenResult<OwnedTargetIsa>>,
21 emit_debug_checks: bool,
22 linkopts: LinkOptions,
23 cache_store: Option<Arc<dyn CacheStore>>,
24 clif_dir: Option<path::PathBuf>,
25 wmemcheck: bool,
26}
27
28#[derive(Clone, Default)]
29pub struct LinkOptions {
30 pub padding_between_functions: usize,
34
35 pub force_jump_veneers: bool,
39}
40
41pub fn builder(triple: Option<Triple>) -> Result<Box<dyn CompilerBuilder>> {
42 Ok(Box::new(Builder {
43 tunables: None,
44 inner: IsaBuilder::new(triple, |triple| isa::lookup(triple).map_err(|e| e.into()))?,
45 linkopts: LinkOptions::default(),
46 cache_store: None,
47 clif_dir: None,
48 wmemcheck: false,
49 emit_debug_checks: false,
50 }))
51}
52
53impl CompilerBuilder for Builder {
54 fn triple(&self) -> &target_lexicon::Triple {
55 self.inner.triple()
56 }
57
58 fn clif_dir(&mut self, path: &path::Path) -> Result<()> {
59 self.clif_dir = Some(path.to_path_buf());
60 Ok(())
61 }
62
63 fn target(&mut self, target: target_lexicon::Triple) -> Result<()> {
64 self.inner.target(target)?;
65 Ok(())
66 }
67
68 fn set(&mut self, name: &str, value: &str) -> Result<()> {
69 match name {
71 "wasmtime_linkopt_padding_between_functions" => {
72 self.linkopts.padding_between_functions = value.parse()?;
73 }
74 "wasmtime_linkopt_force_jump_veneer" => {
75 self.linkopts.force_jump_veneers = value.parse()?;
76 }
77 "wasmtime_inlining_intra_module" => {
78 self.tunables.as_mut().unwrap().inlining_intra_module = value.parse()?;
79 }
80 "wasmtime_inlining_small_callee_size" => {
81 self.tunables.as_mut().unwrap().inlining_small_callee_size = value.parse()?;
82 }
83 "wasmtime_inlining_sum_size_threshold" => {
84 self.tunables.as_mut().unwrap().inlining_sum_size_threshold = value.parse()?;
85 }
86 "wasmtime_debug_checks" => {
87 self.emit_debug_checks = true;
88 }
89 _ => {
90 self.inner.set(name, value)?;
91 }
92 }
93 Ok(())
94 }
95
96 fn enable(&mut self, name: &str) -> Result<()> {
97 self.inner.enable(name)
98 }
99
100 fn set_tunables(&mut self, tunables: Tunables) -> Result<()> {
101 self.tunables = Some(tunables);
102 Ok(())
103 }
104
105 fn build(&self) -> Result<Box<dyn wasmtime_environ::Compiler>> {
106 let isa = self.inner.build()?;
107 Ok(Box::new(crate::compiler::Compiler::new(
108 self.tunables
109 .as_ref()
110 .expect("set_tunables not called")
111 .clone(),
112 isa,
113 self.cache_store.clone(),
114 self.emit_debug_checks,
115 self.linkopts.clone(),
116 self.clif_dir.clone(),
117 self.wmemcheck,
118 )))
119 }
120
121 fn settings(&self) -> Vec<Setting> {
122 self.inner.settings()
123 }
124
125 fn enable_incremental_compilation(
126 &mut self,
127 cache_store: Arc<dyn wasmtime_environ::CacheStore>,
128 ) -> Result<()> {
129 self.cache_store = Some(cache_store);
130 Ok(())
131 }
132
133 fn wmemcheck(&mut self, enable: bool) {
134 self.wmemcheck = enable;
135 }
136}
137
138impl fmt::Debug for Builder {
139 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
140 f.debug_struct("Builder")
141 .field("shared_flags", &self.inner.shared_flags().to_string())
142 .finish()
143 }
144}