rune/compile/v1/
linear.rs

1use core::array;
2use core::fmt;
3use core::ops::{Deref, DerefMut};
4use core::slice;
5
6use crate::alloc::{vec, Vec};
7use crate::compile;
8use crate::runtime::InstAddress;
9
10use super::Address;
11
12enum Addresses<'a, 'hir> {
13    Single(Address<'a, 'hir>),
14    List(Vec<Address<'a, 'hir>>),
15}
16
17#[must_use = "This should be freed with a call to Scopes::free_linear"]
18pub(super) struct Linear<'a, 'hir> {
19    addresses: Addresses<'a, 'hir>,
20}
21
22impl<'a, 'hir> Linear<'a, 'hir> {
23    /// Construct a new linear address space.
24    pub(super) fn new(list: Vec<Address<'a, 'hir>>) -> Self {
25        Self {
26            addresses: Addresses::List(list),
27        }
28    }
29
30    /// Construct an empty linear allocation.
31    pub(super) const fn empty() -> Self {
32        Self {
33            addresses: Addresses::List(Vec::new()),
34        }
35    }
36
37    /// Represent a single address.
38    pub(super) fn single(address: Address<'a, 'hir>) -> Self {
39        Self {
40            addresses: Addresses::Single(address),
41        }
42    }
43
44    #[inline]
45    pub(super) fn addr(&self) -> InstAddress {
46        match &self.addresses {
47            Addresses::Single(address) => address.addr(),
48            Addresses::List(list) => list.first().map_or(InstAddress::INVALID, Address::addr),
49        }
50    }
51
52    #[inline]
53    pub(super) fn iter(&self) -> slice::Iter<'_, Address<'a, 'hir>> {
54        <[_]>::iter(self)
55    }
56
57    #[inline]
58    pub(super) fn iter_mut(&mut self) -> slice::IterMut<'_, Address<'a, 'hir>> {
59        <[_]>::iter_mut(self)
60    }
61
62    #[inline]
63    pub(super) fn free(self) -> compile::Result<()> {
64        for addr in self.into_iter().rev() {
65            addr.free()?;
66        }
67
68        Ok(())
69    }
70
71    #[inline]
72    pub(super) fn free_non_dangling(self) -> compile::Result<()> {
73        for addr in self.into_iter().rev() {
74            addr.free_non_dangling()?;
75        }
76
77        Ok(())
78    }
79
80    #[inline]
81    pub(super) fn forget(self) -> compile::Result<()> {
82        for var in self {
83            var.forget()?;
84        }
85
86        Ok(())
87    }
88}
89
90impl<'b, 'a, 'hir> IntoIterator for &'b Linear<'a, 'hir> {
91    type Item = &'b Address<'a, 'hir>;
92    type IntoIter = slice::Iter<'b, Address<'a, 'hir>>;
93
94    #[inline]
95    fn into_iter(self) -> Self::IntoIter {
96        self.iter()
97    }
98}
99
100impl<'b, 'a, 'hir> IntoIterator for &'b mut Linear<'a, 'hir> {
101    type Item = &'b mut Address<'a, 'hir>;
102    type IntoIter = slice::IterMut<'b, Address<'a, 'hir>>;
103
104    #[inline]
105    fn into_iter(self) -> Self::IntoIter {
106        self.iter_mut()
107    }
108}
109
110impl<'a, 'hir> Deref for Linear<'a, 'hir> {
111    type Target = [Address<'a, 'hir>];
112
113    #[inline]
114    fn deref(&self) -> &Self::Target {
115        match &self.addresses {
116            Addresses::Single(address) => slice::from_ref(address),
117            Addresses::List(list) => list,
118        }
119    }
120}
121
122impl DerefMut for Linear<'_, '_> {
123    #[inline]
124    fn deref_mut(&mut self) -> &mut Self::Target {
125        match &mut self.addresses {
126            Addresses::Single(address) => slice::from_mut(address),
127            Addresses::List(list) => list,
128        }
129    }
130}
131
132impl fmt::Debug for Linear<'_, '_> {
133    #[inline]
134    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135        f.debug_list().entries(self.iter()).finish()
136    }
137}
138
139impl<'a, 'hir> IntoIterator for Linear<'a, 'hir> {
140    type Item = Address<'a, 'hir>;
141    type IntoIter = IntoIter<'a, 'hir>;
142
143    #[inline]
144    fn into_iter(self) -> Self::IntoIter {
145        IntoIter {
146            inner: match self.addresses {
147                Addresses::Single(address) => IntoIterRepr::Single([address].into_iter()),
148                Addresses::List(list) => IntoIterRepr::Vec(list.into_iter()),
149            },
150        }
151    }
152}
153
154enum IntoIterRepr<'a, 'hir> {
155    Vec(vec::IntoIter<Address<'a, 'hir>>),
156    Single(array::IntoIter<Address<'a, 'hir>, 1>),
157}
158
159pub(super) struct IntoIter<'a, 'hir> {
160    inner: IntoIterRepr<'a, 'hir>,
161}
162
163impl<'a, 'hir> Iterator for IntoIter<'a, 'hir> {
164    type Item = Address<'a, 'hir>;
165
166    #[inline]
167    fn next(&mut self) -> Option<Self::Item> {
168        match &mut self.inner {
169            IntoIterRepr::Vec(iter) => iter.next(),
170            IntoIterRepr::Single(iter) => iter.next(),
171        }
172    }
173}
174
175impl ExactSizeIterator for IntoIter<'_, '_> {
176    #[inline]
177    fn len(&self) -> usize {
178        match &self.inner {
179            IntoIterRepr::Vec(iter) => iter.len(),
180            IntoIterRepr::Single(iter) => iter.len(),
181        }
182    }
183}
184
185impl DoubleEndedIterator for IntoIter<'_, '_> {
186    #[inline]
187    fn next_back(&mut self) -> Option<Self::Item> {
188        match &mut self.inner {
189            IntoIterRepr::Vec(iter) => iter.next_back(),
190            IntoIterRepr::Single(iter) => iter.next_back(),
191        }
192    }
193}