Skip to main content

miden_tx/executor/
program_executor.rs

1use miden_processor::advice::AdviceInputs;
2use miden_processor::{
3    ExecutionError,
4    ExecutionOptions,
5    ExecutionOutput,
6    FastProcessor,
7    FutureMaybeSend,
8    Host,
9    Program,
10    StackInputs,
11};
12use miden_protocol::vm::{DebugSourceNodeId, PackageDebugInfo};
13
14/// A transaction-scoped program executor used by
15/// [`TransactionExecutor`](super::TransactionExecutor).
16///
17/// TODO: Move this trait into `miden-vm` once the executor boundary is
18/// consolidated there.
19pub trait ProgramExecutor {
20    /// Create a new executor configured with the provided transaction inputs and options.
21    fn new(
22        stack_inputs: StackInputs,
23        advice_inputs: AdviceInputs,
24        options: ExecutionOptions,
25    ) -> Self
26    where
27        Self: Sized;
28
29    /// Execute the provided program against the given host.
30    fn execute<H: Host + Send>(
31        self,
32        program: &Program,
33        host: &mut H,
34    ) -> impl FutureMaybeSend<Result<ExecutionOutput, ExecutionError>>;
35
36    /// Execute the provided program with package-owned source/debug context.
37    ///
38    /// Executors that do not support package debug execution may fall back to plain execution.
39    fn execute_with_package_debug_info<H: Host + Send>(
40        self,
41        program: &Program,
42        package_debug_info: &PackageDebugInfo,
43        entrypoint_source_node: Option<DebugSourceNodeId>,
44        host: &mut H,
45    ) -> impl FutureMaybeSend<Result<ExecutionOutput, ExecutionError>>
46    where
47        Self: Sized,
48    {
49        let _ = package_debug_info;
50        let _ = entrypoint_source_node;
51        self.execute(program, host)
52    }
53}
54
55impl ProgramExecutor for FastProcessor {
56    fn new(
57        stack_inputs: StackInputs,
58        advice_inputs: AdviceInputs,
59        options: ExecutionOptions,
60    ) -> Self {
61        FastProcessor::new_with_options(stack_inputs, advice_inputs, options)
62            .expect("constructing FastProcessor failed due to invalid advice inputs")
63    }
64
65    fn execute<H: Host + Send>(
66        self,
67        program: &Program,
68        host: &mut H,
69    ) -> impl FutureMaybeSend<Result<ExecutionOutput, ExecutionError>> {
70        FastProcessor::execute(self, program, host)
71    }
72
73    fn execute_with_package_debug_info<H: Host + Send>(
74        self,
75        program: &Program,
76        package_debug_info: &PackageDebugInfo,
77        entrypoint_source_node: Option<DebugSourceNodeId>,
78        host: &mut H,
79    ) -> impl FutureMaybeSend<Result<ExecutionOutput, ExecutionError>> {
80        async move {
81            match entrypoint_source_node {
82                Some(entrypoint_source_node) => {
83                    FastProcessor::execute_with_package_debug_info_at_source_node(
84                        self,
85                        program,
86                        package_debug_info,
87                        entrypoint_source_node,
88                        host,
89                    )
90                    .await
91                },
92                None => {
93                    FastProcessor::execute_with_package_debug_info(
94                        self,
95                        program,
96                        package_debug_info,
97                        host,
98                    )
99                    .await
100                },
101            }
102        }
103    }
104}