use std::str::FromStr;
use argh::FromArgs;
use color_eyre::eyre::Result;
use log::info;
use tinywasm::{self, Module};
mod util;
#[cfg(feature = "wat")]
mod wat;
#[derive(FromArgs)]
/// TinyWasm CLI
struct TinyWasmCli {
#[argh(subcommand)]
nested: TinyWasmSubcommand,
/// log level
#[argh(option, short = 'l', default = "\"info\".to_string()")]
log_level: String,
}
#[derive(FromArgs)]
#[argh(subcommand)]
enum TinyWasmSubcommand {
Run(Run),
}
enum Engine {
Main,
}
impl FromStr for Engine {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"main" => Ok(Self::Main),
_ => Err(format!("unknown engine: {}", s)),
}
}
}
#[derive(FromArgs)]
/// run a wasm file
#[argh(subcommand, name = "run")]
struct Run {
/// wasm file to run
#[argh(positional)]
wasm_file: String,
/// engine to use
#[argh(option, short = 'e', default = "Engine::Main")]
engine: Engine,
}
fn main() -> Result<()> {
color_eyre::install()?;
let args: TinyWasmCli = argh::from_env();
let level = match args.log_level.as_str() {
"trace" => log::LevelFilter::Trace,
"debug" => log::LevelFilter::Debug,
"warn" => log::LevelFilter::Warn,
"error" => log::LevelFilter::Error,
"info" => log::LevelFilter::Info,
_ => log::LevelFilter::Info,
};
pretty_env_logger::formatted_builder()
.filter_level(level)
.init();
let cwd = std::env::current_dir()?;
match args.nested {
TinyWasmSubcommand::Run(Run { wasm_file, engine }) => {
let path = cwd.join(wasm_file.clone());
let module = match wasm_file.ends_with(".wat") {
#[cfg(feature = "wat")]
true => {
let wat = std::fs::read_to_string(path)?;
let wasm = wat::wat2wasm(&wat);
tinywasm::Module::parse_bytes(&wasm)?
}
#[cfg(not(feature = "wat"))]
true => {
return Err(color_eyre::eyre::eyre!(
"wat support is not enabled in this build"
))
}
false => tinywasm::Module::parse_file(path)?,
};
match engine {
Engine::Main => run(module),
}
}
}
}
fn run(module: Module) -> Result<()> {
let mut store = tinywasm::Store::default();
let instance = module.instantiate(&mut store)?;
let func = instance.get_typed_func::<(i32, i32), (i32,)>(&store, "add")?;
let (res,) = func.call(&mut store, (2, 2))?;
info!("{res:?}");
Ok(())
}
|