1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
use anyhow::{anyhow, Result};
use clap::Parser;
use std::collections::BTreeMap;
use std::str::FromStr;
use wasmtime_environ::{FlagValue, Setting, SettingKind};
#[derive(Parser)]
#[clap(name = "run")]
pub struct SettingsCommand {
#[clap(long, value_name = "TARGET")]
target: Option<String>,
}
impl SettingsCommand {
pub fn execute(self) -> Result<()> {
let mut builder = wasmtime_cranelift::builder();
if let Some(target) = &self.target {
let target = target_lexicon::Triple::from_str(target).map_err(|e| anyhow!(e))?;
builder.target(target)?;
}
let mut enums = (Vec::new(), 0, "Enum settings:");
let mut nums = (Vec::new(), 0, "Numerical settings:");
let mut bools = (Vec::new(), 0, "Boolean settings:");
let mut presets = (Vec::new(), 0, "Presets:");
for setting in builder.settings() {
let (collection, max, _) = match setting.kind {
SettingKind::Enum => &mut enums,
SettingKind::Num => &mut nums,
SettingKind::Bool => &mut bools,
SettingKind::Preset => &mut presets,
};
if setting.name.len() > *max {
*max = setting.name.len();
}
collection.push(setting);
}
if enums.0.is_empty() && nums.0.is_empty() && bools.0.is_empty() && presets.0.is_empty() {
println!("Target '{}' has no settings.", builder.triple());
return Ok(());
}
println!("Cranelift settings for target '{}':", builder.triple());
for (collection, max, header) in &mut [enums, nums, bools, presets] {
if collection.is_empty() {
continue;
}
collection.sort_by_key(|k| k.name);
println!();
Self::print_settings(header, collection, *max);
}
if self.target.is_none() {
let compiler = builder.build()?;
println!();
println!("Settings inferred for the current host:");
let values = compiler.isa_flags().into_iter().collect::<BTreeMap<_, _>>();
for (name, value) in values {
if let FlagValue::Bool(true) = value {
println!(" {}", name);
}
}
}
Ok(())
}
fn print_settings(header: &str, settings: &[Setting], width: usize) {
println!("{}", header);
for setting in settings {
println!(
" {:width$} {}{}",
setting.name,
setting.description,
setting
.values
.map(|v| format!(" Supported values: {}.", v.join(", ")))
.unwrap_or("".to_string()),
width = width + 2
);
}
}
}