diff --git a/Cargo.toml b/Cargo.toml index 2dee9d0..6d7432a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,9 @@ binaryen = "0.12" criterion = "0.3" diff = "0.1" rand = "0.8" -wabt = "0.10" +wat = "1" +wasmparser = "0.82" +wasmprinter = "0.2" [features] default = ["std"] diff --git a/src/export_globals.rs b/src/export_globals.rs index e509ff6..c36549b 100644 --- a/src/export_globals.rs +++ b/src/export_globals.rs @@ -71,10 +71,8 @@ mod tests { use parity_wasm::elements; fn parse_wat(source: &str) -> elements::Module { - let module_bytes = wabt::Wat2Wasm::new() - .validate(true) - .convert(source) - .expect("failed to parse module"); + let module_bytes = wat::parse_str(source).unwrap(); + wasmparser::validate(&module_bytes).unwrap(); elements::deserialize_buffer(module_bytes.as_ref()).expect("failed to parse module") } @@ -93,7 +91,19 @@ mod tests { let expected_bytes = elements::serialize(expected_module) .expect("injected module must have a function body"); - assert_eq!(actual_bytes, expected_bytes); + let actual_wat = wasmprinter::print_bytes(actual_bytes).unwrap(); + let expected_wat = wasmprinter::print_bytes(expected_bytes).unwrap(); + + if actual_wat != expected_wat { + for diff in diff::lines(&expected_wat, &actual_wat) { + match diff { + diff::Result::Left(l) => println!("-{}", l), + diff::Result::Both(l, _) => println!(" {}", l), + diff::Result::Right(r) => println!("+{}", r), + } + } + panic!() + } } }; } diff --git a/src/gas_metering/mod.rs b/src/gas_metering/mod.rs index f6b4577..b3cbe13 100644 --- a/src/gas_metering/mod.rs +++ b/src/gas_metering/mod.rs @@ -613,21 +613,15 @@ mod tests { #[test] fn simple_grow() { - let module = builder::module() - .global() - .value_type() - .i32() - .build() - .function() - .signature() - .param() - .i32() - .build() - .body() - .with_instructions(elements::Instructions::new(vec![GetGlobal(0), GrowMemory(0), End])) - .build() - .build() - .build(); + let module = parse_wat( + r#"(module + (func (result i32) + global.get 0 + memory.grow) + (global i32 (i32.const 42)) + (memory 0 1) + )"#, + ); let injected_module = inject(module, &ConstantCostRules::new(1, 10_000), "env").unwrap(); @@ -642,26 +636,20 @@ mod tests { ); let binary = serialize(injected_module).expect("serialization failed"); - wabt::wasm2wat(&binary).unwrap(); + wasmparser::validate(&binary).unwrap(); } #[test] fn grow_no_gas_no_track() { - let module = builder::module() - .global() - .value_type() - .i32() - .build() - .function() - .signature() - .param() - .i32() - .build() - .body() - .with_instructions(elements::Instructions::new(vec![GetGlobal(0), GrowMemory(0), End])) - .build() - .build() - .build(); + let module = parse_wat( + r"(module + (func (result i32) + global.get 0 + memory.grow) + (global i32 (i32.const 42)) + (memory 0 1) + )", + ); let injected_module = inject(module, &ConstantCostRules::default(), "env").unwrap(); @@ -673,7 +661,7 @@ mod tests { assert_eq!(injected_module.functions_space(), 2); let binary = serialize(injected_module).expect("serialization failed"); - wabt::wasm2wat(&binary).unwrap(); + wasmparser::validate(&binary).unwrap(); } #[test] @@ -741,11 +729,8 @@ mod tests { } fn parse_wat(source: &str) -> elements::Module { - let module_bytes = wabt::Wat2Wasm::new() - .validate(false) - .convert(source) - .expect("failed to parse module"); - elements::deserialize_buffer(module_bytes.as_ref()).expect("failed to parse module") + let module_bytes = wat::parse_str(source).unwrap(); + elements::deserialize_buffer(module_bytes.as_ref()).unwrap() } macro_rules! test_gas_counter_injection { diff --git a/src/stack_limiter/max_height.rs b/src/stack_limiter/max_height.rs index 055966d..4be939b 100644 --- a/src/stack_limiter/max_height.rs +++ b/src/stack_limiter/max_height.rs @@ -415,7 +415,7 @@ mod tests { use parity_wasm::elements; fn parse_wat(source: &str) -> elements::Module { - elements::deserialize_buffer(&wabt::wat2wasm(source).expect("Failed to wat2wasm")) + elements::deserialize_buffer(&wat::parse_str(source).expect("Failed to wat2wasm")) .expect("Failed to deserialize the module") } @@ -477,7 +477,8 @@ mod tests { #[test] fn yet_another_test() { - const SOURCE: &str = r#" + let module = parse_wat( + r#" (module (memory 0) (func @@ -496,15 +497,8 @@ mod tests { i32.const 2 ) ) -"#; - let module = elements::deserialize_buffer( - wabt::Wat2Wasm::new() - .validate(false) - .convert(SOURCE) - .expect("Failed to wat2wasm") - .as_ref(), - ) - .expect("Failed to deserialize the module"); +"#, + ); let height = compute(0, &module).unwrap(); assert_eq!(height, 2 + ACTIVATION_FRAME_COST); diff --git a/src/stack_limiter/mod.rs b/src/stack_limiter/mod.rs index 02e2a3d..99f13ae 100644 --- a/src/stack_limiter/mod.rs +++ b/src/stack_limiter/mod.rs @@ -351,16 +351,13 @@ mod tests { use parity_wasm::elements; fn parse_wat(source: &str) -> elements::Module { - elements::deserialize_buffer(&wabt::wat2wasm(source).expect("Failed to wat2wasm")) + elements::deserialize_buffer(&wat::parse_str(source).expect("Failed to wat2wasm")) .expect("Failed to deserialize the module") } fn validate_module(module: elements::Module) { let binary = elements::serialize(module).expect("Failed to serialize"); - wabt::Module::read_binary(&binary, &Default::default()) - .expect("Wabt failed to read final binary") - .validate() - .expect("Invalid module"); + wasmparser::validate(&binary).expect("Invalid module"); } #[test] diff --git a/tests/diff.rs b/tests/diff.rs index 03425a2..de6dcbd 100644 --- a/tests/diff.rs +++ b/tests/diff.rs @@ -5,6 +5,7 @@ use std::{ path::{Path, PathBuf}, }; use wasm_instrument as instrument; +use wasmparser::validate; fn slurp>(path: P) -> io::Result> { let mut f = fs::File::open(path)?; @@ -19,11 +20,6 @@ fn dump>(path: P, buf: &[u8]) -> io::Result<()> { Ok(()) } -fn validate_wasm(binary: &[u8]) -> Result<(), wabt::Error> { - wabt::Module::read_binary(&binary, &Default::default())?.validate()?; - Ok(()) -} - fn run_diff_test Vec>(test_dir: &str, name: &str, test: F) { // FIXME: not going to work on windows? let mut fixture_path = PathBuf::from(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/fixtures/",)); @@ -36,17 +32,17 @@ fn run_diff_test Vec>(test_dir: &str, name: &str, test: expected_path.push(test_dir); expected_path.push(name); - let fixture_wat = slurp(&fixture_path).expect("Failed to read fixture"); - let fixture_wasm = wabt::wat2wasm(fixture_wat).expect("Failed to read fixture"); - validate_wasm(&fixture_wasm).expect("Fixture is invalid"); + let fixture_wasm = wat::parse_file(&fixture_path).expect("Failed to read fixture"); + validate(&fixture_wasm).expect("Fixture is invalid"); let expected_wat = slurp(&expected_path).unwrap_or_default(); let expected_wat = std::str::from_utf8(&expected_wat).expect("Failed to decode expected wat"); let actual_wasm = test(fixture_wasm.as_ref()); - validate_wasm(&actual_wasm).expect("Result module is invalid"); + validate(&actual_wasm).expect("Result module is invalid"); - let actual_wat = wabt::wasm2wat(&actual_wasm).expect("Failed to convert result wasm to wat"); + let actual_wat = + wasmprinter::print_bytes(&actual_wasm).expect("Failed to convert result wasm to wat"); if actual_wat != expected_wat { println!("difference!"); diff --git a/tests/expectations/gas/branch.wat b/tests/expectations/gas/branch.wat index 376b5e2..b314e32 100644 --- a/tests/expectations/gas/branch.wat +++ b/tests/expectations/gas/branch.wat @@ -1,11 +1,11 @@ (module (type (;0;) (func (result i32))) (type (;1;) (func (param i32))) - (import "env" "gas" (func (;0;) (type 1))) + (import "env" "gas" (func $fibonacci_with_break (type 1))) (func (;1;) (type 0) (result i32) (local i32 i32) i32.const 13 - call 0 + call $fibonacci_with_break block ;; label = @1 i32.const 0 local.set 0 @@ -19,11 +19,11 @@ i32.const 1 br_if 0 (;@1;) i32.const 5 - call 0 + call $fibonacci_with_break local.get 0 local.get 1 local.tee 0 i32.add local.set 1 end - local.get 1)) + local.get 1)) \ No newline at end of file diff --git a/tests/expectations/gas/call.wat b/tests/expectations/gas/call.wat index b72159e..a02e9df 100644 --- a/tests/expectations/gas/call.wat +++ b/tests/expectations/gas/call.wat @@ -1,19 +1,19 @@ (module (type (;0;) (func (param i32 i32) (result i32))) (type (;1;) (func (param i32))) - (import "env" "gas" (func (;0;) (type 1))) - (func (;1;) (type 0) (param i32 i32) (result i32) + (import "env" "gas" (func $add_locals (type 1))) + (func $add (type 0) (param $x i32) (param $y i32) (result i32) (local i32) i32.const 5 - call 0 - local.get 0 - local.get 1 + call $add_locals + local.get $x + local.get $y call 2 local.set 2 local.get 2) (func (;2;) (type 0) (param i32 i32) (result i32) i32.const 3 - call 0 + call $add_locals local.get 0 local.get 1 - i32.add)) + i32.add)) \ No newline at end of file diff --git a/tests/expectations/gas/ifs.wat b/tests/expectations/gas/ifs.wat index 0252360..163db76 100644 --- a/tests/expectations/gas/ifs.wat +++ b/tests/expectations/gas/ifs.wat @@ -17,4 +17,4 @@ call 0 local.get 0 i32.popcnt - end)) + end)) \ No newline at end of file diff --git a/tests/expectations/gas/simple.wat b/tests/expectations/gas/simple.wat index b967d21..f7b7755 100644 --- a/tests/expectations/gas/simple.wat +++ b/tests/expectations/gas/simple.wat @@ -21,4 +21,4 @@ call 0 block ;; label = @1 end) - (export "simple" (func 1))) + (export "simple" (func 1))) \ No newline at end of file diff --git a/tests/expectations/gas/start.wat b/tests/expectations/gas/start.wat index 78bd406..db51c26 100644 --- a/tests/expectations/gas/start.wat +++ b/tests/expectations/gas/start.wat @@ -2,17 +2,17 @@ (type (;0;) (func (param i32 i32))) (type (;1;) (func)) (type (;2;) (func (param i32))) - (import "env" "ext_return" (func (;0;) (type 0))) + (import "env" "ext_return" (func $ext_return (type 0))) (import "env" "memory" (memory (;0;) 1 1)) - (import "env" "gas" (func (;1;) (type 2))) + (import "env" "gas" (func $start (type 2))) (func (;2;) (type 1) i32.const 4 - call 1 + call $start i32.const 8 i32.const 4 - call 0 + call $ext_return unreachable) (func (;3;) (type 1)) (export "call" (func 3)) (start 2) - (data (;0;) (i32.const 8) "\01\02\03\04")) + (data (;0;) (i32.const 8) "\01\02\03\04")) \ No newline at end of file diff --git a/tests/expectations/stack-height/empty_functions.wat b/tests/expectations/stack-height/empty_functions.wat index 20a71f4..63642ed 100644 --- a/tests/expectations/stack-height/empty_functions.wat +++ b/tests/expectations/stack-height/empty_functions.wat @@ -48,5 +48,5 @@ i32.const 2 i32.sub global.set 0) - (global (;0;) (mut i32) (i32.const 0)) - (export "main" (func 2))) + (global (;0;) (mut i32) i32.const 0) + (export "main" (func 2))) \ No newline at end of file diff --git a/tests/expectations/stack-height/global.wat b/tests/expectations/stack-height/global.wat index 0289a50..a14d625 100644 --- a/tests/expectations/stack-height/global.wat +++ b/tests/expectations/stack-height/global.wat @@ -2,20 +2,20 @@ (type (;0;) (func)) (type (;1;) (func (param i32 i32) (result i32))) (type (;2;) (func (param i32))) - (import "env" "foo" (func (;0;) (type 0))) - (func (;1;) (type 1) (param i32 i32) (result i32) + (import "env" "foo" (func $foo (type 0))) + (func $i32.add (type 1) (param i32 i32) (result i32) local.get 0 local.get 1 i32.add) - (func (;2;) (type 2) (param i32) - (local i32) - global.get 0 + (func (;2;) (type 2) (param $arg i32) + (local $tmp i32) + global.get $counter i32.const 1 i32.add - local.tee 1 - global.set 0 - local.get 1 - local.get 0 + local.tee $tmp + global.set $counter + local.get $tmp + local.get $arg global.get 1 i32.const 4 i32.add @@ -26,7 +26,7 @@ if ;; label = @1 unreachable end - call 1 + call $i32.add global.get 1 i32.const 4 i32.sub @@ -45,11 +45,11 @@ if ;; label = @1 unreachable end - call 1 + call $i32.add global.get 1 i32.const 4 i32.sub global.set 1) - (global (;0;) (mut i32) (i32.const 1)) - (global (;1;) (mut i32) (i32.const 0)) - (export "i32.add" (func 3))) + (global $counter (mut i32) i32.const 1) + (global (;1;) (mut i32) i32.const 0) + (export "i32.add" (func 3))) \ No newline at end of file diff --git a/tests/expectations/stack-height/imports.wat b/tests/expectations/stack-height/imports.wat index 0098281..c945ce2 100644 --- a/tests/expectations/stack-height/imports.wat +++ b/tests/expectations/stack-height/imports.wat @@ -1,11 +1,11 @@ (module (type (;0;) (func)) (type (;1;) (func (param i32 i32) (result i32))) - (import "env" "foo" (func (;0;) (type 0))) - (import "env" "boo" (func (;1;) (type 0))) + (import "env" "foo" (func $foo (type 0))) + (import "env" "boo" (func $boo (type 0))) (func (;2;) (type 1) (param i32 i32) (result i32) - call 0 - call 1 + call $foo + call $boo local.get 0 local.get 1 i32.add) @@ -27,5 +27,5 @@ i32.const 4 i32.sub global.set 0) - (global (;0;) (mut i32) (i32.const 0)) - (export "i32.add" (func 3))) + (global (;0;) (mut i32) i32.const 0) + (export "i32.add" (func 3))) \ No newline at end of file diff --git a/tests/expectations/stack-height/many_locals.wat b/tests/expectations/stack-height/many_locals.wat index c3202f7..941a0e7 100644 --- a/tests/expectations/stack-height/many_locals.wat +++ b/tests/expectations/stack-height/many_locals.wat @@ -1,8 +1,8 @@ (module (type (;0;) (func)) - (func (;0;) (type 0) + (func $one-group-many-locals (type 0) (local i64 i64 i32)) - (func (;1;) (type 0) + (func $main (type 0) global.get 0 i32.const 5 i32.add @@ -13,9 +13,9 @@ if ;; label = @1 unreachable end - call 0 + call $one-group-many-locals global.get 0 i32.const 5 i32.sub global.set 0) - (global (;0;) (mut i32) (i32.const 0))) + (global (;0;) (mut i32) i32.const 0)) \ No newline at end of file diff --git a/tests/expectations/stack-height/simple.wat b/tests/expectations/stack-height/simple.wat index 6d1568f..0e8c54c 100644 --- a/tests/expectations/stack-height/simple.wat +++ b/tests/expectations/stack-height/simple.wat @@ -19,5 +19,5 @@ i32.const 3 i32.sub global.set 0) - (global (;0;) (mut i32) (i32.const 0)) - (export "simple" (func 1))) + (global (;0;) (mut i32) i32.const 0) + (export "simple" (func 1))) \ No newline at end of file diff --git a/tests/expectations/stack-height/start.wat b/tests/expectations/stack-height/start.wat index 87e7ecb..780d5d9 100644 --- a/tests/expectations/stack-height/start.wat +++ b/tests/expectations/stack-height/start.wat @@ -1,9 +1,9 @@ (module (type (;0;) (func (param i32 i32))) (type (;1;) (func)) - (import "env" "ext_return" (func (;0;) (type 0))) + (import "env" "ext_return" (func $ext_return (type 0))) (import "env" "memory" (memory (;0;) 1 1)) - (func (;1;) (type 1) + (func $start (type 1) (local i32)) (func (;2;) (type 1)) (func (;3;) (type 1) @@ -17,7 +17,7 @@ if ;; label = @1 unreachable end - call 1 + call $start global.get 0 i32.const 3 i32.sub @@ -38,6 +38,6 @@ i32.const 2 i32.sub global.set 0) - (global (;0;) (mut i32) (i32.const 0)) + (global (;0;) (mut i32) i32.const 0) (export "call" (func 4)) - (start 3)) + (start 3)) \ No newline at end of file diff --git a/tests/expectations/stack-height/table.wat b/tests/expectations/stack-height/table.wat index b345a5d..d81303e 100644 --- a/tests/expectations/stack-height/table.wat +++ b/tests/expectations/stack-height/table.wat @@ -2,7 +2,7 @@ (type (;0;) (func)) (type (;1;) (func (param i32))) (type (;2;) (func (param i32 i32) (result i32))) - (import "env" "foo" (func (;0;) (type 0))) + (import "env" "foo" (func $foo (type 0))) (func (;1;) (type 1) (param i32) local.get 0 i32.const 0 @@ -16,13 +16,13 @@ if ;; label = @1 unreachable end - call 2 + call $i32.add global.get 0 i32.const 4 i32.sub global.set 0 drop) - (func (;2;) (type 2) (param i32 i32) (result i32) + (func $i32.add (type 2) (param i32 i32) (result i32) local.get 0 local.get 1 i32.add) @@ -56,12 +56,12 @@ if ;; label = @1 unreachable end - call 2 + call $i32.add global.get 0 i32.const 4 i32.sub global.set 0) (table (;0;) 10 funcref) - (global (;0;) (mut i32) (i32.const 0)) + (global (;0;) (mut i32) i32.const 0) (export "i32.add" (func 4)) - (elem (;0;) (i32.const 0) func 0 3 4)) + (elem (;0;) (i32.const 0) func $foo 3 4)) \ No newline at end of file