miden_testing/
executor.rs1#[cfg(test)]
2use miden_processor::DefaultHost;
3use miden_processor::fast::{ExecutionOutput, FastProcessor};
4use miden_processor::{AdviceInputs, AsyncHost, ExecutionError, Program, StackInputs};
5#[cfg(test)]
6use miden_protocol::assembly::Assembler;
7
8pub(crate) struct CodeExecutor<H> {
13 host: H,
14 stack_inputs: Option<StackInputs>,
15 advice_inputs: AdviceInputs,
16}
17
18impl<H: AsyncHost> CodeExecutor<H> {
19 pub(crate) fn new(host: H) -> Self {
22 Self {
23 host,
24 stack_inputs: None,
25 advice_inputs: AdviceInputs::default(),
26 }
27 }
28
29 pub fn extend_advice_inputs(mut self, advice_inputs: AdviceInputs) -> Self {
30 self.advice_inputs.extend(advice_inputs);
31 self
32 }
33
34 pub fn stack_inputs(mut self, stack_inputs: StackInputs) -> Self {
35 self.stack_inputs = Some(stack_inputs);
36 self
37 }
38
39 #[cfg(test)]
44 pub async fn run(self, code: &str) -> Result<ExecutionOutput, ExecutionError> {
45 use alloc::borrow::ToOwned;
46 use alloc::sync::Arc;
47
48 use miden_protocol::assembly::debuginfo::{SourceLanguage, Uri};
49 use miden_protocol::assembly::{DefaultSourceManager, SourceManagerSync};
50 use miden_standards::code_builder::CodeBuilder;
51
52 let source_manager: Arc<dyn SourceManagerSync> = Arc::new(DefaultSourceManager::default());
53 let assembler: Assembler = CodeBuilder::with_kernel_library(source_manager.clone()).into();
54
55 let virtual_source_file =
57 source_manager.load(SourceLanguage::Masm, Uri::new("_user_code"), code.to_owned());
58 let program = assembler.assemble_program(virtual_source_file).unwrap();
59
60 self.execute_program(program).await
61 }
62
63 pub async fn execute_program(
68 mut self,
69 program: Program,
70 ) -> Result<ExecutionOutput, ExecutionError> {
71 let stack_inputs =
77 StackInputs::new(self.stack_inputs.unwrap_or_default().iter().copied().collect())
78 .unwrap();
79
80 let processor = FastProcessor::new_debug(stack_inputs.as_slice(), self.advice_inputs);
81
82 let execution_output = processor.execute(&program, &mut self.host).await?;
83
84 Ok(execution_output)
85 }
86}
87
88#[cfg(test)]
89impl CodeExecutor<DefaultHost> {
90 pub fn with_default_host() -> Self {
91 use miden_protocol::transaction::TransactionKernel;
92
93 let mut host = DefaultHost::default();
94
95 let test_lib = TransactionKernel::library();
96 host.load_library(test_lib.mast_forest()).unwrap();
97
98 CodeExecutor::new(host)
99 }
100}