wasmtime_cli/commands/
wast.rs1use anyhow::{Context as _, Result};
4use clap::Parser;
5use std::path::PathBuf;
6use wasmtime::Engine;
7use wasmtime_cli_flags::CommonOptions;
8use wasmtime_wast::{SpectestConfig, WastContext};
9
10#[derive(Parser)]
12pub struct WastCommand {
13 #[command(flatten)]
14 common: CommonOptions,
15
16 #[arg(required = true, value_name = "SCRIPT_FILE")]
18 scripts: Vec<PathBuf>,
19
20 #[arg(long, require_equals = true, value_name = "true|false")]
23 generate_dwarf: Option<Option<bool>>,
24
25 #[arg(long)]
28 precompile_save: Option<PathBuf>,
29
30 #[arg(long)]
33 precompile_load: Option<PathBuf>,
34
35 #[arg(long = "async", require_equals = true, value_name = "true|false")]
40 async_: Option<Option<bool>>,
41}
42
43impl WastCommand {
44 pub fn execute(mut self) -> Result<()> {
46 self.common.init_logging()?;
47
48 let async_ = optional_flag_with_default(self.async_, true);
49 let mut config = self.common.config(None)?;
50 config.async_support(async_);
51 config.shared_memory(true);
52 let engine = Engine::new(&config)?;
53 let mut wast_context = WastContext::new(
54 &engine,
55 if async_ {
56 wasmtime_wast::Async::Yes
57 } else {
58 wasmtime_wast::Async::No
59 },
60 move |store| {
61 if let Some(fuel) = self.common.wasm.fuel {
62 store.set_fuel(fuel).unwrap();
63 }
64 if let Some(true) = self.common.wasm.epoch_interruption {
65 store.epoch_deadline_trap();
66 store.set_epoch_deadline(1);
67 }
68 },
69 );
70
71 wast_context.generate_dwarf(optional_flag_with_default(self.generate_dwarf, true));
72 wast_context
73 .register_spectest(&SpectestConfig {
74 use_shared_memory: true,
75 suppress_prints: false,
76 })
77 .expect("error instantiating \"spectest\"");
78
79 if let Some(path) = &self.precompile_save {
80 wast_context.precompile_save(path);
81 }
82 if let Some(path) = &self.precompile_load {
83 wast_context.precompile_load(path);
84 }
85
86 for script in self.scripts.iter() {
87 wast_context
88 .run_file(script)
89 .with_context(|| format!("failed to run script file '{}'", script.display()))?;
90 }
91
92 Ok(())
93 }
94}
95
96fn optional_flag_with_default(flag: Option<Option<bool>>, default: bool) -> bool {
97 match flag {
98 None => default,
99 Some(None) => true,
100 Some(Some(val)) => val,
101 }
102}