miden_testing/
executor.rs1use alloc::borrow::ToOwned;
2use alloc::sync::Arc;
3
4use miden_lib::transaction::TransactionKernel;
5use miden_objects::assembly::debuginfo::{SourceLanguage, Uri};
6use miden_objects::assembly::{DefaultSourceManager, SourceManagerSync};
7use miden_processor::{
8 AdviceInputs,
9 DefaultHost,
10 ExecutionError,
11 Process,
12 Program,
13 StackInputs,
14 SyncHost,
15};
16
17pub struct CodeExecutor<H> {
22 host: H,
23 stack_inputs: Option<StackInputs>,
24 advice_inputs: AdviceInputs,
25}
26
27impl<H: SyncHost> CodeExecutor<H> {
28 pub(crate) fn new(host: H) -> Self {
31 Self {
32 host,
33 stack_inputs: None,
34 advice_inputs: AdviceInputs::default(),
35 }
36 }
37
38 pub fn extend_advice_inputs(mut self, advice_inputs: AdviceInputs) -> Self {
39 self.advice_inputs.extend(advice_inputs);
40 self
41 }
42
43 pub fn stack_inputs(mut self, stack_inputs: StackInputs) -> Self {
44 self.stack_inputs = Some(stack_inputs);
45 self
46 }
47
48 pub fn run(self, code: &str) -> Result<Process, ExecutionError> {
53 let source_manager: Arc<dyn SourceManagerSync> = Arc::new(DefaultSourceManager::default());
54 let assembler = TransactionKernel::with_kernel_library(source_manager.clone());
55
56 let virtual_source_file =
58 source_manager.load(SourceLanguage::Masm, Uri::new("_user_code"), code.to_owned());
59 let program = assembler.assemble_program(virtual_source_file).unwrap();
60
61 self.execute_program(program)
62 }
63
64 pub fn execute_program(mut self, program: Program) -> Result<Process, ExecutionError> {
69 let mut process = Process::new_debug(
70 program.kernel().clone(),
71 self.stack_inputs.unwrap_or_default(),
72 self.advice_inputs,
73 );
74 process.execute(&program, &mut self.host)?;
75
76 Ok(process)
77 }
78}
79
80impl CodeExecutor<DefaultHost> {
81 pub fn with_default_host() -> Self {
82 let mut host = DefaultHost::default();
83
84 let test_lib = TransactionKernel::library();
85 host.load_library(test_lib.mast_forest()).unwrap();
86
87 CodeExecutor::new(host)
88 }
89}