diff options
| author | Henry Gressmann <mail@henrygressmann.de> | 2023-12-15 13:16:31 +0100 |
|---|---|---|
| committer | Henry Gressmann <mail@henrygressmann.de> | 2023-12-15 13:16:31 +0100 |
| commit | 62e065ea010137315aa873772c8c11e3b2e262f0 (patch) | |
| tree | 19c0584f8b9eda241206dd3283a89cd3b6b889d7 | |
| parent | 4697f7c63c0e985029e7f0683b518b1dadf17ccb (diff) | |
Release 0.0.4
tinywasm@0.0.4
tinywasm-cli@0.0.4
tinywasm-parser@0.0.4
tinywasm-types@0.0.4
wasm-testsuite@0.2.0
Generated by cargo-workspaces
| -rw-r--r-- | Cargo.lock | 35 | ||||
| -rw-r--r-- | Cargo.toml | 1 | ||||
| -rw-r--r-- | crates/cli/Cargo.toml | 4 | ||||
| -rw-r--r-- | crates/parser/Cargo.toml | 4 | ||||
| -rw-r--r-- | crates/tinywasm/Cargo.toml | 8 | ||||
| -rw-r--r-- | crates/tinywasm/tests/mvp.rs | 285 | ||||
| -rw-r--r-- | crates/types/Cargo.toml | 2 | ||||
| -rw-r--r-- | crates/wasm-testsuite/Cargo.toml | 2 |
8 files changed, 46 insertions, 295 deletions
@@ -323,6 +323,12 @@ dependencies = [ ] [[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] name = "leb128" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -557,6 +563,12 @@ dependencies = [ ] [[package]] +name = "ryu" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" + +[[package]] name = "same-file" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -592,6 +604,17 @@ dependencies = [ ] [[package]] +name = "serde_json" +version = "1.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] name = "sha2" version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -662,11 +685,13 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tinywasm" -version = "0.0.3" +version = "0.0.4" dependencies = [ "eyre", "log", "owo-colors", + "serde", + "serde_json", "tinywasm-parser", "tinywasm-types", "wasm-testsuite", @@ -675,7 +700,7 @@ dependencies = [ [[package]] name = "tinywasm-cli" -version = "0.0.3" +version = "0.0.4" dependencies = [ "argh", "color-eyre", @@ -687,7 +712,7 @@ dependencies = [ [[package]] name = "tinywasm-parser" -version = "0.0.3" +version = "0.0.4" dependencies = [ "log", "tinywasm-types", @@ -696,7 +721,7 @@ dependencies = [ [[package]] name = "tinywasm-types" -version = "0.0.3" +version = "0.0.4" dependencies = [ "log", "rkyv", @@ -759,7 +784,7 @@ dependencies = [ [[package]] name = "wasm-testsuite" -version = "0.1.0" +version = "0.2.0" dependencies = [ "rust-embed", ] @@ -4,6 +4,7 @@ default-members=["crates/cli"] resolver="2" [workspace.package] +version="0.0.4" edition="2021" license="MIT OR Apache-2.0" authors=["Henry Gressmann <mail@henrygressmann.de>"] diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 0ac9559..be3c699 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name="tinywasm-cli" -version="0.0.3" +version.workspace=true description="TinyWasm CLI" edition.workspace=true license.workspace=true @@ -14,7 +14,7 @@ path="src/bin.rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -tinywasm={version="0.0.3", path="../tinywasm", features=["std", "parser"]} +tinywasm={version="0.0.4", path="../tinywasm", features=["std", "parser"]} argh="0.1" color-eyre={version="0.6", default-features=false} log="0.4" diff --git a/crates/parser/Cargo.toml b/crates/parser/Cargo.toml index 28c2675..386c142 100644 --- a/crates/parser/Cargo.toml +++ b/crates/parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name="tinywasm-parser" -version="0.0.3" +version.workspace=true description="TinyWasm parser" edition.workspace=true license.workspace=true @@ -12,7 +12,7 @@ repository.workspace=true # TODO: create dependency free parser wasmparser={version="0.100", package="wasmparser-nostd", default-features=false} log={version="0.4", optional=true} -tinywasm-types={version="0.0.3", path="../types"} +tinywasm-types={version="0.0.4", path="../types"} [features] default=["std", "logging"] diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml index 8c9ea50..e4d6ba5 100644 --- a/crates/tinywasm/Cargo.toml +++ b/crates/tinywasm/Cargo.toml @@ -1,6 +1,6 @@ [package] name="tinywasm" -version="0.0.3" +version.workspace=true description="A tiny WebAssembly interpreter" edition.workspace=true license.workspace=true @@ -14,14 +14,16 @@ path="src/lib.rs" [dependencies] log={version="0.4", optional=true} -tinywasm-parser={version="0.0.3", path="../parser", default-features=false, optional=true} -tinywasm-types={version="0.0.3", path="../types", default-features=false} +tinywasm-parser={version="0.0.4", path="../parser", default-features=false, optional=true} +tinywasm-types={version="0.0.4", path="../types", default-features=false} [dev-dependencies] wasm-testsuite={path="../wasm-testsuite"} wast={version="69.0"} owo-colors={version="3.5"} eyre={version="0.6"} +serde_json={version="1.0"} +serde={version="1.0", features=["derive"]} [features] default=["std", "parser", "logging"] diff --git a/crates/tinywasm/tests/mvp.rs b/crates/tinywasm/tests/mvp.rs index 9331c02..66b6b2e 100644 --- a/crates/tinywasm/tests/mvp.rs +++ b/crates/tinywasm/tests/mvp.rs @@ -1,140 +1,15 @@ -use std::{ - collections::BTreeMap, - fmt::{Debug, Formatter}, -}; +mod testsuite; use eyre::{eyre, Result}; -use log::debug; -use tinywasm_types::TinyWasmModule; -use wast::{ - lexer::Lexer, - parser::{self, ParseBuffer}, - QuoteWat, Wast, -}; - -fn parse_module(mut module: wast::core::Module) -> Result<TinyWasmModule> { - let parser = tinywasm_parser::Parser::new(); - Ok(parser.parse_module_bytes(module.encode().expect("failed to encode module"))?) -} +use testsuite::TestSuite; #[test] #[ignore] fn test_mvp() -> Result<()> { let mut test_suite = TestSuite::new(); + test_suite.run(wasm_testsuite::MVP_TESTS)?; - wasm_testsuite::MVP_TESTS.iter().for_each(|group| { - let test_group = test_suite.test_group(group); - - let wast = wasm_testsuite::get_test_wast(group).expect("failed to get test wast"); - let wast = std::str::from_utf8(&wast).expect("failed to convert wast to utf8"); - - let mut lexer = Lexer::new(wast); - // we need to allow confusing unicode characters since they are technically valid wasm - lexer.allow_confusing_unicode(true); - - let buf = ParseBuffer::new_with_lexer(lexer).expect("failed to create parse buffer"); - let wast_data = parser::parse::<Wast>(&buf).expect("failed to parse wat"); - - let mut last_module: Option<TinyWasmModule> = None; - for (i, directive) in wast_data.directives.into_iter().enumerate() { - let span = directive.span(); - use wast::WastDirective::*; - let name = format!("{}-{}", group, i); - - match directive { - // TODO: needs to support more binary sections - Wat(QuoteWat::Wat(wast::Wat::Module(module))) => { - let result = std::panic::catch_unwind(|| parse_module(module)) - .map_err(|e| eyre!("failed to parse module: {:?}", e)) - .and_then(|res| res); - - match &result { - Err(_) => last_module = None, - Ok(m) => last_module = Some(m.clone()), - } - - test_group.add_result(&format!("{}-parse", name), span, result.map(|_| ())); - } - - // these all pass already :) - AssertMalformed { - span, - module: QuoteWat::Wat(wast::Wat::Module(module)), - message: _, - } => { - let res = std::panic::catch_unwind(|| parse_module(module).map(|_| ())); - test_group.add_result( - &format!("{}-malformed", name), - span, - match res { - Ok(Ok(_)) => Err(eyre!("expected module to be malformed")), - Err(_) | Ok(Err(_)) => Ok(()), - }, - ); - } - AssertReturn { span, exec, results } => { - let Some(module) = last_module.as_ref() else { - // println!("no module found for assert_return: {:?}", exec); - continue; - }; - - let res: Result<Result<()>, _> = std::panic::catch_unwind(|| { - let mut store = tinywasm::Store::new(); - let module = tinywasm::Module::from(module); - let instance = module.instantiate(&mut store)?; - - use wast::WastExecute::*; - let invoke = match exec { - Wat(_) => return Result::Ok(()), // not used by the testsuite - Get { module: _, global: _ } => return Result::Ok(()), - Invoke(invoke) => invoke, - }; - - let args = invoke - .args - .into_iter() - .map(wastarg2tinywasmvalue) - .collect::<Result<Vec<_>>>()?; - let res = instance.get_func(&store, invoke.name)?.call(&mut store, &args)?; - let expected = results - .into_iter() - .map(wastret2tinywasmvalue) - .collect::<Result<Vec<_>>>()?; - - if res.len() != expected.len() { - return Result::Err(eyre!("expected {} results, got {}", expected.len(), res.len())); - } - - for (i, (res, expected)) in res.iter().zip(expected).enumerate() { - if res != &expected { - return Result::Err(eyre!("result {} did not match: {:?} != {:?}", i, res, expected)); - } - } - - Ok(()) - }); - - let res = match res { - Err(e) => Err(eyre!("test panicked: {:?}", e)), - Ok(Err(e)) => Err(e), - Ok(Ok(())) => Ok(()), - }; - - test_group.add_result(&format!("{}-return", name), span, res); - } - Invoke(m) => { - debug!("invoke: {:?}", m); - } - // _ => test_group.add_result( - // &format!("{}-unknown", name), - // span, - // Err(Error::Other("test not implemented".to_string())), - // ), - // TODO: implement more test directives - _ => {} - } - } - }); + test_suite.save_csv("./tests/mvp.csv", env!("CARGO_PKG_VERSION").trim_end())?; if test_suite.failed() { eprintln!("\n\nfailed one or more tests:\n{:#?}", test_suite); @@ -144,155 +19,3 @@ fn test_mvp() -> Result<()> { Ok(()) } } - -fn wastarg2tinywasmvalue(arg: wast::WastArg) -> Result<tinywasm_types::WasmValue> { - let wast::WastArg::Core(arg) = arg else { - return Err(eyre!("unsupported arg type")); - }; - - use tinywasm_types::WasmValue; - use wast::core::WastArgCore::*; - Ok(match arg { - F32(f) => WasmValue::F32(f32::from_bits(f.bits)), - F64(f) => WasmValue::F64(f64::from_bits(f.bits)), - I32(i) => WasmValue::I32(i), - I64(i) => WasmValue::I64(i), - _ => return Err(eyre!("unsupported arg type")), - }) -} - -fn wastret2tinywasmvalue(arg: wast::WastRet) -> Result<tinywasm_types::WasmValue> { - let wast::WastRet::Core(arg) = arg else { - return Err(eyre!("unsupported arg type")); - }; - - use tinywasm_types::WasmValue; - use wast::core::WastRetCore::*; - Ok(match arg { - F32(f) => nanpattern2tinywasmvalue(f)?, - F64(f) => nanpattern2tinywasmvalue(f)?, - I32(i) => WasmValue::I32(i), - I64(i) => WasmValue::I64(i), - _ => return Err(eyre!("unsupported arg type")), - }) -} - -enum Bits { - U32(u32), - U64(u64), -} -trait FloatToken { - fn bits(&self) -> Bits; -} -impl FloatToken for wast::token::Float32 { - fn bits(&self) -> Bits { - Bits::U32(self.bits) - } -} -impl FloatToken for wast::token::Float64 { - fn bits(&self) -> Bits { - Bits::U64(self.bits) - } -} - -fn nanpattern2tinywasmvalue<T>(arg: wast::core::NanPattern<T>) -> Result<tinywasm_types::WasmValue> -where - T: FloatToken, -{ - use wast::core::NanPattern::*; - Ok(match arg { - CanonicalNan => tinywasm_types::WasmValue::F32(f32::NAN), - ArithmeticNan => tinywasm_types::WasmValue::F32(f32::NAN), - Value(v) => match v.bits() { - Bits::U32(v) => tinywasm_types::WasmValue::F32(f32::from_bits(v)), - Bits::U64(v) => tinywasm_types::WasmValue::F64(f64::from_bits(v)), - }, - }) -} - -struct TestSuite(BTreeMap<String, TestGroup>); - -impl TestSuite { - fn new() -> Self { - Self(BTreeMap::new()) - } - - fn failed(&self) -> bool { - self.0.values().any(|group| group.stats().1 > 0) - } - - fn test_group(&mut self, name: &str) -> &mut TestGroup { - self.0.entry(name.to_string()).or_insert_with(TestGroup::new) - } -} - -impl Debug for TestSuite { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - use owo_colors::OwoColorize; - let mut total_passed = 0; - let mut total_failed = 0; - - for (group_name, group) in &self.0 { - let (group_passed, group_failed) = group.stats(); - total_passed += group_passed; - total_failed += group_failed; - - writeln!(f, "{}", group_name.bold().underline())?; - writeln!(f, " Tests Passed: {}", group_passed.to_string().green())?; - writeln!(f, " Tests Failed: {}", group_failed.to_string().red())?; - - // for (test_name, test) in &group.tests { - // write!(f, " {}: ", test_name.bold())?; - // match &test.result { - // Ok(()) => { - // writeln!(f, "{}", "Passed".green())?; - // } - // Err(e) => { - // writeln!(f, "{}", "Failed".red())?; - // // writeln!(f, "Error: {:?}", e)?; - // } - // } - // writeln!(f, " Span: {:?}", test.span)?; - // } - } - - writeln!(f, "\n{}", "Total Test Summary:".bold().underline())?; - writeln!(f, " Total Tests: {}", (total_passed + total_failed))?; - writeln!(f, " Total Passed: {}", total_passed.to_string().green())?; - writeln!(f, " Total Failed: {}", total_failed.to_string().red())?; - Ok(()) - } -} - -struct TestGroup { - tests: BTreeMap<String, TestCase>, -} - -impl TestGroup { - fn new() -> Self { - Self { tests: BTreeMap::new() } - } - - fn stats(&self) -> (usize, usize) { - let mut passed_count = 0; - let mut failed_count = 0; - - for test in self.tests.values() { - match test.result { - Ok(()) => passed_count += 1, - Err(_) => failed_count += 1, - } - } - - (passed_count, failed_count) - } - - fn add_result(&mut self, name: &str, span: wast::token::Span, result: Result<()>) { - self.tests.insert(name.to_string(), TestCase { result, _span: span }); - } -} - -struct TestCase { - result: Result<()>, - _span: wast::token::Span, -} diff --git a/crates/types/Cargo.toml b/crates/types/Cargo.toml index 3e4ed15..bc6769a 100644 --- a/crates/types/Cargo.toml +++ b/crates/types/Cargo.toml @@ -1,6 +1,6 @@ [package] name="tinywasm-types" -version="0.0.3" +version.workspace=true description="TinyWasm types" edition.workspace=true license.workspace=true diff --git a/crates/wasm-testsuite/Cargo.toml b/crates/wasm-testsuite/Cargo.toml index 30a4e58..3e6d647 100644 --- a/crates/wasm-testsuite/Cargo.toml +++ b/crates/wasm-testsuite/Cargo.toml @@ -1,6 +1,6 @@ [package] name="wasm-testsuite" -version="0.1.0" +version="0.2.0" description="Mirror of the WebAssembly core testsuite for use in testing WebAssembly implementations" license="Apache-2.0" readme="README.md" |
