wasm/core/structure/modules/
indices.rs1use alloc::{boxed::Box, vec::Vec};
34use core::marker::PhantomData;
35
36use crate::core::utils::ToUsizeExt;
37
38pub trait Idx: Copy + core::fmt::Debug + core::fmt::Display + Eq {
42 fn new(index: u32) -> Self;
43
44 fn into_inner(self) -> u32;
45}
46
47pub struct IdxVec<I: Idx, T> {
51 inner: Box<[T]>,
52 _phantom: PhantomData<I>,
53}
54
55impl<I: Idx, T> Default for IdxVec<I, T> {
56 fn default() -> Self {
57 Self {
58 inner: Box::default(),
59 _phantom: PhantomData,
60 }
61 }
62}
63
64impl<I: Idx, T: Clone> Clone for IdxVec<I, T> {
65 fn clone(&self) -> Self {
66 Self {
67 inner: self.inner.clone(),
68 _phantom: PhantomData,
69 }
70 }
71}
72
73impl<I: Idx, T: core::fmt::Debug> core::fmt::Debug for IdxVec<I, T> {
74 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
75 f.debug_list().entries(&*self.inner).finish()
76 }
77}
78
79#[derive(Debug)]
81pub struct IdxVecOverflowError;
82
83impl<I: Idx, T> IdxVec<I, T> {
84 pub fn new(elements: Vec<T>) -> Result<Self, IdxVecOverflowError> {
89 if u32::try_from(elements.len()).is_err() {
90 return Err(IdxVecOverflowError);
91 }
92
93 Ok(Self {
94 inner: elements.into_boxed_slice(),
95 _phantom: PhantomData,
96 })
97 }
98
99 pub(crate) fn validate_index(&self, index: u32) -> Option<I> {
100 let index_as_usize = index.into_usize();
101 let _element = self.inner.get(index_as_usize)?;
102 Some(I::new(index))
103 }
104
105 pub unsafe fn get(&self, index: I) -> &T {
113 let index = index.into_inner().into_usize();
114
115 self.inner
118 .get(index)
119 .expect("this to be a valid index due to the safety guarantees made by the caller")
120 }
121
122 #[allow(unused)] pub fn len(&self) -> u32 {
124 u32::try_from(self.inner.len()).expect(
125 "this to never be larger than u32::MAX, because this was checked for in Self::new",
126 )
127 }
128
129 pub fn iter_enumerated(&self) -> impl Iterator<Item = (I, &T)> {
130 self.inner.iter().enumerate().map(|(index, t)| {
131 (
132 I::new(
133 u32::try_from(index)
134 .expect("this vector to contain a maximum of 2^32-1 elements"),
135 ),
136 t,
137 )
138 })
139 }
140
141 pub fn map<R, E>(&self, mapper: impl FnMut(&T) -> Result<R, E>) -> Result<IdxVec<I, R>, E> {
144 Ok(IdxVec {
145 inner: self
146 .inner
147 .iter()
148 .map(mapper)
149 .collect::<Result<Box<[R]>, E>>()?,
150 _phantom: PhantomData,
151 })
152 }
153}
154
155#[derive(Debug)]
157pub struct ExtendedIdxVec<I: Idx, T> {
158 inner: IdxVec<I, T>,
159 num_imports: u32,
160}
161
162impl<I: Idx, T> Default for ExtendedIdxVec<I, T> {
163 fn default() -> Self {
164 Self {
165 inner: IdxVec::default(),
166 num_imports: 0,
167 }
168 }
169}
170
171impl<I: Idx, T: Clone> Clone for ExtendedIdxVec<I, T> {
172 fn clone(&self) -> Self {
173 Self {
174 inner: self.inner.clone(),
175 num_imports: self.num_imports,
176 }
177 }
178}
179
180impl<I: Idx, T> ExtendedIdxVec<I, T> {
181 pub fn new(imports: Vec<T>, locals: Vec<T>) -> Result<Self, IdxVecOverflowError> {
187 let num_imports = u32::try_from(imports.len()).map_err(|_| IdxVecOverflowError)?;
188
189 let mut combined = imports;
190 combined.extend(locals);
191
192 Ok(Self {
193 inner: IdxVec::new(combined)?,
194 num_imports,
195 })
196 }
197
198 pub fn len_local_definitions(&self) -> u32 {
201 self.inner
202 .len()
203 .checked_sub(self.num_imports)
204 .expect("that the number of imports is never larger than the total length of self")
205 }
206
207 pub fn map<R>(
213 &self,
214 new_imported_definitions: Vec<R>,
215 new_local_definitions: Vec<R>,
216 ) -> Option<ExtendedIdxVec<I, R>> {
217 if new_imported_definitions.len() != self.num_imports.into_usize()
218 || u32::try_from(new_local_definitions.len()).ok()? != self.len_local_definitions()
219 {
220 return None;
221 }
222
223 Some(
224 ExtendedIdxVec::new(new_imported_definitions, new_local_definitions)
225 .expect("no overflow can happen because the length did not change"),
226 )
227 }
228
229 pub fn iter_local_definitions(&self) -> core::slice::Iter<'_, T> {
230 self.inner
231 .inner
232 .get(self.num_imports.into_usize()..)
233 .expect("the imports length to never be larger than the total length")
234 .iter()
235 }
236
237 pub fn inner(&self) -> &IdxVec<I, T> {
238 &self.inner
239 }
240
241 pub fn into_inner(self) -> IdxVec<I, T> {
242 self.inner
243 }
244}
245
246#[derive(Copy, Clone, Debug, PartialEq, Eq)]
254pub struct TypeIdx(u32);
255
256impl core::fmt::Display for TypeIdx {
257 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
258 write!(f, "type index {}", self.0)
259 }
260}
261
262impl Idx for TypeIdx {
263 fn new(index: u32) -> Self {
264 Self(index)
265 }
266
267 fn into_inner(self) -> u32 {
268 self.0
269 }
270}
271
272impl TypeIdx {
273 pub fn new(index: u32) -> Self {
278 Self(index)
279 }
280}
281
282#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
283pub struct FuncIdx(u32);
284
285impl core::fmt::Display for FuncIdx {
286 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
287 write!(f, "function index {}", self.0)
288 }
289}
290
291impl Idx for FuncIdx {
292 fn new(index: u32) -> Self {
293 Self(index)
294 }
295
296 fn into_inner(self) -> u32 {
297 self.0
298 }
299}
300
301#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
302pub struct TableIdx(u32);
303
304impl core::fmt::Display for TableIdx {
305 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
306 write!(f, "table index {}", self.0)
307 }
308}
309
310impl Idx for TableIdx {
311 fn new(index: u32) -> Self {
312 Self(index)
313 }
314
315 fn into_inner(self) -> u32 {
316 self.0
317 }
318}
319
320#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
321pub struct MemIdx(u32);
322
323impl core::fmt::Display for MemIdx {
324 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
325 write!(f, "memory index {}", self.0)
326 }
327}
328
329impl Idx for MemIdx {
330 fn new(index: u32) -> Self {
331 Self(index)
332 }
333
334 fn into_inner(self) -> u32 {
335 self.0
336 }
337}
338
339#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
340pub struct GlobalIdx(u32);
341
342impl core::fmt::Display for GlobalIdx {
343 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
344 write!(f, "global index {}", self.0)
345 }
346}
347
348impl Idx for GlobalIdx {
349 fn new(index: u32) -> Self {
350 Self(index)
351 }
352
353 fn into_inner(self) -> u32 {
354 self.0
355 }
356}
357
358#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
359pub struct ElemIdx(u32);
360
361impl core::fmt::Display for ElemIdx {
362 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
363 write!(f, "element index {}", self.0)
364 }
365}
366
367impl Idx for ElemIdx {
368 fn new(index: u32) -> Self {
369 Self(index)
370 }
371
372 fn into_inner(self) -> u32 {
373 self.0
374 }
375}
376
377#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
378pub struct DataIdx(u32);
379
380impl core::fmt::Display for DataIdx {
381 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
382 write!(f, "data index {}", self.0)
383 }
384}
385
386impl Idx for DataIdx {
387 fn new(index: u32) -> Self {
388 Self(index)
389 }
390
391 fn into_inner(self) -> u32 {
392 self.0
393 }
394}
395
396#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
397pub struct LocalIdx(pub(crate) u32);
398
399impl core::fmt::Display for LocalIdx {
400 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
401 write!(f, "local index {}", self.0)
402 }
403}
404
405impl LocalIdx {
406 pub fn into_inner(self) -> u32 {
407 self.0
408 }
409}