From 829db60c869ea5ec9be37e6fc2ad94c2965d63d4 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Mon, 4 Dec 2023 01:53:09 +0100 Subject: [PATCH] feat: add wat support to cli Signed-off-by: Henry Gressmann --- Cargo.lock | 34 ++++++++++++++++++++++++++++++++++ crates/cli/Cargo.toml | 5 +++++ crates/cli/bin.rs | 21 ++++++++++++++++----- crates/cli/wat.rs | 10 ++++++++++ crates/parser/src/lib.rs | 4 ++-- crates/parser/src/module.rs | 4 ++++ crates/tinywasm/src/module.rs | 2 +- examples/wasm/add.wat | 3 --- 8 files changed, 72 insertions(+), 11 deletions(-) create mode 100644 crates/cli/wat.rs diff --git a/Cargo.lock b/Cargo.lock index ba2f313..a6c917f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -200,6 +200,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "leb128" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" + [[package]] name = "libc" version = "0.2.150" @@ -473,6 +479,7 @@ dependencies = [ "log", "pretty_env_logger", "tinywasm", + "wast", ] [[package]] @@ -539,12 +546,27 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + [[package]] name = "valuable" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "wasm-encoder" +version = "0.38.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ad2b51884de9c7f4fe2fd1043fccb8dcad4b1e29558146ee57a144d15779f3f" +dependencies = [ + "leb128", +] + [[package]] name = "wasmparser-nostd" version = "0.100.1" @@ -554,6 +576,18 @@ dependencies = [ "indexmap-nostd", ] +[[package]] +name = "wast" +version = "69.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ee37317321afde358e4d7593745942c48d6d17e0e6e943704de9bbee121e7a" +dependencies = [ + "leb128", + "memchr", + "unicode-width", + "wasm-encoder", +] + [[package]] name = "winapi" version = "0.3.9" diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 783ead2..505b025 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -15,3 +15,8 @@ argh="0.1" color-eyre="0.6" log="0.4" pretty_env_logger="0.5" +wast={version="69.0", optional=true} + +[features] +default=["wast"] +wast=["dep:wast"] diff --git a/crates/cli/bin.rs b/crates/cli/bin.rs index 181b2e1..a067ca8 100644 --- a/crates/cli/bin.rs +++ b/crates/cli/bin.rs @@ -3,8 +3,9 @@ use std::str::FromStr; use argh::FromArgs; use color_eyre::eyre::Result; use log::info; -use tinywasm::{self, WasmValue}; +use tinywasm::{self, Module, WasmValue}; mod util; +mod wat; #[derive(FromArgs)] /// TinyWasm CLI @@ -68,20 +69,30 @@ fn main() -> Result<()> { .filter_level(level) .init(); + let cwd = std::env::current_dir()?; + match args.nested { TinyWasmSubcommand::Run(Run { wasm_file, engine }) => { - let wasm = std::fs::read(wasm_file)?; + let path = cwd.join(wasm_file.clone()); + let module = match wasm_file.ends_with(".wat") { + true => { + let wat = std::fs::read_to_string(path)?; + let wasm = wat::wat2wasm(&wat); + tinywasm::Module::parse_bytes(&wasm)? + } + false => tinywasm::Module::parse_file(path)?, + }; + match engine { - Engine::Main => run(&wasm), + Engine::Main => run(module), } } } } -fn run(wasm: &[u8]) -> Result<()> { +fn run(module: Module) -> Result<()> { let mut store = tinywasm::Store::default(); - let module = tinywasm::Module::parse_bytes(wasm)?; let instance = module.instantiate(&mut store)?; let func = instance.get_func(&store, "add")?; let params = vec![WasmValue::I32(2), WasmValue::I32(2)]; diff --git a/crates/cli/wat.rs b/crates/cli/wat.rs new file mode 100644 index 0000000..22d931d --- /dev/null +++ b/crates/cli/wat.rs @@ -0,0 +1,10 @@ +use wast::{ + parser::{self, ParseBuffer}, + Wat, +}; + +pub fn wat2wasm<'a>(wat: &str) -> Vec { + let buf = ParseBuffer::new(wat).expect("failed to create parse buffer"); + let mut module = parser::parse::(&buf).expect("failed to parse wat"); + module.encode().expect("failed to encode wat") +} diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index 3cc51d6..b1729f4 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs @@ -40,10 +40,10 @@ impl Parser { #[cfg(feature = "std")] pub fn parse_module_file( &self, - path: impl AsRef, + path: impl AsRef + Clone, ) -> Result { use alloc::format; - let f = crate::std::fs::File::open("log.txt").map_err(|e| { + let f = crate::std::fs::File::open(path.clone()).map_err(|e| { ParseError::Other(format!("Error opening file {:?}: {}", path.as_ref(), e)) })?; diff --git a/crates/parser/src/module.rs b/crates/parser/src/module.rs index 268bad7..2beba9e 100644 --- a/crates/parser/src/module.rs +++ b/crates/parser/src/module.rs @@ -162,6 +162,10 @@ impl ModuleReader { validator.end(offset)?; self.end_reached = true; } + CustomSection(reader) => { + debug!("Found custom section"); + debug!("Skipping custom section: {:?}", reader.name()); + } UnknownSection { .. } => { return Err(ParseError::UnsupportedSection("Unknown section".into())) } diff --git a/crates/tinywasm/src/module.rs b/crates/tinywasm/src/module.rs index 05bd643..8e258fd 100644 --- a/crates/tinywasm/src/module.rs +++ b/crates/tinywasm/src/module.rs @@ -21,7 +21,7 @@ impl Module { } #[cfg(feature = "std")] - pub fn parse_file(path: impl AsRef) -> Result { + pub fn parse_file(path: impl AsRef + Clone) -> Result { let parser = tinywasm_parser::Parser::new(); let data = parser.parse_module_file(path)?; Ok(data.into()) diff --git a/examples/wasm/add.wat b/examples/wasm/add.wat index a246245..b5e1f3a 100644 --- a/examples/wasm/add.wat +++ b/examples/wasm/add.wat @@ -1,4 +1,3 @@ -;; name: add ; description: add two numbers (module (func $add (export "add") (param $a i32) (param $b i32) (result i32) local.get $a @@ -10,5 +9,3 @@ local.get $b i64.add) ) - -