wasm/execution/resumable.rs
1//! TODO
2
3use core::num::NonZeroU64;
4
5use alloc::vec::Vec;
6
7use 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)]
20pub 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
28impl WasmResumable {
29 pub fn fuel(&self) -> Option<u64> {
30 self.maybe_fuel
31 }
32
33 pub fn fuel_mut(&mut self) -> &mut Option<u64> {
34 &mut self.maybe_fuel
35 }
36}
37
38/// A [`HostCall`] object contains information required for executing a specific
39/// host function.
40#[derive(Clone, Debug)]
41pub 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)]
56pub 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)]
66pub enum Resumable {
67 Wasm(WasmResumable),
68 Host {
69 host_call: HostCall,
70 host_resumable: HostResumable,
71 },
72}
73
74impl Resumable {
75 /// Tries to convert this [`Resumable`] into a [`WasmResumable`]
76 pub fn as_wasm(self) -> Option<WasmResumable> {
77 match self {
78 Self::Wasm(wasm_resumable) => Some(wasm_resumable),
79 Self::Host { .. } => None,
80 }
81 }
82
83 /// Tries to convert this [`Resumable`] into a [`HostCall`] and
84 /// [`HostResumable`]
85 pub fn as_host(self) -> Option<(HostCall, HostResumable)> {
86 match self {
87 Self::Wasm(_) => None,
88 Self::Host {
89 host_call,
90 host_resumable,
91 } => Some((host_call, host_resumable)),
92 }
93 }
94}
95
96/// Represents the state of a possibly interrupted resumable.
97pub 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}