wasm/execution/
resumable.rs1use core::num::NonZeroU64;
2
3use alloc::vec::Vec;
4
5use crate::{
6 addrs::FuncAddr,
7 core::slotmap::{SlotMap, SlotMapKey},
8 value_stack::Stack,
9 Value,
10};
11
12#[derive(Debug)]
13pub(crate) struct Resumable {
14 pub(crate) stack: Stack,
15 pub(crate) pc: usize,
16 pub(crate) stp: usize,
17 pub(crate) current_func_addr: FuncAddr,
18 pub(crate) maybe_fuel: Option<u64>,
19}
20
21#[derive(Default)]
22pub(crate) struct Dormitory(SlotMap<Resumable>);
23
24impl Dormitory {
25 pub(crate) fn insert(&mut self, resumable: Resumable) -> InvokedResumableRef {
26 let key = self.0.insert(resumable);
27 InvokedResumableRef { key }
28 }
29
30 pub(crate) fn get_mut(
31 &mut self,
32 resumable_ref: &InvokedResumableRef,
33 ) -> Option<&mut Resumable> {
34 self.0.get_mut(&resumable_ref.key)
35 }
36
37 pub(crate) fn remove(&mut self, resumable_ref: InvokedResumableRef) -> Option<Resumable> {
38 self.0.remove(&resumable_ref.key)
39 }
40}
41
42pub struct InvokedResumableRef {
48 pub(crate) key: SlotMapKey<Resumable>,
49}
50
51pub struct FreshResumableRef {
52 pub(crate) func_addr: FuncAddr,
53 pub(crate) params: Vec<Value>,
54 pub(crate) maybe_fuel: Option<u64>,
55}
56
57pub enum ResumableRef {
59 Fresh(FreshResumableRef),
61 Invoked(InvokedResumableRef),
63}
64
65pub enum RunState {
67 Finished {
70 values: Vec<Value>,
71 maybe_remaining_fuel: Option<u64>,
72 },
73 Resumable {
76 resumable_ref: ResumableRef,
77 required_fuel: NonZeroU64,
78 },
79}
80
81#[cfg(test)]
82mod test {
83 use alloc::vec::Vec;
84
85 use crate::{
86 addrs::{Addr, FuncAddr},
87 core::reader::types::{FuncType, ResultType},
88 value_stack::Stack,
89 };
90
91 use super::{Dormitory, Resumable};
92
93 #[test]
95 fn dormitory_constructor() {
96 let mut dorm = Dormitory::default();
97
98 let empty_stack = Stack::new::<()>(
99 Vec::new(),
100 &FuncType {
101 params: ResultType {
102 valtypes: Vec::new(),
103 },
104 returns: ResultType {
105 valtypes: Vec::new(),
106 },
107 },
108 &[],
109 )
110 .unwrap();
111
112 let resumable = Resumable {
113 stack: empty_stack,
114 pc: 11,
115 stp: 13,
116 current_func_addr: FuncAddr::new_unchecked(0),
117 maybe_fuel: None,
118 };
119
120 dorm.insert(resumable);
121 }
122}