1use super::*;
2
3#[derive(Debug, Clone, PartialEq)]
4pub enum VmResult {
5 Value(VmValue),
6 Request(VmRequest),
7}
8
9#[derive(Debug, Clone, PartialEq)]
10pub enum VmValue {
11 Int(String),
12 Float(String),
13 String(StringTree),
14 Bytes(BytesTree),
15 Path(Rc<PathBuf>),
16 Bool(bool),
17 Unit,
18 List(ListTree<Rc<VmValue>>),
19 Tuple(Vec<VmValue>),
20 Record(BTreeMap<typed_ir::Name, VmValue>),
21 Variant {
22 tag: typed_ir::Name,
23 value: Option<Box<VmValue>>,
24 },
25 EffectOp(typed_ir::Path),
26 PrimitiveOp(Rc<VmPrimitive>),
27 Resume(Rc<VmResume>),
28 Closure(Rc<VmClosure>),
29 Thunk(Rc<VmThunk>),
30 EffectId(u64),
31}
32
33#[derive(Debug, Clone, PartialEq)]
34pub struct VmRequest {
35 pub effect: typed_ir::Path,
36 pub payload: VmValue,
37 pub continuation: VmContinuation,
38 pub blocked_id: Option<u64>,
39}
40
41#[derive(Debug, Clone, PartialEq)]
42pub struct VmPrimitive {
43 pub op: typed_ir::PrimitiveOp,
44 pub args: Vec<VmValue>,
45}
46
47#[derive(Debug, Clone, PartialEq)]
48pub struct VmClosure {
49 pub(super) param: typed_ir::Name,
50 pub(super) param_ty: Type,
51 pub(super) body: Expr,
52 pub(super) ret: Type,
53 pub(super) env: Env,
54 pub(super) guard_stack: GuardStack,
55 pub(super) self_name: Option<typed_ir::Path>,
56}
57
58#[derive(Debug, Clone, PartialEq)]
59pub struct VmThunk {
60 pub(super) body: ThunkBody,
61 pub(super) env: Env,
62 pub(super) guard_stack: GuardStack,
63 pub(super) blocked: Vec<BlockedEffect>,
64}
65
66#[derive(Debug, Clone, PartialEq)]
67pub(super) enum ThunkBody {
68 Value(VmValue),
69 Expr(Expr),
70 Emit {
71 effect: typed_ir::Path,
72 payload: VmValue,
73 },
74}
75
76#[derive(Debug, Clone, PartialEq)]
77pub struct VmResume {
78 pub(super) continuation: VmContinuation,
79}
80
81#[derive(Debug, Clone, PartialEq, Default)]
82pub struct VmContinuation {
83 pub(super) frames: Vec<Frame>,
84 pub(super) guard_stack: GuardStack,
85}
86
87#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
88pub struct VmProfile {
89 pub eval_expr_calls: usize,
90 pub max_eval_depth: usize,
91 pub continuation_steps: usize,
92 pub max_continuation_frames: usize,
93}
94
95impl VmProfile {
96 pub fn merge(&mut self, other: Self) {
97 self.eval_expr_calls += other.eval_expr_calls;
98 self.max_eval_depth = self.max_eval_depth.max(other.max_eval_depth);
99 self.continuation_steps += other.continuation_steps;
100 self.max_continuation_frames = self
101 .max_continuation_frames
102 .max(other.max_continuation_frames);
103 }
104}
105
106#[derive(Debug, Clone, PartialEq, Eq, Default)]
107pub(super) struct GuardStack(pub(super) PersistentVector<GuardEntry>);
108
109#[derive(Debug, Clone, PartialEq, Eq)]
110pub(super) struct PersistentVector<T> {
111 pub(super) len: usize,
112 pub(super) tail: Option<Rc<PersistentVectorChunk<T>>>,
113}
114
115#[derive(Debug, Clone, Copy, PartialEq, Eq)]
116pub(super) struct GuardEntry {
117 pub(super) var: EffectIdVar,
118 pub(super) id: u64,
119}
120
121#[derive(Debug, Clone, PartialEq, Eq)]
122pub(super) struct PersistentVectorChunk<T> {
123 pub(super) items: Rc<[T]>,
124 pub(super) parent: Option<Rc<PersistentVectorChunk<T>>>,
125}
126
127#[derive(Debug, Clone, PartialEq)]
128pub(super) struct BlockedEffect {
129 pub(super) guard_id: u64,
130 pub(super) allowed: typed_ir::Type,
131 pub(super) active: bool,
132}
133
134#[derive(Debug, Clone, PartialEq)]
135pub(super) enum Frame {
136 BindHere,
137 ApplyCallee {
138 arg: Expr,
139 env: Env,
140 delay_arg: bool,
141 },
142 ApplyArg {
143 callee: VmValue,
144 },
145 If {
146 then_branch: Expr,
147 else_branch: Expr,
148 env: Env,
149 },
150 Tuple {
151 done: Vec<VmValue>,
152 remaining: Vec<Expr>,
153 env: Env,
154 },
155 Select {
156 field: typed_ir::Name,
157 },
158 Match {
159 arms: Vec<MatchArm>,
160 env: Env,
161 },
162 BlockLet {
163 pattern: Pattern,
164 remaining: Vec<Stmt>,
165 tail: Option<Expr>,
166 env: Env,
167 },
168 BlockExpr {
169 remaining: Vec<Stmt>,
170 tail: Option<Expr>,
171 env: Env,
172 },
173 Handle {
174 id: u64,
175 arms: Vec<HandleArm>,
176 env: Env,
177 guard_stack: GuardStack,
178 expected_ty: Type,
179 },
180 HandleGuard {
181 id: u64,
182 request: VmRequest,
183 outer: VmContinuation,
184 handler_guard_stack: GuardStack,
185 arms: Vec<HandleArm>,
186 env: Env,
187 arm_env: Env,
188 body: Expr,
189 expected_ty: Type,
190 },
191 LocalPushId {
192 parent: GuardStack,
193 },
194 BlockedEffects {
195 blocked: Vec<BlockedEffect>,
196 active: bool,
197 },
198 Coerce {
199 to: typed_ir::Type,
200 },
201 WrapThunkResult {
202 expected_ty: Type,
203 },
204}
205
206pub(super) type Env = HashMap<typed_ir::Path, VmValue>;