1 //! The module that implements the `wasmtime explore` command. 2 3 use anyhow::{Context, Result}; 4 use clap::Parser; 5 use std::{borrow::Cow, path::PathBuf}; 6 use tempfile::tempdir; 7 use wasmtime::Strategy; 8 use wasmtime_cli_flags::CommonOptions; 9 10 /// Explore the compilation of a WebAssembly module to native code. 11 #[derive(Parser)] 12 pub struct ExploreCommand { 13 #[command(flatten)] 14 common: CommonOptions, 15 16 /// The path of the WebAssembly module to compile 17 #[arg(required = true, value_name = "MODULE")] 18 module: PathBuf, 19 20 /// The path of the explorer output (derived from the MODULE name if none 21 /// provided) 22 #[arg(short, long)] 23 output: Option<PathBuf>, 24 } 25 26 impl ExploreCommand { 27 /// Executes the command. 28 pub fn execute(mut self) -> Result<()> { 29 self.common.init_logging()?; 30 31 let mut config = self.common.config(None)?; 32 33 let bytes = 34 Cow::Owned(std::fs::read(&self.module).with_context(|| { 35 format!("failed to read Wasm module: {}", self.module.display()) 36 })?); 37 #[cfg(feature = "wat")] 38 let bytes = wat::parse_bytes(&bytes).map_err(|mut e| { 39 e.set_path(&self.module); 40 e 41 })?; 42 43 let output = self 44 .output 45 .clone() 46 .unwrap_or_else(|| self.module.with_extension("explore.html")); 47 let output_file = std::fs::File::create(&output) 48 .with_context(|| format!("failed to create file: {}", output.display()))?; 49 let mut output_file = std::io::BufWriter::new(output_file); 50 51 let clif_dir = if let Some(Strategy::Cranelift) | None = self.common.codegen.compiler { 52 let clif_dir = tempdir()?; 53 config.emit_clif(clif_dir.path()); 54 config.disable_cache(); // cache does not emit clif 55 Some(clif_dir) 56 } else { 57 None 58 }; 59 60 wasmtime_explorer::generate( 61 &config, 62 self.common.target.as_deref(), 63 clif_dir.as_ref().map(|tmp_dir| tmp_dir.path()), 64 &bytes, 65 &mut output_file, 66 )?; 67 68 println!("Exploration written to {}", output.display()); 69 Ok(()) 70 } 71 } 72