Path: blob/main/crates/environ/examples/factc.rs
1691 views
use anyhow::{Context, Result, bail};1use clap::Parser;2use std::io::{IsTerminal, Write};3use std::path::{Path, PathBuf};4use wasmparser::{Validator, WasmFeatures};5use wasmtime_environ::{ScopeVec, Tunables, component::*};67/// A small helper utility to explore generated adapter modules from Wasmtime's8/// adapter fusion compiler.9///10/// This utility takes a `*.wat` file as input which is expected to be a valid11/// WebAssembly component. The component is parsed and any type definition for a12/// component function gets a generated adapter for it as if the caller/callee13/// used that type as the adapter.14///15/// For example with an input that looks like:16///17/// (component18/// (type (func (param u32) (result (list u8))))19/// )20///21/// This tool can be used to generate an adapter for that signature.22#[derive(Parser)]23struct Factc {24/// Whether or not debug code is inserted into the generated adapter.25#[arg(long)]26debug: bool,2728/// Whether or not to skip validation of the generated adapter module.29#[arg(long)]30skip_validate: bool,3132/// Where to place the generated adapter module. Standard output is used if33/// this is not specified.34#[arg(short, long)]35output: Option<PathBuf>,3637/// Output the text format for WebAssembly instead of the binary format.38#[arg(short, long)]39text: bool,4041/// The input component to generate adapters for.42input: PathBuf,43}4445fn main() -> Result<()> {46Factc::parse().execute()47}4849impl Factc {50fn execute(self) -> Result<()> {51env_logger::init();5253let input = wat::parse_file(&self.input)?;5455let tunables = Tunables::default_host();56let mut validator =57wasmparser::Validator::new_with_features(wasmparser::WasmFeatures::all());58let mut component_types = ComponentTypesBuilder::new(&validator);59let adapters = ScopeVec::new();6061Translator::new(&tunables, &mut validator, &mut component_types, &adapters)62.translate(&input)?;6364let (out_name, mut out_file): (_, Box<dyn std::io::Write>) = match &self.output {65Some(file) => (66file.as_path(),67Box::new(std::io::BufWriter::new(68std::fs::File::create(file)69.with_context(|| format!("failed to create {}", file.display()))?,70)),71),72None => (Path::new("stdout"), Box::new(std::io::stdout())),73};7475for wasm in adapters.into_iter() {76let output = if self.text {77wasmprinter::print_bytes(&wasm)78.context("failed to convert binary wasm to text")?79.into_bytes()80} else if self.output.is_none() && std::io::stdout().is_terminal() {81bail!("cannot print binary wasm output to a terminal unless `-t` flag is passed")82} else {83wasm.to_vec()84};8586out_file87.write_all(&output)88.with_context(|| format!("failed to write to {}", out_name.display()))?;8990if !self.skip_validate {91Validator::new_with_features(WasmFeatures::default() | WasmFeatures::MEMORY64)92.validate_all(&wasm)93.context("failed to validate generated module")?;94}95}9697Ok(())98}99}100101102