datex_core/runtime/execution/
execution_input.rs1use crate::runtime::RuntimeInternal;
2use crate::runtime::execution::ExecutionError;
3use crate::runtime::execution::execution_loop::execution_loop;
4use crate::runtime::execution::execution_loop::interrupts::{
5 ExternalExecutionInterrupt, InterruptProvider,
6};
7use crate::runtime::execution::execution_loop::state::{
8 ExecutionLoopState, RuntimeExecutionState,
9};
10use crate::stdlib::boxed::Box;
11use crate::stdlib::rc::Rc;
12use core::cell::RefCell;
13
14#[derive(Debug, Clone, Default)]
15pub struct ExecutionOptions {
16 pub verbose: bool,
17}
18
19#[derive(Debug, Default)]
21pub struct ExecutionInput<'a> {
22 pub options: ExecutionOptions,
24 pub dxb_body: &'a [u8],
26 pub loop_state: Option<ExecutionLoopState>,
28 pub runtime: Option<Rc<RuntimeInternal>>,
29}
30
31impl<'a> ExecutionInput<'a> {
32 pub fn new(
33 dxb_body: &'a [u8],
34 options: ExecutionOptions,
35 runtime: Option<Rc<RuntimeInternal>>,
36 ) -> Self {
37 Self {
38 options,
39 dxb_body,
40 loop_state: None,
41 runtime,
42 }
43 }
44
45 pub fn execution_loop(
46 mut self,
47 ) -> (
48 InterruptProvider,
49 impl Iterator<Item = Result<ExternalExecutionInterrupt, ExecutionError>>,
50 ) {
51 let mut loop_state = if let Some(existing_loop_state) =
53 self.loop_state.take()
54 {
55 *existing_loop_state.dxb_body.borrow_mut() = self.dxb_body.to_vec();
57 existing_loop_state
58 }
59 else {
61 let state = RuntimeExecutionState {
62 runtime_internal: self.runtime.clone(),
63 source_id: 0, ..Default::default()
65 };
66 let dxb_rc = Rc::new(RefCell::new(self.dxb_body.to_vec()));
68 let interrupt_provider = InterruptProvider::new();
69 ExecutionLoopState {
70 dxb_body: dxb_rc.clone(),
71 iterator: Box::new(execution_loop(
72 state,
73 dxb_rc,
74 interrupt_provider.clone(),
75 )),
76 interrupt_provider,
77 }
78 };
79 let interrupt_provider = loop_state.interrupt_provider.clone();
80
81 let iterator = gen move {
83 loop {
84 let item = loop_state.iterator.next();
85 if item.is_none() {
86 break;
87 }
88 let item = item.unwrap();
89
90 match item {
91 Err(ExecutionError::IntermediateResultWithState(
92 intermediate_result,
93 _,
94 )) => {
95 return yield Err(
96 ExecutionError::IntermediateResultWithState(
97 intermediate_result,
98 Some(loop_state),
99 ),
100 );
101 }
102 _ => yield item,
103 }
104 }
105 };
106
107 (interrupt_provider, iterator)
108 }
109}