ruka_mir/
instr.rs

1use crate::{MirAggregateArg, MirCallArg, MirFuncId, MirIntrinsic, MirLocalId};
2
3/// Source position metadata captured for MIR instructions.
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub struct MirSourcePos {
6    /// Source file identifier assigned during parsing.
7    pub file_id: u32,
8    /// 1-based source line number.
9    pub line: u32,
10    /// 1-based source column number.
11    pub column: u32,
12}
13
14/// MIR instruction set used by lowering and codegen.
15///
16/// This is the canonical instruction representation stored in blocks.
17#[derive(Debug, Clone)]
18pub enum MirInstr {
19    /// Write unit constant into `dst`.
20    ConstUnit {
21        /// Destination local receiving the unit constant.
22        /// Destination local receiving the result.
23        dst: MirLocalId,
24    },
25    /// Write integer constant into `dst`.
26    ConstInt {
27        /// Destination local receiving the integer constant.
28        /// Destination local receiving the result.
29        dst: MirLocalId,
30        /// Constant integer value.
31        value: i64,
32    },
33    /// Write floating-point constant into `dst`.
34    ConstFloat {
35        /// Destination local receiving the floating-point constant.
36        dst: MirLocalId,
37        /// Constant floating-point value.
38        value: f64,
39    },
40    /// Write string constant into `dst`.
41    ConstString {
42        /// Destination local receiving the string constant.
43        /// Destination local receiving the result.
44        dst: MirLocalId,
45        /// Constant string contents.
46        value: String,
47    },
48    /// Write boolean constant into `dst`.
49    ConstBool {
50        /// Destination local receiving the boolean constant.
51        /// Destination local receiving the result.
52        dst: MirLocalId,
53        /// Constant boolean value.
54        value: bool,
55    },
56    /// Write null pointer constant into `dst`.
57    ConstNull {
58        /// Destination local receiving the null pointer value.
59        /// Destination local receiving the result.
60        dst: MirLocalId,
61    },
62    /// Allocate pointer payload and wrap in nullable handle.
63    PointerNew {
64        /// Source local providing the pointee value.
65        /// Source local supplying the stored value.
66        src: MirLocalId,
67        /// Destination local receiving the pointer handle.
68        /// Destination local receiving the result.
69        dst: MirLocalId,
70    },
71    /// Build array literal from `items` into `dst`.
72    MakeArray {
73        /// Aggregate arguments used to build the array.
74        items: Vec<MirAggregateArg>,
75        /// Destination local receiving the result.
76        dst: MirLocalId,
77        /// Optional source position for the allocation site.
78        source_pos: Option<MirSourcePos>,
79    },
80    /// Build tuple literal from `items` into `dst`.
81    MakeTuple {
82        /// Aggregate arguments used to build the tuple.
83        items: Vec<MirAggregateArg>,
84        /// Destination local receiving the result.
85        dst: MirLocalId,
86        /// Optional source position for the allocation site.
87        source_pos: Option<MirSourcePos>,
88    },
89    /// Build struct literal value.
90    MakeStruct {
91        /// Struct constructor name to instantiate.
92        name: String,
93        /// Field values keyed by field name.
94        fields: Vec<(String, MirLocalId)>,
95        /// Destination local receiving the result.
96        dst: MirLocalId,
97        /// Optional source position for the allocation site.
98        source_pos: Option<MirSourcePos>,
99    },
100    /// Build enum literal value.
101    MakeEnum {
102        /// Enum constructor name to instantiate.
103        enum_name: String,
104        /// Variant constructor name to instantiate.
105        variant: String,
106        /// Variant payload argument values.
107        payload: Vec<MirAggregateArg>,
108        /// Destination local receiving the result.
109        dst: MirLocalId,
110        /// Optional source position for the allocation site.
111        source_pos: Option<MirSourcePos>,
112    },
113    /// Read field from struct value.
114    ReadField {
115        /// Base local supplying the aggregate value.
116        base: MirLocalId,
117        /// Field name being read from the aggregate.
118        field: String,
119        /// Destination local receiving the result.
120        dst: MirLocalId,
121    },
122    /// Borrow struct/tuple field read-only.
123    FieldBorrowRo {
124        /// Base local supplying the aggregate value.
125        base: MirLocalId,
126        /// Field name being borrowed from the aggregate.
127        field: String,
128        /// Destination local receiving the result.
129        dst: MirLocalId,
130    },
131    /// Borrow struct/tuple field mutably.
132    FieldBorrowMut {
133        /// Base local supplying the aggregate value.
134        base: MirLocalId,
135        /// Field name being borrowed from the aggregate.
136        field: String,
137        /// Destination local receiving the result.
138        dst: MirLocalId,
139    },
140    /// Test whether enum value currently stores a specific variant.
141    EnumIsVariant {
142        /// Enum local being inspected.
143        value: MirLocalId,
144        /// Enum constructor name being tested.
145        enum_name: String,
146        /// Variant constructor name being tested.
147        variant: String,
148        /// Number of payload fields declared on the tested variant.
149        payload_len: usize,
150        /// Destination local receiving the result.
151        dst: MirLocalId,
152    },
153    /// Extract one enum payload field by variant/index.
154    EnumGetField {
155        /// Enum local being inspected.
156        value: MirLocalId,
157        /// Enum constructor name being extracted from.
158        enum_name: String,
159        /// Variant constructor name being extracted from.
160        variant: String,
161        /// Payload field index within the variant.
162        index: usize,
163        /// Destination local receiving the extracted field.
164        dst: MirLocalId,
165    },
166    /// Logical copy from `src` into `dst`.
167    Copy {
168        /// Source local being copied.
169        /// Source local supplying the stored value.
170        src: MirLocalId,
171        /// Destination local receiving the copied value.
172        dst: MirLocalId,
173    },
174    /// Ownership move from `src` into `dst`.
175    Move {
176        /// Source local being moved.
177        /// Source local supplying the stored value.
178        src: MirLocalId,
179        /// Destination local receiving the moved value.
180        dst: MirLocalId,
181    },
182    /// Assign local storage from `src` into `dst`.
183    AssignLocal {
184        /// Source local being assigned from.
185        /// Source local supplying the stored value.
186        src: MirLocalId,
187        /// Destination local being assigned to.
188        dst: MirLocalId,
189    },
190    /// Store value through mutable reference local.
191    StoreRef {
192        /// Source local supplying the stored value.
193        src: MirLocalId,
194        /// Destination mutable reference local.
195        dst_ref: MirLocalId,
196    },
197    /// Assign through a struct field path rooted at `base`.
198    AssignFieldPath {
199        /// Base local supplying the aggregate value.
200        base: MirLocalId,
201        /// Field path traversed from the base local.
202        fields: Vec<String>,
203        /// Source local supplying the stored value.
204        src: MirLocalId,
205    },
206    /// Release one retained heap ownership for `local`.
207    ///
208    /// Lowering defines this instruction now so later ownership passes can
209    /// place releases explicitly without changing MIR shape again.
210    ReleaseHeap {
211        /// Local whose heap ownership should be released.
212        local: MirLocalId,
213    },
214    /// Internal function call.
215    Call {
216        /// Function id of the callee.
217        callee: MirFuncId,
218        /// Positional call arguments.
219        args: Vec<MirCallArg>,
220        /// Destination local receiving the result.
221        dst: MirLocalId,
222    },
223    /// Extern/runtime symbol call.
224    CallExtern {
225        /// Canonical symbol name of the extern/runtime function.
226        symbol: String,
227        /// Positional call arguments.
228        args: Vec<MirCallArg>,
229        /// Destination local receiving the result.
230        dst: MirLocalId,
231    },
232    /// Builtin intrinsic call.
233    CallIntrinsic {
234        /// Intrinsic to invoke.
235        intrinsic: MirIntrinsic,
236        /// Positional call arguments.
237        args: Vec<MirCallArg>,
238        /// Destination local receiving the result.
239        dst: MirLocalId,
240        /// Optional source position for the call site.
241        source_pos: Option<MirSourcePos>,
242    },
243    /// Collection length query.
244    CollectionLen {
245        /// Collection local being queried or borrowed from.
246        collection: MirLocalId,
247        /// Destination local receiving the result.
248        dst: MirLocalId,
249    },
250    /// Borrow collection element read-only.
251    IndexBorrowRo {
252        /// Collection local being queried or borrowed from.
253        collection: MirLocalId,
254        /// Index local selecting an element.
255        index: MirLocalId,
256        /// Destination local receiving the result.
257        dst: MirLocalId,
258    },
259    /// Borrow collection element mutably.
260    IndexBorrowMut {
261        /// Collection local being queried or borrowed from.
262        collection: MirLocalId,
263        /// Index local selecting an element.
264        index: MirLocalId,
265        /// Destination local receiving the result.
266        dst: MirLocalId,
267    },
268    /// Borrow collection range read-only as a slice.
269    SliceBorrowRo {
270        /// Collection local being queried or borrowed from.
271        collection: MirLocalId,
272        /// Optional start bound local.
273        start: Option<MirLocalId>,
274        /// Optional end bound local.
275        end: Option<MirLocalId>,
276        /// Destination local receiving the result.
277        dst: MirLocalId,
278    },
279    /// Borrow collection range mutably as a slice.
280    SliceBorrowMut {
281        /// Collection local being queried or borrowed from.
282        collection: MirLocalId,
283        /// Optional start bound local.
284        start: Option<MirLocalId>,
285        /// Optional end bound local.
286        end: Option<MirLocalId>,
287        /// Destination local receiving the result.
288        dst: MirLocalId,
289    },
290    /// Test whether nullable pointer is non-null.
291    PointerIsSome {
292        /// Pointer local being inspected or borrowed from.
293        pointer: MirLocalId,
294        /// Destination local receiving the result.
295        dst: MirLocalId,
296    },
297    /// Borrow nullable pointer payload read-only.
298    PointerBorrowRo {
299        /// Pointer local being inspected or borrowed from.
300        pointer: MirLocalId,
301        /// Destination local receiving the result.
302        dst: MirLocalId,
303    },
304    /// Borrow nullable pointer payload mutably.
305    PointerBorrowMut {
306        /// Pointer local being inspected or borrowed from.
307        pointer: MirLocalId,
308        /// Destination local receiving the result.
309        dst: MirLocalId,
310    },
311    /// Copy value from a reference local.
312    DerefCopy {
313        /// Source reference local being dereferenced.
314        src: MirLocalId,
315        /// Destination local receiving the copied value.
316        dst: MirLocalId,
317    },
318    /// Numeric value cast to another scalar numeric type.
319    NumCast {
320        /// Source local supplying the input value.
321        src: MirLocalId,
322        /// Destination local receiving the cast result.
323        dst: MirLocalId,
324    },
325    /// Checked integer cast that traps when value does not fit destination range.
326    CheckedIntCast {
327        /// Source local supplying the input value.
328        src: MirLocalId,
329        /// Destination local receiving the cast result.
330        dst: MirLocalId,
331    },
332    /// Integer less-than comparison.
333    IntLt {
334        /// Left-hand operand local.
335        lhs: MirLocalId,
336        /// Right-hand operand local.
337        rhs: MirLocalId,
338        /// Destination local receiving the result.
339        dst: MirLocalId,
340    },
341    /// Integer greater-than comparison.
342    IntGt {
343        /// Left-hand operand local.
344        lhs: MirLocalId,
345        /// Right-hand operand local.
346        rhs: MirLocalId,
347        /// Destination local receiving the result.
348        dst: MirLocalId,
349    },
350    /// Integer less-than-or-equal comparison.
351    IntLtEq {
352        /// Left-hand operand local.
353        lhs: MirLocalId,
354        /// Right-hand operand local.
355        rhs: MirLocalId,
356        /// Destination local receiving the result.
357        dst: MirLocalId,
358    },
359    /// Integer greater-than-or-equal comparison.
360    IntGtEq {
361        /// Left-hand operand local.
362        lhs: MirLocalId,
363        /// Right-hand operand local.
364        rhs: MirLocalId,
365        /// Destination local receiving the result.
366        dst: MirLocalId,
367    },
368    /// Integer equality comparison.
369    IntEq {
370        /// Left-hand operand local.
371        lhs: MirLocalId,
372        /// Right-hand operand local.
373        rhs: MirLocalId,
374        /// Destination local receiving the result.
375        dst: MirLocalId,
376    },
377    /// Integer inequality comparison.
378    IntNeq {
379        /// Left-hand operand local.
380        lhs: MirLocalId,
381        /// Right-hand operand local.
382        rhs: MirLocalId,
383        /// Destination local receiving the result.
384        dst: MirLocalId,
385    },
386    /// Integer addition.
387    IntAdd {
388        /// Left-hand operand local.
389        lhs: MirLocalId,
390        /// Right-hand operand local.
391        rhs: MirLocalId,
392        /// Destination local receiving the result.
393        dst: MirLocalId,
394    },
395    /// Integer subtraction.
396    IntSub {
397        /// Left-hand operand local.
398        lhs: MirLocalId,
399        /// Right-hand operand local.
400        rhs: MirLocalId,
401        /// Destination local receiving the result.
402        dst: MirLocalId,
403    },
404    /// Integer multiplication.
405    IntMul {
406        /// Left-hand operand local.
407        lhs: MirLocalId,
408        /// Right-hand operand local.
409        rhs: MirLocalId,
410        /// Destination local receiving the result.
411        dst: MirLocalId,
412    },
413    /// Integer division.
414    IntDiv {
415        /// Left-hand operand local.
416        lhs: MirLocalId,
417        /// Right-hand operand local.
418        rhs: MirLocalId,
419        /// Destination local receiving the result.
420        dst: MirLocalId,
421    },
422    /// Integer modulo.
423    IntMod {
424        /// Left-hand operand local.
425        lhs: MirLocalId,
426        /// Right-hand operand local.
427        rhs: MirLocalId,
428        /// Destination local receiving the result.
429        dst: MirLocalId,
430    },
431}
432
433/// Structured lowering helper form.
434///
435/// This is used while constructing CFG and is not stored as the
436/// canonical body representation in [`MirFunction`](crate::MirFunction).
437#[derive(Debug, Clone)]
438pub enum MirStmt {
439    /// Plain instruction embedded in structured lowering output.
440    Instr(MirInstr),
441    /// Structured conditional used during CFG construction.
442    If {
443        /// Local id holding the branch condition.
444        cond: MirLocalId,
445        /// Structured statements executed on the then path.
446        then_body: Vec<MirStmt>,
447        /// Structured statements executed on the else path.
448        else_body: Vec<MirStmt>,
449    },
450    /// Structured loop used during CFG construction.
451    While {
452        /// Loop-carried parameter locals.
453        loop_params: Vec<MirLocalId>,
454        /// Initial arguments supplied to the loop.
455        init_args: Vec<MirLocalId>,
456        /// Structured statements computing the loop condition.
457        cond_body: Vec<MirStmt>,
458        /// Local id holding the branch condition.
459        cond: MirLocalId,
460        /// Structured statements in the loop body.
461        body: Vec<MirStmt>,
462        /// Updated loop arguments supplied to the next iteration.
463        step_args: Vec<MirLocalId>,
464    },
465    /// Structured return used during CFG construction.
466    Return {
467        /// Local id returned from the surrounding function.
468        value: MirLocalId,
469    },
470}