Files
wasmtime/winch/src/main.rs
Alex Crichton 3b9668558f winch: Prepare for an update to the wasm-tools crates (#5238)
This commit prepares the `winch` crate for updating `wasm-tools`,
notably changing a bit about how the visitation of operators works. This
moves the function body and wasm validator out of the `CodeGen`
structure and into parameters threaded into the emission of the actual
function.

Additionally the `VisitOperator` implementation was updated to remove
the explicit calls to the validator, favoring instead a macro-generated
solution to guarantee that all validation happens before any translation
proceeds. This means that the `VisitOperator for CodeGen` impl is now
infallible and the various methods have been inlined into the trait
methods as well as removing the `Result<_>`.

Finally this commit updates translation to call `validator.finish(..)`
which is required to perform the final validation steps of the function
body.
2022-11-10 14:01:42 -06:00

74 lines
2.2 KiB
Rust

//! Winch CLI tool, meant mostly for testing purposes.
//!
//! Reads Wasm in binary/text format and compiles them
//! to any of the supported architectures using Winch.
use anyhow::{Context, Result};
use clap::Parser;
use std::{fs, path::PathBuf, str::FromStr};
use target_lexicon::Triple;
use wasmtime_environ::{
wasmparser::{types::Types, Parser as WasmParser, Validator},
DefinedFuncIndex, FunctionBodyData, Module, ModuleEnvironment, Tunables,
};
use winch_codegen::isa::{self, TargetIsa};
#[derive(Parser, Debug)]
struct Options {
/// The input file.
input: PathBuf,
/// The target architecture.
#[clap(long = "target")]
target: String,
}
fn main() -> Result<()> {
let opt = Options::from_args();
let bytes = fs::read(&opt.input)
.with_context(|| format!("Failed to read input file {}", opt.input.display()))?;
let bytes = wat::parse_bytes(&bytes)?;
let triple = Triple::from_str(&opt.target)?;
let isa = isa::lookup(triple)?;
let mut validator = Validator::new();
let parser = WasmParser::new(0);
let mut types = Default::default();
let tunables = Tunables::default();
let mut translation = ModuleEnvironment::new(&tunables, &mut validator, &mut types)
.translate(parser, &bytes)
.context("Failed to translate WebAssembly module")?;
let _ = types.finish();
let body_inputs = std::mem::take(&mut translation.function_body_inputs);
let module = &translation.module;
let types = translation.get_types();
body_inputs
.into_iter()
.try_for_each(|func| compile(&*isa, module, types, func))?;
Ok(())
}
fn compile(
isa: &dyn TargetIsa,
module: &Module,
types: &Types,
f: (DefinedFuncIndex, FunctionBodyData<'_>),
) -> Result<()> {
let index = module.func_index(f.0);
let sig = types
.func_type_at(index.as_u32())
.expect(&format!("function type at index {:?}", index.as_u32()));
let FunctionBodyData { body, validator } = f.1;
let validator = validator.into_validator(Default::default());
let buffer = isa
.compile_function(&sig, &body, validator)
.expect("Couldn't compile function");
for i in buffer {
println!("{}", i);
}
Ok(())
}