wasmtime_cli/commands/
explore.rs

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