xref: /wasmtime-44.0.1/src/commands/explore.rs (revision cccc4e64)
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