diff options
Diffstat (limited to 'crates/cli/src/bin.rs')
| -rw-r--r-- | crates/cli/src/bin.rs | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/crates/cli/src/bin.rs b/crates/cli/src/bin.rs new file mode 100644 index 0000000..3615e4a --- /dev/null +++ b/crates/cli/src/bin.rs @@ -0,0 +1,112 @@ +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(()) +} |
