midenc_hir/
locals.rs

1use alloc::alloc::Layout;
2use core::fmt;
3
4use super::Type;
5
6/// A strongly typed identifier for referencing locals associated with a function
7#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
8pub struct LocalId(u16);
9impl LocalId {
10    /// Create a new instance from a `u16`.
11    #[inline]
12    pub fn from_u16(x: u16) -> Self {
13        debug_assert!(x < u16::MAX, "invalid raw local id");
14        Self(x)
15    }
16
17    /// Return the underlying index value as a `usize`.
18    #[inline]
19    pub fn as_usize(self) -> usize {
20        self.0 as usize
21    }
22}
23impl cranelift_entity::EntityRef for LocalId {
24    #[inline]
25    fn new(index: usize) -> Self {
26        debug_assert!(index < (u16::MAX as usize));
27        Self(index as u16)
28    }
29
30    #[inline]
31    fn index(self) -> usize {
32        self.0 as usize
33    }
34}
35impl cranelift_entity::packed_option::ReservedValue for LocalId {
36    #[inline]
37    fn reserved_value() -> LocalId {
38        Self(u16::MAX)
39    }
40
41    #[inline]
42    fn is_reserved_value(&self) -> bool {
43        self.0 == u16::MAX
44    }
45}
46impl fmt::Display for LocalId {
47    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
48        write!(f, "local{}", self.0)
49    }
50}
51impl fmt::Debug for LocalId {
52    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
53        fmt::Display::fmt(&self.0, f)
54    }
55}
56impl From<LocalId> for u16 {
57    #[inline(always)]
58    fn from(id: LocalId) -> Self {
59        id.0
60    }
61}
62impl From<LocalId> for miden_assembly::ast::Immediate<u16> {
63    #[inline(always)]
64    fn from(id: LocalId) -> Self {
65        miden_assembly::ast::Immediate::Value(miden_assembly::Span::unknown(id.0))
66    }
67}
68
69/// Represents a local allocated on the heap statically
70#[derive(Debug, Clone, PartialEq, Eq)]
71pub struct Local {
72    /// The unique identifier associated with this local
73    ///
74    /// It also represents the offset in the set of locals of a function
75    /// where this local will be allocated.
76    ///
77    /// NOTE: If a local's size is larger than a word, multiple consecutive
78    /// local allocations may be made to ensure there is enough memory starting
79    /// at the offset represented by `id` to hold the entire value
80    pub id: LocalId,
81    /// The type of the value stored in this local
82    pub ty: Type,
83}
84impl Local {
85    /// Returns the [Layout] for this local in memory
86    pub fn layout(&self) -> Layout {
87        self.ty.layout()
88    }
89
90    /// Returns the size in bytes for this local, including necessary alignment padding
91    pub fn size_in_bytes(&self) -> usize {
92        self.ty.size_in_bytes()
93    }
94
95    /// Returns the size in words for this local, including necessary alignment padding
96    pub fn size_in_words(&self) -> usize {
97        self.ty.size_in_words()
98    }
99}