miden_testing/
executor.rs1use alloc::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> {
42 let assembler = TransactionKernel::testing_assembler();
43 let source_manager = assembler.source_manager();
44 let program = assembler.assemble_program(code).unwrap();
45 self.execute_program(program, source_manager)
46 }
47
48 pub fn execute_program(
49 mut self,
50 program: Program,
51 source_manager: Arc<dyn SourceManager>,
52 ) -> Result<Process, ExecutionError> {
53 let mut process =
54 Process::new_debug(program.kernel().clone(), self.stack_inputs.unwrap_or_default())
55 .with_source_manager(source_manager);
56 process.execute(&program, &mut self.host)?;
57
58 Ok(process)
59 }
60}
61
62impl<A> CodeExecutor<DefaultHost<A>>
63where
64 A: AdviceProvider,
65{
66 pub fn with_advice_provider(adv_provider: A) -> Self {
67 let mut host = DefaultHost::new(adv_provider);
68
69 let test_lib = TransactionKernel::kernel_as_library();
70 host.load_mast_forest(test_lib.mast_forest().clone()).unwrap();
71
72 CodeExecutor::new(host)
73 }
74}