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
47impl WastCommand {
48 pub fn execute(mut self) -> Result<()> {
50 self.common.init_logging()?;
51
52 let async_ = optional_flag_with_default(self.async_, true);
53 let mut config = self.common.config(None)?;
54 config.shared_memory(true);
55 let engine = Engine::new(&config)?;
56 let mut wast_context = WastContext::new(
57 &engine,
58 if async_ {
59 wasmtime_wast::Async::Yes
60 } else {
61 wasmtime_wast::Async::No
62 },
63 move |store| {
64 if let Some(fuel) = self.common.wasm.fuel {
65 store.set_fuel(fuel).unwrap();
66 }
67 if let Some(true) = self.common.wasm.epoch_interruption {
68 store.epoch_deadline_trap();
69 store.set_epoch_deadline(1);
70 }
71 },
72 );
73
74 wast_context.generate_dwarf(optional_flag_with_default(self.generate_dwarf, true));
75 wast_context
76 .register_spectest(&SpectestConfig {
77 use_shared_memory: true,
78 suppress_prints: false,
79 })
80 .expect("error instantiating \"spectest\"");
81
82 if let Some(path) = &self.precompile_save {
83 wast_context.precompile_save(path);
84 }
85 if let Some(path) = &self.precompile_load {
86 wast_context.precompile_load(path);
87 }
88
89 if self.wasmtime_builtins {
90 wast_context.register_wasmtime()?;
91 }
92
93 for script in self.scripts.iter() {
94 wast_context
95 .run_file(script)
96 .with_context(|| format!("failed to run script file '{}'", script.display()))?;
97 }
98
99 Ok(())
100 }
101}
102
103fn optional_flag_with_default(flag: Option<Option<bool>>, default: bool) -> bool {
104 match flag {
105 None => default,
106 Some(None) => true,
107 Some(Some(val)) => val,
108 }
109}