Skip to main content

byteflow/vm/
result.rs

1use std::time::Duration;
2
3use crate::bytecode::{CapId, Value};
4
5use super::fault::Fault;
6
7/// What happened at the end of a [`crate::Vm::run`] slice.
8///
9/// This is the entire interface between `byteflow-vm` and the scheduler: the
10/// VM never touches threads, mailboxes or timers directly. It runs bytecode
11/// until it either finishes, needs an effect only the scheduler can perform,
12/// or exhausts its instruction budget — then hands one of these back and
13/// stops. That separation is what lets `byteflow-scheduler` move a suspended
14/// `Vm` between worker threads freely: it's just a value sitting in a
15/// `Flow`.
16#[derive(Debug)]
17pub enum VmResult {
18    /// The outermost frame returned/exited. The Flow should terminate
19    /// with this value delivered to `FlowHandle::join`.
20    Complete(Value),
21    /// Cooperative yield or instruction-budget exhaustion. Re-enqueue as
22    /// `Ready` on any worker; resuming picks up at the saved `pc` with no
23    /// register writeback needed.
24    Yield,
25    /// `Sleep` opcode. Register the Flow on the timer wheel; resume with
26    /// a plain `run()` call (no writeback) once it elapses.
27    Sleep(Duration),
28    /// `Spawn` — create a child flow; parent receives a **Cap** (`SEND|ASK`).
29    Spawn {
30        function: u32,
31        args: Vec<Value>,
32        dest_reg: u8,
33        requested_rights: crate::bytecode::CapRights,
34    },
35    /// `SelfPid` — write a **self Cap** (`SEND|ASK`) into `dest_reg`.
36    SelfPid { dest_reg: u8 },
37    /// `Send` — Atomic Hop to a **capability** target (requires SEND).
38    Send { target_cap: CapId, message: Value },
39    /// `Receive` / `ReceiveTimeout` / `ReceiveMatch` / `ReceiveMatchImm`.
40    Receive {
41        dest_reg: u8,
42        timeout: Option<Duration>,
43        match_tag: Option<u16>,
44    },
45    /// `Ask` / `AskTimeout` — RPC hop to a **capability** target (requires ASK).
46    Ask {
47        dest_reg: u8,
48        target_cap: CapId,
49        request: Value,
50        timeout: Option<Duration>,
51    },
52    /// `Monitor ra, rb` — watch the flow addressed by Cap `r[b]`.
53    Monitor { dest_reg: u8, target_cap: CapId },
54    /// `Demonitor ra` — drop monitor whose ref is `r[a]` (Int).
55    Demonitor { monitor_reg: u8 },
56    /// `Link ra, rb` — bidirectional link with Cap `r[b]`.
57    Link { dest_reg: u8, target_cap: CapId },
58    /// `Unlink ra` — drop link whose id is `r[a]` (Int).
59    Unlink { link_reg: u8 },
60    /// `Delegate ra, rb` — attenuate Cap `r[b]` into `r[a]`.
61    Delegate {
62        dest_reg: u8,
63        src_cap: CapId,
64        want_rights: crate::bytecode::CapRights,
65        want_native_cap: Option<CapId>,
66    },
67    /// A fault occurred; the Flow fails. See [`Fault`].
68    Trap(Fault),
69}