/build/source/src/execution/resumable.rs
Line | Count | Source |
1 | | //! TODO |
2 | | |
3 | | use core::num::NonZeroU64; |
4 | | |
5 | | use alloc::vec::Vec; |
6 | | |
7 | | use crate::{addrs::FuncAddr, value_stack::Stack, Hostcode, Value}; |
8 | | |
9 | | /// A [`WasmResumable`] is an object used to resume execution of Wasm code. |
10 | | /// |
11 | | /// # Safety |
12 | | /// |
13 | | /// TODO: |
14 | | /// |
15 | | /// - stack must be initialized with correct parameters to function |
16 | | /// referenced by function address |
17 | | /// - program counter must be valid for the bytecode of function referenced by the function address |
18 | | /// - stp must point to the correct sidetable entry for the function referenced by function address |
19 | | #[derive(Debug)] |
20 | | pub struct WasmResumable { |
21 | | pub(crate) stack: Stack, |
22 | | pub(crate) pc: usize, |
23 | | pub(crate) stp: usize, |
24 | | pub(crate) current_func_addr: FuncAddr, |
25 | | pub(crate) maybe_fuel: Option<u64>, |
26 | | } |
27 | | |
28 | | impl WasmResumable { |
29 | 0 | pub fn fuel(&self) -> Option<u64> { |
30 | 0 | self.maybe_fuel |
31 | 0 | } |
32 | | |
33 | 43 | pub fn fuel_mut(&mut self) -> &mut Option<u64> { |
34 | 43 | &mut self.maybe_fuel |
35 | 43 | } |
36 | | } |
37 | | |
38 | | /// A [`HostCall`] object contains information required for executing a specific |
39 | | /// host function. |
40 | | #[derive(Clone, Debug)] |
41 | | pub struct HostCall { |
42 | | /// Must contain the correct parameter types for the host function with host |
43 | | /// code `hostcode`. |
44 | | pub params: Vec<Value>, |
45 | | pub hostcode: Hostcode, |
46 | | } |
47 | | |
48 | | /// A [`HostResumable`] is used to resume execution after executing its |
49 | | /// [`HostCall`]. |
50 | | /// |
51 | | /// When a host function is called, a [`HostResumable`] and [`HostCall`] are |
52 | | /// returned. After the [`HostCall`] was used to execute the host function, the |
53 | | /// [`HostResumable`] is used together with the return values of the host call |
54 | | /// to resume execution. |
55 | | #[derive(Debug)] |
56 | | pub struct HostResumable { |
57 | | pub(crate) host_func_addr: FuncAddr, |
58 | | pub(crate) inner_resumable: Option<WasmResumable>, |
59 | | /// Hack: This is `Some` only if `inner_resumable` is `None`. In that case |
60 | | /// it is used to store the maybe_fuel, so it can be returned in |
61 | | /// [`RunState::Finished`] later. |
62 | | pub(crate) maybe_fuel: Option<Option<u64>>, |
63 | | } |
64 | | |
65 | | #[derive(Debug)] |
66 | | pub enum Resumable { |
67 | | Wasm(WasmResumable), |
68 | | Host { |
69 | | host_call: HostCall, |
70 | | host_resumable: HostResumable, |
71 | | }, |
72 | | } |
73 | | |
74 | | impl Resumable { |
75 | | /// Tries to convert this [`Resumable`] into a [`WasmResumable`] |
76 | 0 | pub fn as_wasm(self) -> Option<WasmResumable> { |
77 | 0 | match self { |
78 | 0 | Self::Wasm(wasm_resumable) => Some(wasm_resumable), |
79 | 0 | Self::Host { .. } => None, |
80 | | } |
81 | 0 | } |
82 | | |
83 | | /// Tries to convert this [`Resumable`] into a [`HostCall`] and |
84 | | /// [`HostResumable`] |
85 | 0 | pub fn as_host(self) -> Option<(HostCall, HostResumable)> { |
86 | 0 | match self { |
87 | 0 | Self::Wasm(_) => None, |
88 | | Self::Host { |
89 | 0 | host_call, |
90 | 0 | host_resumable, |
91 | 0 | } => Some((host_call, host_resumable)), |
92 | | } |
93 | 0 | } |
94 | | } |
95 | | |
96 | | /// Represents the state of a possibly interrupted resumable. |
97 | | pub enum RunState { |
98 | | /// represents a resumable that has executed completely with return values `values` and possibly remaining fuel |
99 | | /// `maybe_remaining_fuel` (has `Some(remaining_fuel)` for fuel-metered operations and `None` otherwise) |
100 | | Finished { |
101 | | values: Vec<Value>, |
102 | | maybe_remaining_fuel: Option<u64>, |
103 | | }, |
104 | | /// represents a resumable that has ran out of fuel during execution, missing at least `required_fuel` units of fuel |
105 | | /// to continue further execution (this is None if unknown). |
106 | | Resumable { |
107 | | resumable: WasmResumable, |
108 | | required_fuel: Option<NonZeroU64>, |
109 | | }, |
110 | | /// A host function was called by Wasm code. Use the [`HostCall`] to execute |
111 | | /// the host function and resume execution using the [`HostResumable`] and |
112 | | /// the return values produced by execution. |
113 | | HostCalled { |
114 | | host_call: HostCall, |
115 | | resumable: HostResumable, |
116 | | }, |
117 | | } |