datex_core/runtime/execution/execution_loop/
state.rs1use crate::{
2 collections::HashMap,
3 references::observers::TransceiverId,
4 runtime::{
5 RuntimeInternal,
6 execution::{
7 ExecutionError,
8 execution_loop::{
9 ExternalExecutionInterrupt, execution_loop,
10 interrupts::InterruptProvider,
11 },
12 },
13 },
14 values::value_container::ValueContainer,
15};
16use core::{cell::RefCell, fmt::Debug};
17
18use crate::prelude::*;
19pub struct ExecutionLoopState {
20 pub iterator: Box<
21 dyn Iterator<Item = Result<ExternalExecutionInterrupt, ExecutionError>>,
22 >,
23 pub dxb_body: Rc<RefCell<Vec<u8>>>,
24 pub(crate) interrupt_provider: InterruptProvider,
25}
26impl ExecutionLoopState {
27 pub fn new(
28 dxb_body: Vec<u8>,
29 runtime: Option<Rc<RuntimeInternal>>,
30 slots: RuntimeExecutionSlots,
31 ) -> Self {
32 let state = RuntimeExecutionState {
33 runtime_internal: runtime.clone(),
34 source_id: 0, slots,
36 };
37 let dxb_rc = Rc::new(RefCell::new(dxb_body.to_vec()));
39 let interrupt_provider = InterruptProvider::new();
40 ExecutionLoopState {
41 dxb_body: dxb_rc.clone(),
42 iterator: Box::new(execution_loop(
43 state,
44 dxb_rc,
45 interrupt_provider.clone(),
46 )),
47 interrupt_provider,
48 }
49 }
50}
51
52impl Debug for ExecutionLoopState {
53 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
54 f.debug_struct("ExecutionIterator")
55 .field("dxb_body_length", &self.dxb_body.borrow().len())
56 .finish()
57 }
58}
59
60#[derive(Debug, Default)]
61pub struct RuntimeExecutionState {
62 pub slots: RuntimeExecutionSlots,
65 pub runtime_internal: Option<Rc<RuntimeInternal>>,
66 pub source_id: TransceiverId,
67}
68
69#[derive(Debug, Default)]
70pub struct RuntimeExecutionSlots {
71 pub slots: HashMap<u32, Option<ValueContainer>>,
72}
73
74impl RuntimeExecutionSlots {
75 pub(crate) fn allocate_slot(
77 &mut self,
78 address: u32,
79 value: Option<ValueContainer>,
80 ) {
81 self.slots.insert(address, value);
82 }
83
84 pub(crate) fn drop_slot(
87 &mut self,
88 address: u32,
89 ) -> Result<Option<ValueContainer>, ExecutionError> {
90 self.slots
91 .remove(&address)
92 .ok_or(())
93 .map_err(|_| ExecutionError::SlotNotAllocated(address))
94 }
95
96 pub(crate) fn set_slot_value(
99 &mut self,
100 address: u32,
101 value: ValueContainer,
102 ) -> Result<Option<ValueContainer>, ExecutionError> {
103 self.slots
104 .insert(address, Some(value))
105 .ok_or(())
106 .map_err(|_| ExecutionError::SlotNotAllocated(address))
107 }
108
109 pub(crate) fn get_slot_value(
112 &self,
113 address: u32,
114 ) -> Result<&ValueContainer, ExecutionError> {
115 self.slots
116 .get(&address)
117 .and_then(|inner| inner.as_ref())
118 .ok_or_else(|| ExecutionError::SlotNotAllocated(address))
119 }
120
121 pub(crate) fn get_slot_value_mut(
124 &mut self,
125 address: u32,
126 ) -> Result<&mut ValueContainer, ExecutionError> {
127 self.slots
128 .get_mut(&address)
129 .and_then(|inner| inner.as_mut())
130 .ok_or_else(|| ExecutionError::SlotNotAllocated(address))
131 }
132}