byteflow/vm/result.rs
1use std::time::Duration;
2
3use crate::bytecode::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 },
34 /// `SelfPid` — write a **self Cap** (`SEND|ASK`) into `dest_reg`.
35 SelfPid { dest_reg: u8 },
36 /// `Send` — Atomic Hop to a **capability** target (requires SEND).
37 Send { target_cap: u64, message: Value },
38 /// `Receive` / `ReceiveTimeout` / `ReceiveMatch` / `ReceiveMatchImm`.
39 Receive {
40 dest_reg: u8,
41 timeout: Option<Duration>,
42 match_tag: Option<u16>,
43 },
44 /// `Ask` — RPC hop to a **capability** target (requires ASK).
45 Ask {
46 dest_reg: u8,
47 target_cap: u64,
48 request: Value,
49 },
50 /// A fault occurred; the Flow fails. See [`Fault`].
51 Trap(Fault),
52}