Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions codegen/masm/src/emulator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ pub struct Emulator {
step_over: Option<InstructionPointer>,
clk: usize,
clk_limit: usize,
entrypoint: Option<FunctionIdent>,
}
impl Default for Emulator {
fn default() -> Self {
Expand Down Expand Up @@ -170,6 +171,7 @@ impl Emulator {
step_over: None,
clk: 0,
clk_limit: usize::MAX,
entrypoint: None,
}
}

Expand Down Expand Up @@ -292,6 +294,7 @@ impl Emulator {
self.load_module(module)?;
cursor.move_next();
}
self.entrypoint = program.entrypoint;

// TODO: Load data segments

Expand Down Expand Up @@ -508,10 +511,10 @@ impl Emulator {
Status::Faulted(ref err) => return Err(err.clone()),
}

let main_fn = FunctionIdent {
let main_fn = self.entrypoint.unwrap_or_else(|| FunctionIdent {
module: LibraryNamespace::EXEC_PATH.into(),
function: ProcedureName::MAIN_PROC_NAME.into(),
};
});

// Run to completion
let stack = self.invoke(main_fn, &[]).map_err(|err| match err {
Expand Down
80 changes: 52 additions & 28 deletions tests/integration/src/compiler_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use std::{
};

use miden_assembly::{ast::ModuleKind, diagnostics::Report, Assembler, LibraryPath};
use miden_core::Program;
use miden_diagnostics::SourceSpan;
use miden_stdlib::StdLibrary;
use midenc_frontend_wasm::{translate, WasmTranslationConfig};
Expand Down Expand Up @@ -93,14 +92,16 @@ pub struct CompilerTest {
pub source: CompilerTestSource,
/// The entrypoint function to use when building the IR
entrypoint: Option<FunctionIdent>,
/// The compiled IR
pub hir: Option<HirArtifact>,
/// The compiled MASM
pub masm_program: Option<Box<miden_core::Program>>,
/// The MASM source code
pub masm_src: Option<String>,
/// The extra MASM modules to link to the compiled MASM program
pub link_masm_modules: LinkMasmModules,
/// The compiled IR
hir: Option<HirArtifact>,
/// The MASM source code
masm_src: Option<String>,
/// The compiled IR MASM program
ir_masm_program: Option<Result<Arc<midenc_codegen_masm::Program>, String>>,
/// The compiled VM program
vm_masm_program: Option<Result<Arc<miden_core::Program>, String>>,
}

impl Default for CompilerTest {
Expand All @@ -110,10 +111,11 @@ impl Default for CompilerTest {
session: Arc::new(dummy_session()),
source: CompilerTestSource::Rust(String::new()),
entrypoint: None,
link_masm_modules: Vec::new(),
hir: None,
masm_program: None,
masm_src: None,
link_masm_modules: Vec::new(),
ir_masm_program: None,
vm_masm_program: None,
}
}
}
Expand Down Expand Up @@ -558,23 +560,26 @@ impl CompilerTest {
expected_masm_file.assert_eq(&program);
}

/// Get the compiled IR MASM program
pub fn ir_masm_program(&mut self) -> Arc<midenc_codegen_masm::Program> {
if self.ir_masm_program.is_none() {
self.compile_wasm_to_masm_program();
}
self.ir_masm_program.as_ref().unwrap().as_ref().unwrap().clone()
}

/// Get the compiled MASM as [`miden_core::Program`]
pub fn masm_program(&mut self) -> Box<miden_core::Program> {
if self.masm_program.is_none() {
let (masm, src) = self.compile_wasm_to_masm_program();
self.masm_src = Some(src);
let unwrapped = masm.unwrap_or_else(|e| panic!("Failed to assemble MASM: {:?}", e));
self.masm_program = Some(unwrapped.into());
pub fn vm_masm_program(&mut self) -> Arc<miden_core::Program> {
if self.vm_masm_program.is_none() {
self.compile_wasm_to_masm_program();
}
self.masm_program.clone().unwrap()
self.vm_masm_program.as_ref().unwrap().as_ref().unwrap().clone()
}

/// Get the MASM source code
pub fn masm_src(&mut self) -> String {
if self.masm_src.is_none() {
let (masm, src) = self.compile_wasm_to_masm_program();
self.masm_src = Some(src);
self.masm_program = masm.ok().map(Box::from);
self.compile_wasm_to_masm_program();
}
self.masm_src.clone().unwrap()
}
Expand All @@ -588,9 +593,7 @@ impl CompilerTest {
}
}

pub(crate) fn compile_wasm_to_masm_program(
&self,
) -> (Result<miden_core::Program, Report>, String) {
pub(crate) fn compile_wasm_to_masm_program(&mut self) {
match midenc_compile::compile_to_memory(self.session.clone()).unwrap() {
midenc_compile::Compiled::Program(_p) => todo!("Program compilation not yet supported"),
midenc_compile::Compiled::Modules(modules) => {
Expand All @@ -599,9 +602,13 @@ impl CompilerTest {
self.entrypoint,
&self.link_masm_modules,
);
let prog =
masm_prog_from_modules(&modules, self.entrypoint, &self.link_masm_modules);
(prog, src)
self.masm_src = Some(src);
let vm_prog =
vm_masm_prog_from_modules(&modules, self.entrypoint, &self.link_masm_modules);
self.vm_masm_program = Some(vm_prog.map_err(|e| format!("{:?}", e)));
let ir_prog =
ir_masm_prog_from_modules(modules, self.entrypoint, &self.link_masm_modules);
self.ir_masm_program = Some(ir_prog.map_err(|e| format!("{:?}", e)));
}
}
}
Expand All @@ -627,12 +634,29 @@ pub fn skip_rust_compilation(cargo_project_folder: &Path, artifact_name: &str) -
skip_rust
}

#[allow(clippy::vec_box)]
fn ir_masm_prog_from_modules(
modules: Vec<Box<midenc_codegen_masm::Module>>,
entrypoint: Option<FunctionIdent>,
link_masm_modules: &LinkMasmModules,
) -> Result<Arc<midenc_codegen_masm::Program>, Report> {
let mut p = midenc_codegen_masm::Program::empty();
for (_path, _src) in link_masm_modules {
// TODO: implement linking of MASM source code
}
for module in modules.into_iter() {
p.insert(module);
}
p.entrypoint = entrypoint;
Ok(Box::new(p).freeze())
}

// Assemble the VM MASM program from the compiled IR MASM modules
fn masm_prog_from_modules(
fn vm_masm_prog_from_modules(
modules: &[Box<midenc_codegen_masm::Module>],
entrypoint: Option<FunctionIdent>,
link_masm_modules: &LinkMasmModules,
) -> Result<Program, Report> {
) -> Result<Arc<miden_core::Program>, Report> {
let mut assembler = Assembler::default().with_library(&StdLibrary::default())?;
for (path, src) in link_masm_modules {
let options = miden_assembly::CompileOptions {
Expand All @@ -657,7 +681,7 @@ fn masm_prog_from_modules(
}
if let Some(entrypoint) = entrypoint {
let prog_source = masm_prog_source(entrypoint);
assembler.assemble_program(prog_source)
assembler.assemble_program(prog_source).map(Arc::new)
} else {
todo!()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ fn test_blake3_hash() {
test.expect_wasm(expect_file![format!("../../../expected/{artifact_name}.wat")]);
test.expect_ir(expect_file![format!("../../../expected/{artifact_name}.hir")]);
test.expect_masm(expect_file![format!("../../../expected/{artifact_name}.masm")]);
let vm_program = test.masm_program();
let vm_program = test.vm_masm_program();

// Run the Rust and compiled MASM code against a bunch of random inputs and compare the results
let res = TestRunner::default().run(&any::<[u8; 64]>(), move |ibytes| {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ fn test_get_inputs(test_name: &str, expected_inputs: Vec<Felt>) {
test.expect_ir(expect_file![format!("../../../expected/{artifact_name}.hir")]);
test.expect_masm(expect_file![format!("../../../expected/{artifact_name}.masm")]);

let _vm_program = test.masm_program();
let _vm_program = test.vm_masm_program();
// let _vm_out = execute_vm(&vm_program, &[]);
}

Expand Down
2 changes: 1 addition & 1 deletion tests/integration/src/rust_masm_tests/apps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fn fib() {
test.expect_ir(expect_file!["../../expected/fib.hir"]);
test.expect_masm(expect_file!["../../expected/fib.masm"]);
// let ir_masm = test.ir_masm_program();
let vm_program = &test.masm_program();
let vm_program = &test.vm_masm_program();

// Run the Rust and compiled MASM code against a bunch of random inputs and compare the results
TestRunner::default()
Expand Down
10 changes: 6 additions & 4 deletions tests/integration/src/rust_masm_tests/instructions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ macro_rules! test_bin_op {
test.expect_wasm(expect_file![format!("../../expected/{artifact_name}.wat")]);
test.expect_ir(expect_file![format!("../../expected/{artifact_name}.hir")]);
test.expect_masm(expect_file![format!("../../expected/{artifact_name}.masm")]);
let vm_program = test.masm_program();
let vm_program = test.vm_masm_program();
let ir_program = test.ir_masm_program();

// Run the Rust and compiled MASM code against a bunch of random inputs and compare the results
let res = TestRunner::default()
Expand All @@ -31,7 +32,7 @@ macro_rules! test_bin_op {
let rs_out = a $op b;
dbg!(&rs_out);
let args = [TestFelt::from(a).0, TestFelt::from(b).0];
run_masm_vs_rust(rs_out, &vm_program, &args)
run_masm_vs_rust(rs_out, &vm_program, ir_program.clone(), &args)
});
match res {
Err(TestError::Fail(_, value)) => {
Expand Down Expand Up @@ -60,15 +61,16 @@ macro_rules! test_unary_op {
test.expect_wasm(expect_file![format!("../../expected/{artifact_name}.wat")]);
test.expect_ir(expect_file![format!("../../expected/{artifact_name}.hir")]);
test.expect_masm(expect_file![format!("../../expected/{artifact_name}.masm")]);
let vm_program = test.masm_program();
let vm_program = test.vm_masm_program();
let ir_program = test.ir_masm_program();

// Run the Rust and compiled MASM code against a bunch of random inputs and compare the results
let res = TestRunner::default()
.run(&($range), move |a| {
let rs_out = $op a;
dbg!(&rs_out);
let args = [TestFelt::from(a).0];
run_masm_vs_rust(rs_out, &vm_program, &args)
run_masm_vs_rust(rs_out, &vm_program, ir_program.clone(), &args)
});
match res {
Err(TestError::Fail(_, value)) => {
Expand Down
5 changes: 3 additions & 2 deletions tests/integration/src/rust_masm_tests/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ macro_rules! test_bin_op {
test.expect_wasm(expect_file![format!("../../expected/{artifact_name}.wat")]);
test.expect_ir(expect_file![format!("../../expected/{artifact_name}.hir")]);
test.expect_masm(expect_file![format!("../../expected/{artifact_name}.masm")]);
let vm_program = test.masm_program();
let vm_program = test.vm_masm_program();
let ir_program = test.ir_masm_program();

// Run the Rust and compiled MASM code against a bunch of random inputs and compare the results
let res = TestRunner::default()
Expand All @@ -36,7 +37,7 @@ macro_rules! test_bin_op {
let rs_out = a_felt $op b_felt;
dbg!(&rs_out);
let args = [a.0, b.0];
run_masm_vs_rust(rs_out, &vm_program, &args)
run_masm_vs_rust(rs_out, &vm_program, ir_program.clone(), &args)
});
match res {
Err(TestError::Fail(_, value)) => {
Expand Down
12 changes: 9 additions & 3 deletions tests/integration/src/rust_masm_tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
#![allow(unused_imports)]
#![allow(unused_variables)]

use std::sync::Arc;

use miden_core::Felt;
use proptest::{prop_assert_eq, test_runner::TestCaseError};

use crate::{execute_vm, felt_conversion::TestFelt};
use crate::{execute_emulator, execute_vm, felt_conversion::TestFelt};

mod abi_transform;
mod apps;
Expand All @@ -14,6 +19,7 @@ mod wit_sdk;
pub fn run_masm_vs_rust<T>(
rust_out: T,
vm_program: &miden_core::Program,
ir_program: Arc<midenc_codegen_masm::Program>,
args: &[Felt],
) -> Result<(), TestCaseError>
where
Expand All @@ -22,8 +28,8 @@ where
let vm_out: T = (*execute_vm(vm_program, args).first().unwrap()).into();
dbg!(&vm_out);
prop_assert_eq!(rust_out.clone(), vm_out, "VM output mismatch");
// TODO: eq for i64 and u64 fails with invalid operand stack size error
// let emul_out: T = execute_emulator(ir_masm.clone(), &args).first().unwrap().clone().into();
// TODO: Uncomment after https://github.com/0xPolygonMiden/compiler/issues/228 is fixed
// let emul_out: T = (*execute_emulator(ir_program.clone(), args).first().unwrap()).into();
// prop_assert_eq!(rust_out, emul_out, "Emulator output mismatch");
Ok(())
}