diff --git a/.gitmodules b/.gitmodules index ed714f0..862ee69 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "tests/testsuite"] - path = tests/testsuite + path = testsuite + url = git@github.com:WebAssembly/testsuite.git +[submodule "testsuite"] + path = testsuite url = git@github.com:WebAssembly/testsuite.git diff --git a/Cargo.lock b/Cargo.lock index 4385552..df5daf5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -536,6 +536,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "wasker" version = "0.1.0" @@ -546,6 +552,7 @@ dependencies = [ "inkwell", "log", "pretty-hex", + "wasi", "wasmparser", "wast 70.0.2", "wat", diff --git a/Cargo.toml b/Cargo.toml index 132d96c..d394c1f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,3 +17,4 @@ log = "0.4.20" env_logger = "0.10.0" pretty-hex = "0.3.0" wast = "70.0.2" +wasi = "0.11.0+wasi-snapshot-preview1" diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..465467f --- /dev/null +++ b/build.rs @@ -0,0 +1,3 @@ +fn main() { + println!("cargo:rustc-link-search=native=target/spectest"); +} diff --git a/examples/wasi-wrapper/rust/Cargo.toml b/examples/wasi-wrapper/rust/Cargo.toml index c8ffe31..bd147a1 100644 --- a/examples/wasi-wrapper/rust/Cargo.toml +++ b/examples/wasi-wrapper/rust/Cargo.toml @@ -4,5 +4,4 @@ version = "0.1.0" edition = "2021" build = "build.rs" -[dependencies] -wasi = "0.11.0+wasi-snapshot-preview1" +[dependencies] \ No newline at end of file diff --git a/examples/wasi-wrapper/rust/src/main.rs b/examples/wasi-wrapper/rust/src/main.rs index 8b4ecfb..be5588a 100644 --- a/examples/wasi-wrapper/rust/src/main.rs +++ b/examples/wasi-wrapper/rust/src/main.rs @@ -1,6 +1,3 @@ -mod memory; -mod wasi; - extern "C" { fn wasker_main(); } diff --git a/examples/wasi-wrapper/rust/src/memory.rs b/examples/wasi-wrapper/rust/src/memory.rs deleted file mode 100644 index 7783917..0000000 --- a/examples/wasi-wrapper/rust/src/memory.rs +++ /dev/null @@ -1,46 +0,0 @@ -//! Linear Memory -use std::sync::Mutex; - -const LINEAR_MEMORY_BLOCK_SIZE: i32 = 64 * 1024; -const LINEAR_MEMORY_BLOCK_NUM_MAX: i32 = 32; - -static mut LINEAR_MEMORY_BASE: *mut u8 = 0 as _; -static LINEAR_MEMORY_BLOCK_NUM: Mutex = Mutex::new(0); - -#[inline] -pub unsafe fn get_memory_base() -> *mut u8 { - LINEAR_MEMORY_BASE -} - -unsafe fn alloc_memory() -> *mut u8 { - use std::alloc::{alloc, Layout}; - LINEAR_MEMORY_BASE = alloc( - Layout::from_size_align( - (LINEAR_MEMORY_BLOCK_SIZE * LINEAR_MEMORY_BLOCK_NUM_MAX) as usize, - 8, - ) - .unwrap(), - ); - LINEAR_MEMORY_BASE -} - -#[no_mangle] -pub extern "C" fn memory_base() -> usize { - unsafe { alloc_memory() as usize } -} - -#[no_mangle] -pub extern "C" fn memory_grow(block_num: i32) -> i32 { - assert!( - block_num >= 0, - "block_num must be greater than or equal to 0" - ); - let mut num = LINEAR_MEMORY_BLOCK_NUM.lock().unwrap(); - let old_val = *num; - if num.checked_add(block_num).unwrap() > LINEAR_MEMORY_BLOCK_NUM_MAX { - println!("memory_grow: failed to grow memory"); - return -1; - } - *num += block_num; - old_val -} diff --git a/src/compiler.rs b/src/compiler.rs index a5c7f64..2e7404b 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -3,18 +3,32 @@ use crate::environment::Environment; use crate::inkwell::init_inkwell; use crate::section::translate_module; -use anyhow::{anyhow, Context, Result}; +use anyhow::{anyhow, Context, Ok, Result}; use clap::Parser; use inkwell::{context, module::Module, passes::PassManager, targets}; -use std::path; +use std::fmt::format; +use std::io::{Read, Write}; +use std::path::PathBuf; +use wast::{ + core::WastArgCore, core::WastRetCore, lexer::Lexer, parser::ParseBuffer, Wast, WastDirective, +}; use wat; +/// Ahead-of-Time Wasm to ELF compiler. #[derive(Parser, Debug)] pub struct Args { - pub input_file: path::PathBuf, + /// Path to the input Wasm or WAT file. + #[arg(short, long, default_value = "./hello.wat")] + pub input_file: PathBuf, + /// Path to the output ELF file. #[arg(short, long, default_value = "./wasm.o")] - pub output_file: path::PathBuf, + pub output_file: PathBuf, + + /// SpecTest mode + /// If this flag is set, the compiler will output ELF file from spectest's *.wast file. + #[arg(short, long, default_value = "false")] + pub spectest: bool, } /// Receive a path to a Wasm binary or WAT and compile it into ELF binary. @@ -31,6 +45,183 @@ pub fn compile_wasm_from_file(args: &Args) -> Result<()> { compile_wasm(&wasm, args) } +fn compile_spec_test(testname: &str, idx: usize) { + let project_root = std::env::var("CARGO_MANIFEST_DIR").expect("error get env"); + + // Read Wast + let mut wat = String::new(); + let wat_path = std::path::Path::new(&project_root).join(format!("testsuite/{}.wast", testname)); + log::info!("open file: {:?}", wat_path); + let mut file = std::fs::File::open(wat_path).expect("error open file"); + file.read_to_string(&mut wat).expect("cannot read file"); + + // Parse Wast + let mut lexer = Lexer::new(&wat); + lexer.allow_confusing_unicode(true); + let parse_buffer = match ParseBuffer::new_with_lexer(lexer) { + core::result::Result::Ok(buffer) => buffer, + Err(error) => { + panic!("failed to create ParseBuffer : {}", error) + } + }; + let wast = match wast::parser::parse::(&parse_buffer) { + core::result::Result::Ok(wast) => wast, + Err(error) => { + panic!( + "failed to parse `.wast` spec test file {} for: {}", + testname, error + ) + } + }; + + // Compile Wast + let target_dir = std::path::Path::new(&project_root).join(format!("target/spectest")); + if !target_dir.exists() { + std::fs::create_dir_all(&target_dir).expect("error create target dir"); + } + + let mut buff_externc = if idx == 0 { + String::from("#[link(name = \"spectest\")]\nextern \"C\" {\n") + } else { + String::new() + }; + let mut buff_test = String::from(format!("#[test]\nfn test_{}()", testname)); + buff_test.push_str("{\n"); + + for directive in wast.directives { + match directive { + WastDirective::Wat(mut wat) => { + // Get Wasm binary + let wasm = wat.encode().expect("failed to encode wat"); + assert_eq!(wasm[0..4], [0, 97, 115, 109]); + + // Compile with Wasker + let args = Args { + input_file: "dummy.wasm".into(), + output_file: format!("{}/{}.o", target_dir.display(), testname).into(), + spectest: false, + }; + compile_wasm(&wasm, &args).expect("failed to Wasker compile"); + } + WastDirective::AssertReturn { + span: _, + exec, + results, + } => match exec { + wast::WastExecute::Invoke(wast::WastInvoke { + span: _, + module: _, + name, + args, + }) => { + let mut test_strings = String::from("\tassert_eq!("); + if results.len() > 1 { + log::error!("TODO: results.len() > 1"); + assert!(false); + } + match &results[0] { + wast::WastRet::Core(ret) => match ret { + WastRetCore::I32(i) => { + test_strings.push_str(&format!("{},", i)); + } + WastRetCore::I64(i) => { + test_strings.push_str(&format!("{},", i)); + } + WastRetCore::F32(f) => { + test_strings.push_str(&format!("{:?},", f)); + } + WastRetCore::F64(f) => { + test_strings.push_str(&format!("{:?},", f)); + } + _ => {} + }, + _ => { + log::error!("TODO: results[0] is not Core"); + assert!(false); + } + } + test_strings.push_str(format!("{}(", name).as_str()); + for arg in args { + match arg { + wast::WastArg::Core(argcore) => match argcore { + WastArgCore::I32(i) => { + test_strings.push_str(&format!("{},", i)); + } + WastArgCore::I64(i) => { + test_strings.push_str(&format!("{},", i)); + } + WastArgCore::F32(f) => { + test_strings.push_str(&format!("{:?},", f)); + } + WastArgCore::F64(f) => { + test_strings.push_str(&format!("{:?},", f)); + } + _ => {} + }, + _ => {} + } + } + // remove last comma + test_strings.pop(); + test_strings.push_str("));\n"); + buff_test.push_str(test_strings.as_str()); + } + + _ => {} + }, + WastDirective::AssertInvalid { + span: _, + module: _, + message: _, + } => {} + WastDirective::AssertTrap { + span: _, + exec: _, + message: _, + } => {} + WastDirective::AssertMalformed { + span: _, + module: _, + message: _, + } => {} + _other => {} + } + } + + buff_externc.push_str("\n}\n"); + buff_test.push_str("}\n"); + let rs_path = target_dir.join(format!("{}/target/spectest/spectest.rs", project_root)); + + if idx == 0 { + // remove file if exists + if rs_path.exists() { + std::fs::remove_file(&rs_path).expect("error remove file"); + } + + // write to new file + let buff = format!("{}{}", buff_externc, buff_test); + std::fs::write(&rs_path, &buff).expect("error write file"); + } else { + let f = std::fs::OpenOptions::new() + .write(true) + .append(true) + .open(&rs_path) + .expect("error open file"); + let mut bw = std::io::BufWriter::new(f); + bw.write_all(buff_test.as_bytes()) + .expect("error write file"); + } +} + +pub const SPECTESTS: [&str; 2] = ["i32", "i64"]; + +pub fn compile_wast_from_spectest() -> Result<()> { + for (i, testname) in SPECTESTS.iter().enumerate() { + compile_spec_test(testname, i); + } + Ok(()) +} + /// Receive a Wasm binary and compile it into ELF binary. pub fn compile_wasm(wasm: &[u8], args: &Args) -> Result<()> { // Prepare inkwell (Rust-wrapper of LLVM) instances @@ -88,7 +279,7 @@ pub fn compile_wasm(wasm: &[u8], args: &Args) -> Result<()> { } fn output_elf(environment: Environment) -> Result<()> { - let obj_path = path::Path::new(environment.output_file); + let obj_path = PathBuf::from(environment.output_file); let ll_path = obj_path.with_extension("ll"); log::info!("write to {}", ll_path.display()); diff --git a/src/lib.rs b/src/lib.rs index f4c4e22..395a366 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,3 +6,4 @@ pub mod environment; pub mod inkwell; pub mod insts; pub mod section; +pub mod wasi_wrapper; diff --git a/src/main.rs b/src/main.rs index 978ded7..7007e65 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,8 +7,15 @@ fn main() -> Result<()> { env_logger::init_from_env(env_logger::Env::new().default_filter_or("info")); let args = compiler::Args::parse(); + // If spectest mode is enabled, compile Wasm from spectest's *.wast file. + if args.spectest { + log::info!("SpecTest mode is enabled."); + compiler::compile_wast_from_spectest().expect("Failed to compile spectest"); + return Ok(()); + } + // Compile Wasm and output ELF - compiler::compile_wasm_from_file(&args)?; + compiler::compile_wasm_from_file(&args).expect("Failed to compile input Wasm"); Ok(()) } diff --git a/examples/wasi-wrapper/rust/src/wasi.rs b/src/wasi_wrapper.rs similarity index 56% rename from examples/wasi-wrapper/rust/src/wasi.rs rename to src/wasi_wrapper.rs index f0c13de..89920da 100644 --- a/examples/wasi-wrapper/rust/src/wasi.rs +++ b/src/wasi_wrapper.rs @@ -1,7 +1,29 @@ -//! WASI Implementation based on Rust Std Lib -use crate::memory::get_memory_base; +use std::sync::Mutex; use wasi::{Errno, ERRNO_SUCCESS}; +const LINEAR_MEMORY_BLOCK_SIZE: i32 = 64 * 1024; +const LINEAR_MEMORY_BLOCK_NUM_MAX: i32 = 32; + +static mut LINEAR_MEMORY_BASE: *mut u8 = 0 as _; +static LINEAR_MEMORY_BLOCK_NUM: Mutex = Mutex::new(0); + +#[inline] +pub unsafe fn get_memory_base() -> *mut u8 { + LINEAR_MEMORY_BASE +} + +unsafe fn alloc_memory() -> *mut u8 { + use std::alloc::{alloc, Layout}; + LINEAR_MEMORY_BASE = alloc( + Layout::from_size_align( + (LINEAR_MEMORY_BLOCK_SIZE * LINEAR_MEMORY_BLOCK_NUM_MAX) as usize, + 8, + ) + .unwrap(), + ); + LINEAR_MEMORY_BASE +} + #[repr(C)] #[derive(Clone, Copy)] struct IoVec { @@ -60,3 +82,24 @@ pub extern "C" fn environ_sizes_get(_env_count_addr: i32, _env_buf_size_addr: i3 pub extern "C" fn proc_exit(code: i32) -> ! { std::process::exit(code); } + +#[no_mangle] +pub extern "C" fn memory_base() -> usize { + unsafe { alloc_memory() as usize } +} + +#[no_mangle] +pub extern "C" fn memory_grow(block_num: i32) -> i32 { + assert!( + block_num >= 0, + "block_num must be greater than or equal to 0" + ); + let mut num = LINEAR_MEMORY_BLOCK_NUM.lock().unwrap(); + let old_val = *num; + if num.checked_add(block_num).unwrap() > LINEAR_MEMORY_BLOCK_NUM_MAX { + println!("memory_grow: failed to grow memory"); + return -1; + } + *num += block_num; + old_val +} diff --git a/tests/control.rs b/tests/control.rs deleted file mode 100644 index 5c25110..0000000 --- a/tests/control.rs +++ /dev/null @@ -1,131 +0,0 @@ -use wasker::compiler; - -#[test] -fn example() { - let wat = "./tests/wat/block.wat"; - let args = compiler::Args { - input_file: wat.into(), - output_file: "/tmp/wasm.o".into(), - }; - compiler::compile_wasm_from_file(&args).expect("fail compile"); -} - -#[test] -fn block() { - let wat = "./tests/wat/block.wat"; - let args = compiler::Args { - input_file: wat.into(), - output_file: "/tmp/wasm.o".into(), - }; - compiler::compile_wasm_from_file(&args).expect("fail compile"); -} - -#[test] -fn ret() { - let wat = "./tests/wat/return.wat"; - let args = compiler::Args { - input_file: wat.into(), - output_file: "/tmp/wasm.o".into(), - }; - compiler::compile_wasm_from_file(&args).expect("fail compile"); -} - -#[test] -fn call() { - let wat = "./tests/wat/call.wat"; - let args = compiler::Args { - input_file: wat.into(), - output_file: "/tmp/wasm.o".into(), - }; - compiler::compile_wasm_from_file(&args).expect("fail compile"); -} - -#[test] -fn call_indirect() { - let wat = "./tests/wat/call_indirect.wat"; - let args = compiler::Args { - input_file: wat.into(), - output_file: "/tmp/wasm.o".into(), - }; - compiler::compile_wasm_from_file(&args).expect("fail compile"); -} - -#[test] -fn select() { - let wat = "./tests/wat/select.wat"; - let args = compiler::Args { - input_file: wat.into(), - output_file: "/tmp/wasm.o".into(), - }; - compiler::compile_wasm_from_file(&args).expect("fail compile"); -} - -#[test] -fn br() { - let wat = "./tests/wat/br.wat"; - let args = compiler::Args { - input_file: wat.into(), - output_file: "/tmp/wasm.o".into(), - }; - compiler::compile_wasm_from_file(&args).expect("fail compile"); -} - -#[test] -fn br_table() { - let wat = "./tests/wat/br_table.wat"; - let args = compiler::Args { - input_file: wat.into(), - output_file: "/tmp/wasm.o".into(), - }; - compiler::compile_wasm_from_file(&args).expect("fail compile"); -} - -#[test] -fn br_if() { - let wat = "./tests/wat/br_if.wat"; - let args = compiler::Args { - input_file: wat.into(), - output_file: "/tmp/wasm.o".into(), - }; - compiler::compile_wasm_from_file(&args).expect("fail compile"); -} - -#[test] -fn iff() { - let wat = "./tests/wat/if.wat"; - let args = compiler::Args { - input_file: wat.into(), - output_file: "/tmp/wasm.o".into(), - }; - compiler::compile_wasm_from_file(&args).expect("fail compile"); -} - -#[test] -fn loopp() { - let wat = "./tests/wat/loop.wat"; - let args = compiler::Args { - input_file: wat.into(), - output_file: "/tmp/wasm.o".into(), - }; - compiler::compile_wasm_from_file(&args).expect("fail compile"); -} - -#[test] -fn switch() { - let wat = "./tests/wat/switch.wat"; - let args = compiler::Args { - input_file: wat.into(), - output_file: "/tmp/wasm.o".into(), - }; - compiler::compile_wasm_from_file(&args).expect("fail compile"); -} - -#[test] -fn bulk() { - let wat = "./tests/wat/bulk.wat"; - let args = compiler::Args { - input_file: wat.into(), - output_file: "/tmp/wasm.o".into(), - }; - compiler::compile_wasm_from_file(&args).expect("fail compile"); -} diff --git a/tests/local.rs b/tests/local.rs deleted file mode 100644 index 466a57f..0000000 --- a/tests/local.rs +++ /dev/null @@ -1,21 +0,0 @@ -use wasker::compiler; - -#[test] -fn local_get() { - let wat = "./tests/wat/local_get.wat"; - let args = compiler::Args { - input_file: wat.into(), - output_file: "/tmp/wasm.o".into(), - }; - compiler::compile_wasm_from_file(&args).expect("fail compile"); -} - -#[test] -fn global() { - let wat = "./tests/wat/global.wat"; - let args = compiler::Args { - input_file: wat.into(), - output_file: "/tmp/wasm.o".into(), - }; - compiler::compile_wasm_from_file(&args).expect("fail compile"); -} diff --git a/tests/main.rs b/tests/main.rs index bffcdf9..47bd18d 100644 --- a/tests/main.rs +++ b/tests/main.rs @@ -1,6 +1,2 @@ -mod control; -mod local; -mod memory; -mod numeric; mod rust; mod spec; diff --git a/tests/memory.rs b/tests/memory.rs deleted file mode 100644 index 4ea20f7..0000000 --- a/tests/memory.rs +++ /dev/null @@ -1,71 +0,0 @@ -use wasker::compiler; - -#[test] -fn memory_size() { - let wat = "./tests/wat/memory_size.wat"; - let args = compiler::Args { - input_file: wat.into(), - output_file: "/tmp/wasm.o".into(), - }; - compiler::compile_wasm_from_file(&args).expect("fail compile"); -} - -#[test] -fn memory_copy() { - let wat = "./tests/wat/memory_copy.wat"; - let args = compiler::Args { - input_file: wat.into(), - output_file: "/tmp/wasm.o".into(), - }; - compiler::compile_wasm_from_file(&args).expect("fail compile"); -} - -#[test] -fn memory_fill() { - let wat = "./tests/wat/memory_fill.wat"; - let args = compiler::Args { - input_file: wat.into(), - output_file: "/tmp/wasm.o".into(), - }; - compiler::compile_wasm_from_file(&args).expect("fail compile"); -} - -#[test] -fn endianness() { - let wat = "./tests/wat/endianness.wat"; - let args = compiler::Args { - input_file: wat.into(), - output_file: "/tmp/wasm.o".into(), - }; - compiler::compile_wasm_from_file(&args).expect("fail compile"); -} - -#[test] -fn address32() { - let wat = "./tests/wat/address32.wat"; - let args = compiler::Args { - input_file: wat.into(), - output_file: "/tmp/wasm.o".into(), - }; - compiler::compile_wasm_from_file(&args).expect("fail compile"); -} - -#[test] -fn address64() { - let wat = "./tests/wat/address64.wat"; - let args = compiler::Args { - input_file: wat.into(), - output_file: "/tmp/wasm.o".into(), - }; - compiler::compile_wasm_from_file(&args).expect("fail compile"); -} - -#[test] -fn align() { - let wat = "./tests/wat/align.wat"; - let args = compiler::Args { - input_file: wat.into(), - output_file: "/tmp/wasm.o".into(), - }; - compiler::compile_wasm_from_file(&args).expect("fail compile"); -} diff --git a/tests/numeric.rs b/tests/numeric.rs deleted file mode 100644 index f330935..0000000 --- a/tests/numeric.rs +++ /dev/null @@ -1,51 +0,0 @@ -use wasker::compiler; - -#[test] -fn i64() { - let wat = "./tests/wat/i64.wat"; - let args = compiler::Args { - input_file: wat.into(), - output_file: "/tmp/wasm.o".into(), - }; - compiler::compile_wasm_from_file(&args).expect("fail compile"); -} - -#[test] -fn convert() { - let wat = "./tests/wat/convert.wat"; - let args = compiler::Args { - input_file: wat.into(), - output_file: "/tmp/wasm.o".into(), - }; - compiler::compile_wasm_from_file(&args).expect("fail compile"); -} - -#[test] -fn f64() { - let wat = "./tests/wat/f64.wat"; - let args = compiler::Args { - input_file: wat.into(), - output_file: "/tmp/wasm.o".into(), - }; - compiler::compile_wasm_from_file(&args).expect("fail compile"); -} - -#[test] -fn f64_cmp() { - let wat = "./tests/wat/f64_cmp.wat"; - let args = compiler::Args { - input_file: wat.into(), - output_file: "/tmp/wasm.o".into(), - }; - compiler::compile_wasm_from_file(&args).expect("fail compile"); -} - -#[test] -fn f64_bitwise() { - let wat = "./tests/wat/f64_bitwise.wat"; - let args = compiler::Args { - input_file: wat.into(), - output_file: "/tmp/wasm.o".into(), - }; - compiler::compile_wasm_from_file(&args).expect("fail compile"); -} diff --git a/tests/rust.rs b/tests/rust.rs index 17c10d9..d115bab 100644 --- a/tests/rust.rs +++ b/tests/rust.rs @@ -6,6 +6,7 @@ fn rust() { let args = compiler::Args { input_file: wat.into(), output_file: "/tmp/wasm.o".into(), + spectest: false, }; compiler::compile_wasm_from_file(&args).expect("fail compile"); } diff --git a/tests/spec.rs b/tests/spec.rs index 0b2c46a..b8a7239 100644 --- a/tests/spec.rs +++ b/tests/spec.rs @@ -1,166 +1,5 @@ -use std::io::Read; - -use wasker::compiler::{self, compile_wasm}; -use wast::{lexer::Lexer, parser::ParseBuffer, Wast, WastDirective}; - -fn run_spec_test(testname: &str) { - let path = "./tests/testsuite"; - - // Read Wast - let mut wat = String::new(); - let wat_path = std::path::Path::new(path).join(format!("{}.wast", testname)); - println!("open file: {:?}", wat_path); - let mut file = std::fs::File::open(wat_path).expect("error open file"); - file.read_to_string(&mut wat).expect("cannot read file"); - - // Parse Wast - let mut lexer = Lexer::new(&wat); - lexer.allow_confusing_unicode(true); - let parse_buffer = match ParseBuffer::new_with_lexer(lexer) { - Ok(buffer) => buffer, - Err(error) => { - panic!("failed to create ParseBuffer : {}", error) - } - }; - let wast = match wast::parser::parse::(&parse_buffer) { - Ok(wast) => wast, - Err(error) => { - panic!( - "failed to parse `.wast` spec test file {} for: {}", - testname, error - ) - } - }; - - // Execute - for directive in wast.directives { - match directive { - WastDirective::Wat(mut wat) => { - // Get Wasm binary - let wasm = wat.encode().expect("failed to encode wat"); - assert_eq!(wasm[0..4], [0, 97, 115, 109]); - - // Compile with Wasker - let args = compiler::Args { - input_file: "dummy.wasm".into(), - output_file: "/tmp/wasm.o".into(), - }; - compile_wasm(&wasm, &args).expect("failed to Wasker compile"); - } - WastDirective::AssertReturn { - span: _, - exec: _, - results: _, - } => {} - WastDirective::AssertInvalid { - span: _, - module: _, - message: _, - } => {} - WastDirective::AssertTrap { - span: _, - exec: _, - message: _, - } => {} - WastDirective::AssertMalformed { - span: _, - module: _, - message: _, - } => {} - WastDirective::Invoke(_invoke) => {} - _other => {} - } - } -} - -macro_rules! spec_test { - ($testname:ident, $fname:expr) => { - #[test] - #[allow(non_snake_case)] - fn $testname() { - run_spec_test($fname); - } - }; -} - -spec_test!(i64, "i64"); - -/* -spec_test!(address, "address"); -spec_test!(align, "align"); -spec_test!(binary, "binary"); -spec_test!(binary_leb128, "binary-leb128"); -spec_test!(block, "block"); -spec_test!(br, "br"); -spec_test!(br_if, "br_if"); -spec_test!(br_table, "br_table"); -spec_test!(break_drop, "break-drop"); -spec_test!(call, "call"); -spec_test!(call_indirect, "call_indirect"); -spec_test!(comments, "comments"); -spec_test!(r#const, "const"); -spec_test!(conversions, "conversions"); -spec_test!(custom, "custom"); -spec_test!(endianness, "endianness"); -spec_test!(exports, "exports"); -spec_test!(f32, "f32"); -spec_test!(f32_bitwise, "f32_bitwise"); -spec_test!(f32_cmp, "f32_cmp"); -spec_test!(f64, "f64"); -spec_test!(f64_bitwise, "f64_bitwise"); -spec_test!(f64_cmp, "f64_cmp"); -spec_test!(fac, "fac"); -spec_test!(float_exprs, "float_exprs"); -spec_test!(float_literals, "float_literals"); -spec_test!(float_memory, "float_memory"); -spec_test!(float_misc, "float_misc"); -spec_test!(forward, "forward"); -spec_test!(func_ptrs, "func_ptrs"); -spec_test!(i32, "i32"); -spec_test!(r#if, "if"); -spec_test!(inline_module, "inline-module"); -spec_test!(int_exprs, "int_exprs"); -spec_test!(int_literals, "int_literals"); -spec_test!(labels, "labels"); -spec_test!(left_to_right, "left-to-right"); -spec_test!(load, "load"); -spec_test!(local_get, "local_get"); -spec_test!(local_set, "local_set"); -spec_test!(local_tee, "local_tee"); -spec_test!(r#loop, "loop"); -spec_test!(memory, "memory"); -spec_test!(memory_grow, "memory_grow"); -spec_test!(memory_redundancy, "memory_redundancy"); -spec_test!(memory_size, "memory_size"); -spec_test!(memory_trap, "memory_trap"); -spec_test!(names, "names"); -spec_test!(nop, "nop"); -spec_test!(r#return, "return"); -spec_test!(select, "select"); -spec_test!(skip_stack_guard_page, "skip-stack-guard-page"); -spec_test!(start, "start"); -spec_test!(store, "store"); -spec_test!(switch, "switch"); -spec_test!(traps, "traps"); -spec_test!(token, "token"); -spec_test!(r#type, "type"); -spec_test!(unreachable, "unreachable"); -spec_test!(unreached_invalid, "unreached-invalid"); -spec_test!(utf8_import_field, "utf8-import-field"); -spec_test!(utf8_import_module, "utf8-import-module"); -spec_test!(utf8_invalid_encoding, "utf8-invalid-encoding"); -spec_test!(utf8_custom_section_id, "utf8-custom-section-id"); - -// Run failed because of unsupported ImportKind::Memory -spec_test!(data, "data"); -spec_test!(elem, "elem"); -spec_test!(globals, "globals"); -spec_test!(imports, "imports"); -spec_test!(linking, "linking"); - - -spec_test!(func, "func"); -spec_test!(unwind, "unwind"); - -spec_test!(stack, "stack"); -*/ +// Generated test code from spectest.rs: +include!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/target/spectest/spectest.rs" +)); diff --git a/tests/testsuite b/tests/testsuite deleted file mode 160000 index 83f0863..0000000 --- a/tests/testsuite +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 83f0863c9f52050590dd47a4647d5c5ef1f2fdf9 diff --git a/testsuite b/testsuite new file mode 160000 index 0000000..7d002b7 --- /dev/null +++ b/testsuite @@ -0,0 +1 @@ +Subproject commit 7d002b7f5eda5eee8d13f3a5aa6b1843fdaf3dfa