wasm/execution/
resumable.rs

1use core::num::NonZeroU64;
2
3use alloc::vec::Vec;
4
5use crate::{addrs::FuncAddr, value_stack::Stack, HaltExecutionError, Value};
6
7/// # Safety
8///
9/// TODO:
10///
11/// - stack must be initialized with correct parameters to function
12///   referenced by function address
13/// - program counter must be valid for the bytecode of function referenced by the function address
14/// - stp must point to the correct sidetable entry for the function referenced by function address
15#[derive(Debug)]
16pub struct WasmResumable {
17    pub(crate) stack: Stack,
18    pub(crate) pc: usize,
19    pub(crate) stp: usize,
20    pub(crate) current_func_addr: FuncAddr,
21    pub(crate) maybe_fuel: Option<u64>,
22}
23
24#[derive(Debug)]
25pub struct HostResumable<T> {
26    /// Must be a host function instance.
27    pub(crate) func_addr: FuncAddr,
28    /// Must contain the correct types as specified by the [`FuncType`](crate::FuncType) for
29    /// `func_addr`.
30    pub(crate) params: Vec<Value>,
31    pub(crate) hostcode: fn(&mut T, Vec<Value>) -> Result<Vec<Value>, HaltExecutionError>,
32    pub(crate) maybe_fuel: Option<u64>,
33}
34
35#[derive(Debug)]
36pub enum Resumable<T> {
37    Wasm(WasmResumable),
38    Host(HostResumable<T>),
39}
40
41impl<T> Resumable<T> {
42    pub fn fuel(&self) -> Option<u64> {
43        match self {
44            Resumable::Wasm(wasm_resumable) => wasm_resumable.maybe_fuel,
45            Resumable::Host(host_resumable) => host_resumable.maybe_fuel,
46        }
47    }
48
49    pub fn fuel_mut(&mut self) -> &mut Option<u64> {
50        match self {
51            Resumable::Wasm(wasm_resumable) => &mut wasm_resumable.maybe_fuel,
52            Resumable::Host(host_resumable) => &mut host_resumable.maybe_fuel,
53        }
54    }
55}
56
57/// Represents the state of a possibly interrupted resumable.
58pub enum RunState<T> {
59    /// represents a resumable that has executed completely with return values `values` and possibly remaining fuel
60    /// `maybe_remaining_fuel` (has `Some(remaining_fuel)` for fuel-metered operations and `None` otherwise)
61    Finished {
62        values: Vec<Value>,
63        maybe_remaining_fuel: Option<u64>,
64    },
65    /// represents a resumable that has ran out of fuel during execution, missing at least `required_fuel` units of fuel
66    /// to continue further execution.
67    Resumable {
68        resumable: Resumable<T>, // TODO make this a `WasmResumable`
69        required_fuel: NonZeroU64,
70    },
71}