wasm/execution/
resumable.rs1use core::num::NonZeroU32;
2
3use alloc::{
4 sync::{Arc, Weak},
5 vec::Vec,
6};
7
8use crate::{
9 addrs::FuncAddr,
10 core::slotmap::{SlotMap, SlotMapKey},
11 rw_spinlock::RwSpinLock,
12 value_stack::Stack,
13 Value,
14};
15
16#[derive(Debug)]
17pub(crate) struct Resumable {
18 pub(crate) stack: Stack,
19 pub(crate) pc: usize,
20 pub(crate) stp: usize,
21 pub(crate) current_func_addr: FuncAddr,
22 pub(crate) maybe_fuel: Option<u32>,
23}
24
25#[derive(Default)]
26pub(crate) struct Dormitory(pub(crate) Arc<RwSpinLock<SlotMap<Resumable>>>);
27
28impl Dormitory {
29 #[allow(unused)]
30 pub(crate) fn new() -> Self {
31 Self::default()
32 }
33
34 pub(crate) fn insert(&self, resumable: Resumable) -> InvokedResumableRef {
35 let key = self.0.write().insert(resumable);
36
37 InvokedResumableRef {
38 dormitory: Arc::downgrade(&self.0),
39 key,
40 }
41 }
42}
43
44pub struct InvokedResumableRef {
45 pub(crate) dormitory: Weak<RwSpinLock<SlotMap<Resumable>>>,
46 pub(crate) key: SlotMapKey<Resumable>,
47}
48
49pub struct FreshResumableRef {
50 pub(crate) func_addr: FuncAddr,
51 pub(crate) params: Vec<Value>,
52 pub(crate) maybe_fuel: Option<u32>,
53}
54
55pub enum ResumableRef {
59 Fresh(FreshResumableRef),
60 Invoked(InvokedResumableRef),
61}
62
63impl Drop for InvokedResumableRef {
64 fn drop(&mut self) {
65 let Some(dormitory) = self.dormitory.upgrade() else {
66 return;
68 };
69
70 dormitory.write().remove(&self.key)
71 .expect("that the resumable could not have been removed already, because then this self could not exist or the dormitory weak pointer would have been None");
72 }
73}
74
75pub enum RunState {
79 Finished(Vec<Value>),
80 Resumable {
81 resumable_ref: ResumableRef,
82 required_fuel: NonZeroU32,
83 },
84}
85
86#[cfg(test)]
87mod test {
88 use crate::{addrs::FuncAddr, value_stack::Stack};
89
90 use super::{Dormitory, Resumable};
91
92 #[test]
94 fn dormitory_constructor() {
95 let dorm = Dormitory::new();
96
97 let resumable = Resumable {
98 stack: Stack::new(),
99 pc: 11,
100 stp: 13,
101 current_func_addr: FuncAddr::INVALID,
102 maybe_fuel: None,
103 };
104
105 dorm.insert(resumable);
106 }
107}