From df8a7df9a4cc965c7ac8345757f086df17989e9e Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Wed, 27 Dec 2023 12:27:04 +0200 Subject: [PATCH 1/3] test: lazy IR compilation in integration tests --- frontend-wasm/tests/expected/add.hir | 10 +-- frontend-wasm/tests/expected/enum.hir | 10 +-- frontend-wasm/tests/expected/fib.hir | 5 +- frontend-wasm/tests/expected/static_mut.hir | 18 ++---- frontend-wasm/tests/test_rust_comp.rs | 1 + tests/integration/src/compiler_test.rs | 69 ++++++++++----------- 6 files changed, 45 insertions(+), 68 deletions(-) diff --git a/frontend-wasm/tests/expected/add.hir b/frontend-wasm/tests/expected/add.hir index fae6ccb91..062e509cd 100644 --- a/frontend-wasm/tests/expected/add.hir +++ b/frontend-wasm/tests/expected/add.hir @@ -11,17 +11,11 @@ block0: v1 = const.i32 1 : i32; v2 = const.i32 2 : i32; v3 = call noname::add(v1, v2) : i32; - br block1(v3); - -block1(v0: i32): - ret v0; + ret v3; } pub fn add(i32, i32) -> i32 { block0(v0: i32, v1: i32): v3 = add.wrapping v1, v0 : i32; - br block1(v3); - -block1(v2: i32): - ret v2; + ret v3; } diff --git a/frontend-wasm/tests/expected/enum.hir b/frontend-wasm/tests/expected/enum.hir index a70cac308..7d2c901d9 100644 --- a/frontend-wasm/tests/expected/enum.hir +++ b/frontend-wasm/tests/expected/enum.hir @@ -22,10 +22,7 @@ block0: v12 = const.i32 2 : i32; v13 = call noname::match_enum(v10, v11, v12) : i32; v14 = add.wrapping v9, v13 : i32; - br block1(v14); - -block1(v0: i32): - ret v0; + ret v14; } pub fn match_enum(i32, i32, i32) -> i32 { @@ -40,12 +37,9 @@ block0(v0: i32, v1: i32, v2: i32): _ => block4 }; -block1(v3: i32): - ret v3; - block2: v9 = mul.wrapping v1, v0 : i32; - br block1(v9); + ret v9; block3: v8 = sub.wrapping v0, v1 : i32; diff --git a/frontend-wasm/tests/expected/fib.hir b/frontend-wasm/tests/expected/fib.hir index 8be1c0991..ac0404dd6 100644 --- a/frontend-wasm/tests/expected/fib.hir +++ b/frontend-wasm/tests/expected/fib.hir @@ -10,10 +10,7 @@ pub fn __main() -> i32 { block0: v1 = const.i32 25 : i32; v2 = call noname::fib(v1) : i32; - br block1(v2); - -block1(v0: i32): - ret v0; + ret v2; } pub fn fib(i32) -> i32 { diff --git a/frontend-wasm/tests/expected/static_mut.hir b/frontend-wasm/tests/expected/static_mut.hir index 5c4a0397e..cd2e84063 100644 --- a/frontend-wasm/tests/expected/static_mut.hir +++ b/frontend-wasm/tests/expected/static_mut.hir @@ -16,9 +16,6 @@ block0: v3 = const.i32 -9 : i32; br block2(v3, v2); -block1(v0: i32): - ret v0; - block2(v4: i32, v11: i32): v5 = const.i32 1048585 : i32; v6 = add.wrapping v4, v5 : i32; @@ -30,15 +27,15 @@ block2(v4: i32, v11: i32): v13 = const.i32 1 : i32; v14 = add.wrapping v4, v13 : i32; v15 = neq v14, 0 : i1; - condbr v15, block2(v14, v12), block4; + condbr v15, block5, block4; -block3: - v16 = const.i32 255 : i32; - v17 = band v12, v16 : i32; - br block1(v17); +block5: + br block2(v14, v12); block4: - br block3; + v16 = const.i32 255 : i32; + v17 = band v12, v16 : i32; + ret v17; } pub fn global_var_update() { @@ -57,8 +54,5 @@ block0: v11 = add.checked v10, 1048576 : u32; v12 = inttoptr v11 : *mut u8; store v12, v9; - br block1; - -block1: ret; } diff --git a/frontend-wasm/tests/test_rust_comp.rs b/frontend-wasm/tests/test_rust_comp.rs index c8b017f29..bb25179d7 100644 --- a/frontend-wasm/tests/test_rust_comp.rs +++ b/frontend-wasm/tests/test_rust_comp.rs @@ -22,6 +22,7 @@ fn rust_enum() { test.expect_ir(expect_file!["./expected/enum.hir"]); } +#[ignore = "Block inlining pass crashes"] #[test] fn rust_array() { let mut test = CompilerTest::rust_source_program(include_str!("rust_source/array.rs")); diff --git a/tests/integration/src/compiler_test.rs b/tests/integration/src/compiler_test.rs index 9a5aa1713..eb3d86e73 100644 --- a/tests/integration/src/compiler_test.rs +++ b/tests/integration/src/compiler_test.rs @@ -60,6 +60,7 @@ impl CompilerTestSource { pub struct CompilerTest { session: Session, pub(crate) source: CompilerTestSource, + entrypoint: Option, wasm_bytes: Vec, /// The WIT Rust bindings generated by the wit-bindgen (if Wasm component is compiled) wit_bind: Option, @@ -164,6 +165,7 @@ impl CompilerTest { cargo_project_folder_name: cargo_project_folder.to_string(), artifact_name, }, + entrypoint: None, wasm_bytes: fs::read(wasm_artifacts.first().unwrap()).unwrap(), wit_bind: Some(wit_bind_str), hir: None, @@ -217,7 +219,6 @@ impl CompilerTest { fs::remove_dir_all(target_dir).unwrap(); let session = default_session(); - let entrypoint = FunctionIdent { module: Ident::new(Symbol::intern("noname"), SourceSpan::default()), function: Ident::new( @@ -225,13 +226,6 @@ impl CompilerTest { SourceSpan::default(), ), }; - let hir_module = wasm_to_ir(&wasm_bytes, &session); - let mut builder = ProgramBuilder::new(&session.diagnostics) - .with_module(hir_module.into()) - .unwrap(); - builder = builder.with_entrypoint(entrypoint); - let hir_program = builder.link().expect("Failed to link IR program"); - CompilerTest { session, source: CompilerTestSource::RustCargo { @@ -239,7 +233,8 @@ impl CompilerTest { artifact_name: artifact_name.to_string(), }, wasm_bytes, - hir: Some(hir_program.into()), + entrypoint: Some(entrypoint), + hir: None, ir_masm: None, wit_bind: None, } @@ -249,21 +244,12 @@ impl CompilerTest { pub fn rust_source_program(rust_source: &str) -> Self { let wasm_bytes = compile_rust_file(rust_source); let session = default_session(); - let ir_module = translate_module( - &wasm_bytes, - &WasmTranslationConfig::default(), - &session.diagnostics, - ) - .expect("Failed to translate Wasm to IR program"); - let builder = ProgramBuilder::new(&session.diagnostics) - .with_module(ir_module.into()) - .unwrap(); - let ir_program = builder.link().expect("Failed to link IR program"); CompilerTest { session, source: CompilerTestSource::Rust(rust_source.to_string()), wasm_bytes, - hir: Some(ir_program), + entrypoint: None, + hir: None, ir_masm: None, wit_bind: None, } @@ -288,7 +274,6 @@ impl CompilerTest { ); let wasm_bytes = compile_rust_file(&rust_source); let session = default_session(); - let ir_module = wasm_to_ir(&wasm_bytes, &session); let entrypoint = FunctionIdent { module: Ident { name: Symbol::intern("noname"), @@ -299,17 +284,13 @@ impl CompilerTest { span: SourceSpan::default(), }, }; - let builder = ProgramBuilder::new(&session.diagnostics) - .with_module(ir_module.into()) - .unwrap() - .with_entrypoint(entrypoint); - let ir_program_with_entrypoint = builder.link().expect("Failed to link IR program"); CompilerTest { session, source: CompilerTestSource::Rust(rust_source.to_string()), wasm_bytes, - hir: Some(ir_program_with_entrypoint), + entrypoint: Some(entrypoint), + hir: None, ir_masm: None, wit_bind: None, } @@ -330,12 +311,23 @@ impl CompilerTest { /// Compare the compiled IR against the expected output pub fn expect_ir(&mut self, expected_hir_file: expect_test::ExpectFile) { + let hir_program = if let Some(hir) = self.hir.as_ref() { + hir + } else { + let hir_module = wasm_to_ir(&self.wasm_bytes, &self.session); + let mut builder = ProgramBuilder::new(&self.session.diagnostics) + .with_module(hir_module.into()) + .unwrap(); + if let Some(entrypoint) = self.entrypoint.as_ref() { + builder = builder.with_entrypoint(entrypoint.clone()); + } + let hir_program = builder.link().expect("Failed to link IR program"); + self.hir = Some(hir_program); + self.hir.as_ref().unwrap() + }; // Program does not implement pretty printer yet, use the first module let ir_module = demangle( - &self - .hir - .as_ref() - .expect("IR is not compiled") + &hir_program .modules() .iter() .take(1) @@ -420,9 +412,15 @@ fn compile_rust_file(rust_source: &str) -> Vec { "wasm32-unknown-unknown", ]; let file_name = hash_string(&[rust_source]); - let temp_dir = std::env::temp_dir(); - let input_file = temp_dir.join(format!("{file_name}.rs")); - let output_file = temp_dir.join(format!("{file_name}.wasm")); + let proj_dir = std::env::temp_dir().join(&file_name); + if proj_dir.exists() { + fs::remove_dir_all(&proj_dir).unwrap(); + fs::create_dir_all(&proj_dir).unwrap(); + } else { + fs::create_dir_all(&proj_dir).unwrap(); + } + let input_file = proj_dir.join(format!("{file_name}.rs")); + let output_file = proj_dir.join(format!("{file_name}.wasm")); fs::write(&input_file, rust_source).unwrap(); let output = Command::new("rustc") .args(&rustc_opts) @@ -436,8 +434,7 @@ fn compile_rust_file(rust_source: &str) -> Vec { panic!("Rust to Wasm compilation failed!"); } let wasm = fs::read(&output_file).unwrap(); - fs::remove_file(&input_file).unwrap(); - fs::remove_file(&output_file).unwrap(); + fs::remove_dir_all(proj_dir).unwrap(); return wasm; } From 8cbdc5ddbd8835fc70553f4a232fb02ae767ab42 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Tue, 2 Jan 2024 11:05:38 +0200 Subject: [PATCH 2/3] test: enable `rust_array` frontend test after block inline pass fixed --- frontend-wasm/tests/expected/array.hir | 22 ++++++++-------------- frontend-wasm/tests/test_rust_comp.rs | 1 - 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/frontend-wasm/tests/expected/array.hir b/frontend-wasm/tests/expected/array.hir index 671735c4b..ea3d04799 100644 --- a/frontend-wasm/tests/expected/array.hir +++ b/frontend-wasm/tests/expected/array.hir @@ -17,10 +17,7 @@ block0: v5 = const.i32 5 : i32; v6 = call noname::sum_arr(v4, v5) : i32; v7 = add.wrapping v3, v6 : i32; - br block1(v7); - -block1(v0: i32): - ret v0; + ret v7; } pub fn sum_arr(i32, i32) -> i32 { @@ -30,13 +27,10 @@ block0(v0: i32, v1: i32): v5 = eq v1, 0 : i1; v6 = cast v5 : i32; v7 = neq v6, 0 : i1; - condbr v7, block2(v4), block3; - -block1(v2: i32): - ret v2; + condbr v7, block7, block3; -block2(v20: i32): - br block1(v20); +block7: + ret v4; block3: br block4(v0, v4, v1); @@ -51,11 +45,11 @@ block4(v8: i32, v12: i32, v16: i32): v17 = const.i32 -1 : i32; v18 = add.wrapping v16, v17 : i32; v19 = neq v18, 0 : i1; - condbr v19, block4(v15, v13, v18), block6; + condbr v19, block8, block6; -block5: - br block2(v13); +block8: + br block4(v15, v13, v18); block6: - br block5; + ret v13; } diff --git a/frontend-wasm/tests/test_rust_comp.rs b/frontend-wasm/tests/test_rust_comp.rs index bb25179d7..c8b017f29 100644 --- a/frontend-wasm/tests/test_rust_comp.rs +++ b/frontend-wasm/tests/test_rust_comp.rs @@ -22,7 +22,6 @@ fn rust_enum() { test.expect_ir(expect_file!["./expected/enum.hir"]); } -#[ignore = "Block inlining pass crashes"] #[test] fn rust_array() { let mut test = CompilerTest::rust_source_program(include_str!("rust_source/array.rs")); From fb8aca3388e1e1e20926546ef6968a0e9e928e24 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Tue, 2 Jan 2024 16:08:23 +0200 Subject: [PATCH 3/3] chore: update wasmparser to v0.118.1 --- Cargo.lock | 12 +----------- frontend-wasm/Cargo.toml | 2 +- frontend-wasm/src/module/sections_translator.rs | 17 +++++------------ 3 files changed, 7 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d456c454e..478a94eb7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2683,7 +2683,7 @@ dependencies = [ "miden-integration-tests", "smallvec", "thiserror", - "wasmparser 0.107.0", + "wasmparser 0.118.1", "wat", ] @@ -5103,16 +5103,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "wasmparser" -version = "0.107.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29e3ac9b780c7dda0cac7a52a5d6d2d6707cc6e3451c9db209b6c758f40d7acb" -dependencies = [ - "indexmap 1.9.3", - "semver", -] - [[package]] name = "wasmparser" version = "0.108.0" diff --git a/frontend-wasm/Cargo.toml b/frontend-wasm/Cargo.toml index 2b8682b05..bb822c9d4 100644 --- a/frontend-wasm/Cargo.toml +++ b/frontend-wasm/Cargo.toml @@ -20,7 +20,7 @@ thiserror.workspace = true smallvec.workspace = true log.workspace = true anyhow.workspace = true -wasmparser = "0.107" +wasmparser = "0.118.1" derive_more = "0.99" [dev-dependencies] diff --git a/frontend-wasm/src/module/sections_translator.rs b/frontend-wasm/src/module/sections_translator.rs index f2424128c..e44c3baf7 100644 --- a/frontend-wasm/src/module/sections_translator.rs +++ b/frontend-wasm/src/module/sections_translator.rs @@ -14,25 +14,18 @@ use miden_diagnostics::DiagnosticsHandler; use wasmparser::{ Data, DataKind, DataSectionReader, ElementSectionReader, FunctionSectionReader, GlobalSectionReader, ImportSectionReader, MemorySectionReader, NameSectionReader, Naming, - Operator, Type, TypeRef, TypeSectionReader, + Operator, TypeRef, TypeSectionReader, }; /// Parses the Type section of the wasm module. pub fn parse_type_section<'a>( types: TypeSectionReader<'a>, environ: &mut ModuleEnvironment<'a>, - diagnostics: &DiagnosticsHandler, + _diagnostics: &DiagnosticsHandler, ) -> WasmResult<()> { - for entry in types { - match entry? { - Type::Func(wasm_func_ty) => { - let ty = convert_func_type(&wasm_func_ty)?; - environ.declare_type_func(ty); - } - Type::Array(_) => { - unsupported_diag!(diagnostics, "Array types are not supported"); - } - } + for wasm_func_ty in types.into_iter_err_on_gc_types() { + let ty = convert_func_type(&wasm_func_ty?)?; + environ.declare_type_func(ty); } Ok(()) }