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}