Skip to main content

byteflow/jit/
exit.rs

1//! Native exit codes returned by compiled traces.
2
3/// Why a compiled trace stopped.
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub enum ExitReason {
6    /// Keep executing natively at `pc`.
7    Continue { pc: u32 },
8    /// Delegate to the interpreter / scheduler at `pc` (Send, Ask, …).
9    Effect { pc: u32 },
10    /// Outermost `Return` — value lives in `return_reg`.
11    Return { return_reg: u8 },
12    /// Instruction quantum exhausted mid-trace.
13    Budget { pc: u32 },
14    /// Semantic fault (divide-by-zero, explicit trap, …).
15    Trap { pc: u32 },
16    /// Type guard failed — resume in the interpreter.
17    Deopt { pc: u32 },
18}
19
20/// Wire format returned across the native boundary.
21#[repr(C)]
22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
23pub struct JitReturn {
24    pub kind: u32,
25    pub pc: u32,
26    pub return_reg: u32,
27}
28
29pub const JIT_CONTINUE: u32 = 0;
30pub const JIT_EFFECT: u32 = 1;
31pub const JIT_RETURN: u32 = 2;
32pub const JIT_BUDGET: u32 = 3;
33pub const JIT_TRAP: u32 = 4;
34pub const JIT_DEOPT: u32 = 5;
35
36impl JitReturn {
37    pub fn from_reason(reason: ExitReason) -> Self {
38        match reason {
39            ExitReason::Continue { pc } => Self {
40                kind: JIT_CONTINUE,
41                pc,
42                return_reg: 0,
43            },
44            ExitReason::Effect { pc } => Self {
45                kind: JIT_EFFECT,
46                pc,
47                return_reg: 0,
48            },
49            ExitReason::Return { return_reg } => Self {
50                kind: JIT_RETURN,
51                pc: 0,
52                return_reg: u32::from(return_reg),
53            },
54            ExitReason::Budget { pc } => Self {
55                kind: JIT_BUDGET,
56                pc,
57                return_reg: 0,
58            },
59            ExitReason::Trap { pc } => Self {
60                kind: JIT_TRAP,
61                pc,
62                return_reg: 0,
63            },
64            ExitReason::Deopt { pc } => Self {
65                kind: JIT_DEOPT,
66                pc,
67                return_reg: 0,
68            },
69        }
70    }
71
72    pub fn into_reason(self) -> ExitReason {
73        match self.kind {
74            JIT_CONTINUE => ExitReason::Continue { pc: self.pc },
75            JIT_EFFECT => ExitReason::Effect { pc: self.pc },
76            JIT_RETURN => ExitReason::Return {
77                return_reg: self.return_reg as u8,
78            },
79            JIT_BUDGET => ExitReason::Budget { pc: self.pc },
80            JIT_TRAP => ExitReason::Trap { pc: self.pc },
81            JIT_DEOPT => ExitReason::Deopt { pc: self.pc },
82            _ => ExitReason::Deopt { pc: self.pc },
83        }
84    }
85}