From 52bebfac2e6a2dc934273e38230d3986e68a3fe3 Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Sun, 10 Dec 2023 13:35:13 +0100 Subject: feat: move wasm core testsuite to a seperate crate Signed-off-by: Henry Gressmann --- crates/wasm-testsuite/Cargo.toml | 17 ++++++ crates/wasm-testsuite/data | 1 + crates/wasm-testsuite/lib.rs | 112 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+) create mode 100644 crates/wasm-testsuite/Cargo.toml create mode 160000 crates/wasm-testsuite/data create mode 100644 crates/wasm-testsuite/lib.rs (limited to 'crates/wasm-testsuite') diff --git a/crates/wasm-testsuite/Cargo.toml b/crates/wasm-testsuite/Cargo.toml new file mode 100644 index 0000000..1145b3c --- /dev/null +++ b/crates/wasm-testsuite/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name="wasm-testsuite" +version="0.0.1" +description="Mirror of the WebAssembly core testsuite for use in testing WebAssembly implementations" +edition.workspace=true +license.workspace=true +authors.workspace=true +repository.workspace=true + +[lib] +path="lib.rs" + +[package.metadata.workspaces] +independent=true + +[dependencies] +rust-embed={version="8.1.0", features=["include-exclude"]} diff --git a/crates/wasm-testsuite/data b/crates/wasm-testsuite/data new file mode 160000 index 0000000..dc27dad --- /dev/null +++ b/crates/wasm-testsuite/data @@ -0,0 +1 @@ +Subproject commit dc27dad3e34e466bdbfea32fe3c73f5e31f88560 diff --git a/crates/wasm-testsuite/lib.rs b/crates/wasm-testsuite/lib.rs new file mode 100644 index 0000000..102389a --- /dev/null +++ b/crates/wasm-testsuite/lib.rs @@ -0,0 +1,112 @@ +//! This crate provides a way to access the WebAssembly spec testsuite. +//! +//! The testsuite is included as a git submodule and embedded into the binary. +//! +//! Generated from https://github.com/WebAssembly/testsuite + +#![forbid(unsafe_code)] +#![doc(test( + no_crate_inject, + attr( + deny(warnings, rust_2018_idioms), + allow(dead_code, unused_assignments, unused_variables) + ) +))] +#![warn(missing_docs, missing_debug_implementations, rust_2018_idioms, unreachable_pub)] + +use rust_embed::RustEmbed; +use std::borrow::Cow; + +#[derive(RustEmbed)] +#[folder = "data/"] +#[include = "*.wast"] +struct Asset; + +/// List of all proposals. +/// This list is generated from the `proposals` folder in https://github.com/WebAssembly/testsuite +#[rustfmt::skip] +pub const PROPOSALS: &[&str] = &["annotations", "exception-handling", "memory64", "function-references", "multi-memory", "relaxed-simd", "tail-call", "threads", "extended-const", "gc"]; + +/// Get all test file names and their contents. +/// +/// Proposals can be filtered by passing a list of proposal names. +/// Valid proposal names are listed in [`PROPOSALS`]. +/// Returns an iterator over tuples of the form `(test_name, test_data)`. +/// test_name is the name of the test file and the proposal name (if any), e.g. `annotations/br.wast`. +pub fn get_tests(include_proposals: &[String]) -> impl Iterator)> { + let include_proposals = include_proposals.to_vec(); + + Asset::iter().filter_map(move |x| { + let mut parts = x.split('/'); + match parts.next() { + Some("proposals") => { + let proposal = parts.next(); + let test_name = parts.next().unwrap_or_default(); + + if proposal.map_or(false, |p| include_proposals.contains(&p.to_string())) { + let full_path = format!("{}/{}", proposal.unwrap_or_default(), test_name); + let data = Asset::get(&x).unwrap().data; + Some((full_path, data)) + } else { + None + } + } + Some(test_name) => { + let data = Asset::get(&x).unwrap().data; + Some((test_name.to_owned(), data)) + } + None => None, + } + }) +} + +/// Get the WAST file as a byte slice. +/// +/// # Examples +/// proposals: {proposal}/{test_name}.wast +/// tests: {test_name}.wast +pub fn get_wast(name: &str) -> Option> { + if !name.ends_with(".wast") { + panic!("Expected .wast file. Got: {}", name); + } + + match name.contains('/') { + true => Asset::get(&format!("proposals/{}", name)).map(|x| x.data), + false => Asset::get(name).map(|x| x.data), + } +} + +#[cfg(test)] +mod tests { + use std::collections::HashSet; + + use super::*; + + #[test] + fn test_proposals() { + let mut unique_proposals = HashSet::new(); + + // check that all proposals are present + for proposal in Asset::iter() { + if !proposal.starts_with("proposals/") { + continue; + } + + let proposal = proposal.split('/').nth(1).unwrap(); + unique_proposals.insert(proposal.to_owned()); + // assert!(PROPOSALS.contains(&proposal)); + } + println!("{:?}", unique_proposals); + } + + #[test] + fn test_get_tests() { + let tests = get_tests(&["annotations".to_owned()]); + let tests: Vec<_> = tests.collect(); + println!("{:?}", tests.iter().map(|(name, _)| name).collect::>()); + + // for (name, data) in tests { + // println!("{}: {}", name, data.len()); + // } + } +} -- cgit v1.3.1