Skip to content

Commit

Permalink
Merge pull request #84 from 0xPolygonMiden/greenhat/i80-wasm-cm-pr2-i…
Browse files Browse the repository at this point in the history
…nteg-tests-lazy-ir-build

[2/3] Wasm CM support in frontend-wasm. Integration tests preparation (lazy IR compilation)
  • Loading branch information
bitwalker authored Jan 16, 2024
2 parents 95632fa + fb8aca3 commit 2ebf8e7
Show file tree
Hide file tree
Showing 9 changed files with 59 additions and 106 deletions.
12 changes: 1 addition & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion frontend-wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
17 changes: 5 additions & 12 deletions frontend-wasm/src/module/sections_translator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
}
Expand Down
10 changes: 2 additions & 8 deletions frontend-wasm/tests/expected/add.hir
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
22 changes: 8 additions & 14 deletions frontend-wasm/tests/expected/array.hir
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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);
Expand All @@ -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;
}
10 changes: 2 additions & 8 deletions frontend-wasm/tests/expected/enum.hir
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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;
Expand Down
5 changes: 1 addition & 4 deletions frontend-wasm/tests/expected/fib.hir
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
18 changes: 6 additions & 12 deletions frontend-wasm/tests/expected/static_mut.hir
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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() {
Expand All @@ -57,8 +54,5 @@ block0:
v11 = add.checked v10, 1048576 : u32;
v12 = inttoptr v11 : *mut u8;
store v12, v9;
br block1;

block1:
ret;
}
69 changes: 33 additions & 36 deletions tests/integration/src/compiler_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ impl CompilerTestSource {
pub struct CompilerTest {
session: Session,
pub(crate) source: CompilerTestSource,
entrypoint: Option<FunctionIdent>,
wasm_bytes: Vec<u8>,
/// The WIT Rust bindings generated by the wit-bindgen (if Wasm component is compiled)
wit_bind: Option<String>,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -217,29 +219,22 @@ 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(
Symbol::intern(entrypoint.to_string()),
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 {
cargo_project_folder_name: cargo_project_folder.to_string(),
artifact_name: artifact_name.to_string(),
},
wasm_bytes,
hir: Some(hir_program.into()),
entrypoint: Some(entrypoint),
hir: None,
ir_masm: None,
wit_bind: None,
}
Expand All @@ -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,
}
Expand All @@ -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"),
Expand All @@ -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,
}
Expand All @@ -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)
Expand Down Expand Up @@ -420,9 +412,15 @@ fn compile_rust_file(rust_source: &str) -> Vec<u8> {
"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)
Expand All @@ -436,8 +434,7 @@ fn compile_rust_file(rust_source: &str) -> Vec<u8> {
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;
}

Expand Down

0 comments on commit 2ebf8e7

Please sign in to comment.