wasmtime_cli/commands/
wast.rs1use clap::Parser;
4use std::path::PathBuf;
5use wasmtime::{Engine, Result, error::Context as _};
6use wasmtime_cli_flags::CommonOptions;
7use wasmtime_wast::{SpectestConfig, WastContext};
8
9#[derive(Parser)]
11pub struct WastCommand {
12 #[command(flatten)]
13 common: CommonOptions,
14
15 #[arg(required = true, value_name = "SCRIPT_FILE")]
17 scripts: Vec<PathBuf>,
18
19 #[arg(long, require_equals = true, value_name = "true|false")]
22 generate_dwarf: Option<Option<bool>>,
23
24 #[arg(long)]
27 precompile_save: Option<PathBuf>,
28
29 #[arg(long)]
32 precompile_load: Option<PathBuf>,
33
34 #[arg(long = "async", require_equals = true, value_name = "true|false")]
39 async_: Option<Option<bool>>,
40
41 #[arg(long = "wasmtime-builtins")]
44 wasmtime_builtins: bool,
45
46 #[arg(long)]
49 ignore_error_messages: bool,
50}
51
52impl WastCommand {
53 pub fn execute(mut self) -> Result<()> {
55 self.common.init_logging()?;
56
57 let async_ = optional_flag_with_default(self.async_, true);
58 let mut config = self.common.config(None)?;
59 config.shared_memory(true);
60
61 let generate_dwarf = optional_flag_with_default(self.generate_dwarf, true);
62 if generate_dwarf {
65 config.wasm_backtrace_details(wasmtime::WasmBacktraceDetails::Enable);
66 }
67 let engine = Engine::new(&config)?;
68 let mut wast_context = WastContext::new(
69 &engine,
70 if async_ {
71 wasmtime_wast::Async::Yes
72 } else {
73 wasmtime_wast::Async::No
74 },
75 move |store| {
76 if let Some(fuel) = self.common.wasm.fuel {
77 store.set_fuel(fuel).unwrap();
78 }
79 if let Some(true) = self.common.wasm.epoch_interruption {
80 store.epoch_deadline_trap();
81 store.set_epoch_deadline(1);
82 }
83 },
84 );
85
86 wast_context.generate_dwarf(generate_dwarf);
87 wast_context
88 .register_spectest(&SpectestConfig {
89 use_shared_memory: true,
90 suppress_prints: false,
91 })
92 .expect("error instantiating \"spectest\"");
93 wast_context.ignore_error_messages(self.ignore_error_messages);
94
95 if let Some(path) = &self.precompile_save {
96 wast_context.precompile_save(path);
97 }
98 if let Some(path) = &self.precompile_load {
99 wast_context.precompile_load(path);
100 }
101
102 if self.wasmtime_builtins {
103 wast_context.register_wasmtime()?;
104 }
105
106 for script in self.scripts.iter() {
107 wast_context
108 .run_file(script)
109 .with_context(|| format!("failed to run script file '{}'", script.display()))?;
110 }
111
112 Ok(())
113 }
114}
115
116fn optional_flag_with_default(flag: Option<Option<bool>>, default: bool) -> bool {
117 match flag {
118 None => default,
119 Some(None) => true,
120 Some(Some(val)) => val,
121 }
122}