Skip to main content

byteflow/vm/
result.rs

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