miden_testing/
executor.rs1use alloc::{borrow::ToOwned, sync::Arc};
2
3use miden_lib::transaction::TransactionKernel;
4use miden_objects::assembly::SourceManager;
5use vm_processor::{
6 AdviceInputs, AdviceProvider, DefaultHost, ExecutionError, Host, Process, Program, StackInputs,
7};
8
9pub struct CodeExecutor<H> {
14 host: H,
15 stack_inputs: Option<StackInputs>,
16 advice_inputs: AdviceInputs,
17}
18
19impl<H: Host> CodeExecutor<H> {
20 pub(crate) fn new(host: H) -> Self {
23 Self {
24 host,
25 stack_inputs: None,
26 advice_inputs: AdviceInputs::default(),
27 }
28 }
29
30 pub fn extend_advice_inputs(mut self, advice_inputs: AdviceInputs) -> Self {
31 self.advice_inputs.extend(advice_inputs);
32 self
33 }
34
35 pub fn stack_inputs(mut self, stack_inputs: StackInputs) -> Self {
36 self.stack_inputs = Some(stack_inputs);
37 self
38 }
39
40 pub fn run(self, code: &str) -> Result<Process, ExecutionError> {
45 let assembler = TransactionKernel::testing_assembler().with_debug_mode(true);
46 let source_manager = assembler.source_manager();
47
48 let virtual_source_file = source_manager.load("_user_code", code.to_owned());
50 let program = assembler.assemble_program(virtual_source_file).unwrap();
51
52 self.execute_program(program, source_manager)
53 }
54
55 pub fn execute_program(
60 mut self,
61 program: Program,
62 source_manager: Arc<dyn SourceManager>,
63 ) -> Result<Process, ExecutionError> {
64 let mut process =
65 Process::new_debug(program.kernel().clone(), self.stack_inputs.unwrap_or_default())
66 .with_source_manager(source_manager);
67 process.execute(&program, &mut self.host)?;
68
69 Ok(process)
70 }
71}
72
73impl<A> CodeExecutor<DefaultHost<A>>
74where
75 A: AdviceProvider,
76{
77 pub fn with_advice_provider(adv_provider: A) -> Self {
78 let mut host = DefaultHost::new(adv_provider);
79
80 let test_lib = TransactionKernel::kernel_as_library();
81 host.load_mast_forest(test_lib.mast_forest().clone()).unwrap();
82
83 CodeExecutor::new(host)
84 }
85}