1use core::marker::PhantomData;
34
35use alloc::{boxed::Box, vec::Vec};
36
37use crate::{
38 core::{
39 error::DecodingError,
40 reader::{types::FuncType, WasmReader},
41 utils::ToUsizeExt,
42 },
43 ValType, ValidationError,
44};
45
46pub trait Idx: Copy + core::fmt::Debug + core::fmt::Display + Eq {
50 fn new(index: u32) -> Self;
51
52 fn into_inner(self) -> u32;
53}
54
55pub struct IdxVec<I: Idx, T> {
59 inner: Box<[T]>,
60 _phantom: PhantomData<I>,
61}
62
63impl<I: Idx, T> Default for IdxVec<I, T> {
64 fn default() -> Self {
65 Self {
66 inner: Box::default(),
67 _phantom: PhantomData,
68 }
69 }
70}
71
72impl<I: Idx, T: Clone> Clone for IdxVec<I, T> {
73 fn clone(&self) -> Self {
74 Self {
75 inner: self.inner.clone(),
76 _phantom: PhantomData,
77 }
78 }
79}
80
81impl<I: Idx, T: core::fmt::Debug> core::fmt::Debug for IdxVec<I, T> {
82 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
83 f.debug_list().entries(&*self.inner).finish()
84 }
85}
86
87#[derive(Debug)]
89pub struct IdxVecOverflowError;
90
91impl<I: Idx, T> IdxVec<I, T> {
92 pub fn new(elements: Vec<T>) -> Result<Self, IdxVecOverflowError> {
97 if u32::try_from(elements.len()).is_err() {
98 return Err(IdxVecOverflowError);
99 }
100
101 Ok(Self {
102 inner: elements.into_boxed_slice(),
103 _phantom: PhantomData,
104 })
105 }
106
107 fn validate_index(&self, index: u32) -> Option<I> {
108 let index_as_usize = index.into_usize();
109 let _element = self.inner.get(index_as_usize)?;
110 Some(I::new(index))
111 }
112
113 pub unsafe fn get(&self, index: I) -> &T {
121 let index = index.into_inner().into_usize();
122
123 self.inner
126 .get(index)
127 .expect("this to be a valid index due to the safety guarantees made by the caller")
128 }
129
130 #[allow(unused)] pub fn len(&self) -> u32 {
132 u32::try_from(self.inner.len()).expect(
133 "this to never be larger than u32::MAX, because this was checked for in Self::new",
134 )
135 }
136
137 pub fn iter_enumerated(&self) -> impl Iterator<Item = (I, &T)> {
138 self.inner.iter().enumerate().map(|(index, t)| {
139 (
140 I::new(
141 u32::try_from(index)
142 .expect("this vector to contain a maximum of 2^32-1 elements"),
143 ),
144 t,
145 )
146 })
147 }
148
149 pub fn map<R, E>(&self, mapper: impl FnMut(&T) -> Result<R, E>) -> Result<IdxVec<I, R>, E> {
152 Ok(IdxVec {
153 inner: self
154 .inner
155 .iter()
156 .map(mapper)
157 .collect::<Result<Box<[R]>, E>>()?,
158 _phantom: PhantomData,
159 })
160 }
161}
162
163#[derive(Debug)]
165pub struct ExtendedIdxVec<I: Idx, T> {
166 inner: IdxVec<I, T>,
167 num_imports: u32,
168}
169
170impl<I: Idx, T> Default for ExtendedIdxVec<I, T> {
171 fn default() -> Self {
172 Self {
173 inner: IdxVec::default(),
174 num_imports: 0,
175 }
176 }
177}
178
179impl<I: Idx, T: Clone> Clone for ExtendedIdxVec<I, T> {
180 fn clone(&self) -> Self {
181 Self {
182 inner: self.inner.clone(),
183 num_imports: self.num_imports,
184 }
185 }
186}
187
188impl<I: Idx, T> ExtendedIdxVec<I, T> {
189 pub fn new(imports: Vec<T>, locals: Vec<T>) -> Result<Self, IdxVecOverflowError> {
195 let num_imports = u32::try_from(imports.len()).map_err(|_| IdxVecOverflowError)?;
196
197 let mut combined = imports;
198 combined.extend(locals);
199
200 Ok(Self {
201 inner: IdxVec::new(combined)?,
202 num_imports,
203 })
204 }
205
206 pub fn len_local_definitions(&self) -> u32 {
209 self.inner
210 .len()
211 .checked_sub(self.num_imports)
212 .expect("that the number of imports is never larger than the total length of self")
213 }
214
215 pub fn map<R>(
221 &self,
222 new_imported_definitions: Vec<R>,
223 new_local_definitions: Vec<R>,
224 ) -> Option<ExtendedIdxVec<I, R>> {
225 if new_imported_definitions.len() != self.num_imports.into_usize()
226 || u32::try_from(new_local_definitions.len()).ok()? != self.len_local_definitions()
227 {
228 return None;
229 }
230
231 Some(
232 ExtendedIdxVec::new(new_imported_definitions, new_local_definitions)
233 .expect("no overflow can happen because the length did not change"),
234 )
235 }
236
237 pub fn iter_local_definitions(&self) -> core::slice::Iter<'_, T> {
238 self.inner
239 .inner
240 .get(self.num_imports.into_usize()..)
241 .expect("the imports length to never be larger than the total length")
242 .iter()
243 }
244
245 pub fn inner(&self) -> &IdxVec<I, T> {
246 &self.inner
247 }
248
249 pub fn into_inner(self) -> IdxVec<I, T> {
250 self.inner
251 }
252}
253
254#[derive(Copy, Clone, Debug, PartialEq, Eq)]
262pub struct TypeIdx(u32);
263
264impl core::fmt::Display for TypeIdx {
265 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
266 write!(f, "type index {}", self.0)
267 }
268}
269
270impl Idx for TypeIdx {
271 fn new(index: u32) -> Self {
272 Self(index)
273 }
274
275 fn into_inner(self) -> u32 {
276 self.0
277 }
278}
279
280impl TypeIdx {
281 pub fn new(index: u32) -> Self {
286 Self(index)
287 }
288
289 pub fn validate(
294 index: u32,
295 c_types: &IdxVec<TypeIdx, FuncType>,
296 ) -> Result<Self, ValidationError> {
297 c_types
298 .validate_index(index)
299 .ok_or(ValidationError::InvalidTypeIdx(index))
300 }
301
302 pub fn read_and_validate(
305 wasm: &mut WasmReader,
306 c_types: &IdxVec<TypeIdx, FuncType>,
307 ) -> Result<Self, ValidationError> {
308 let index = wasm.read_var_u32()?;
309 Self::validate(index, c_types)
310 }
311
312 pub unsafe fn read_unchecked(wasm: &mut WasmReader) -> Self {
320 let index = wasm.read_var_u32().unwrap();
321 Self::new(index)
322 }
323}
324
325#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
326pub struct FuncIdx(u32);
327
328impl core::fmt::Display for FuncIdx {
329 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
330 write!(f, "function index {}", self.0)
331 }
332}
333
334impl Idx for FuncIdx {
335 fn new(index: u32) -> Self {
336 Self(index)
337 }
338
339 fn into_inner(self) -> u32 {
340 self.0
341 }
342}
343
344impl FuncIdx {
345 pub fn validate<T>(index: u32, c_funcs: &IdxVec<FuncIdx, T>) -> Result<Self, ValidationError> {
350 c_funcs
351 .validate_index(index)
352 .ok_or(ValidationError::InvalidFuncIdx(index))
353 }
354
355 pub fn read_and_validate<T>(
358 wasm: &mut WasmReader,
359 c_funcs: &IdxVec<FuncIdx, T>,
360 ) -> Result<Self, ValidationError> {
361 let index = wasm.read_var_u32()?;
362 Self::validate(index, c_funcs)
363 }
364
365 pub unsafe fn read_unchecked(wasm: &mut WasmReader) -> Self {
373 let index = wasm.read_var_u32().unwrap();
374 Self::new(index)
375 }
376}
377
378#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
379pub struct TableIdx(u32);
380
381impl core::fmt::Display for TableIdx {
382 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
383 write!(f, "table index {}", self.0)
384 }
385}
386
387impl Idx for TableIdx {
388 fn new(index: u32) -> Self {
389 Self(index)
390 }
391
392 fn into_inner(self) -> u32 {
393 self.0
394 }
395}
396
397impl TableIdx {
398 pub fn validate<T>(
403 index: u32,
404 c_tables: &IdxVec<TableIdx, T>,
405 ) -> Result<Self, ValidationError> {
406 c_tables
407 .validate_index(index)
408 .ok_or(ValidationError::InvalidTableIdx(index))
409 }
410
411 pub fn read_and_validate<T>(
414 wasm: &mut WasmReader,
415 c_tables: &IdxVec<TableIdx, T>,
416 ) -> Result<Self, ValidationError> {
417 let index = wasm.read_var_u32()?;
418 Self::validate(index, c_tables)
419 }
420
421 pub unsafe fn read_unchecked(wasm: &mut WasmReader) -> Self {
429 let index = wasm.read_var_u32().unwrap();
430 Self::new(index)
431 }
432}
433
434#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
435pub struct MemIdx(u32);
436
437impl core::fmt::Display for MemIdx {
438 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
439 write!(f, "memory index {}", self.0)
440 }
441}
442
443impl Idx for MemIdx {
444 fn new(index: u32) -> Self {
445 Self(index)
446 }
447
448 fn into_inner(self) -> u32 {
449 self.0
450 }
451}
452
453impl MemIdx {
454 pub fn validate<T>(index: u32, c_mems: &IdxVec<MemIdx, T>) -> Result<Self, ValidationError> {
459 c_mems
460 .validate_index(index)
461 .ok_or(ValidationError::InvalidMemIdx(index))
462 }
463
464 pub fn read_and_validate<T>(
467 wasm: &mut WasmReader,
468 c_mems: &IdxVec<MemIdx, T>,
469 ) -> Result<Self, ValidationError> {
470 let index = wasm.read_var_u32()?;
471 Self::validate(index, c_mems)
472 }
473
474 #[allow(unused)] pub unsafe fn read_unchecked(wasm: &mut WasmReader) -> Self {
483 let index = wasm.read_var_u32().unwrap();
484 Self::new(index)
485 }
486}
487
488#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
489pub struct GlobalIdx(u32);
490
491impl core::fmt::Display for GlobalIdx {
492 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
493 write!(f, "global index {}", self.0)
494 }
495}
496
497impl Idx for GlobalIdx {
498 fn new(index: u32) -> Self {
499 Self(index)
500 }
501
502 fn into_inner(self) -> u32 {
503 self.0
504 }
505}
506
507impl GlobalIdx {
508 pub fn validate<T>(
513 index: u32,
514 c_globals: &IdxVec<GlobalIdx, T>,
515 ) -> Result<Self, ValidationError> {
516 c_globals
517 .validate_index(index)
518 .ok_or(ValidationError::InvalidGlobalIdx(index))
519 }
520
521 pub fn read_and_validate<T>(
524 wasm: &mut WasmReader,
525 c_globals: &IdxVec<GlobalIdx, T>,
526 ) -> Result<Self, ValidationError> {
527 let index = wasm.read_var_u32()?;
528 Self::validate(index, c_globals)
529 }
530
531 pub unsafe fn read_unchecked(wasm: &mut WasmReader) -> Self {
539 let index = wasm.read_var_u32().unwrap();
540 Self::new(index)
541 }
542}
543
544#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
545pub struct ElemIdx(u32);
546
547impl core::fmt::Display for ElemIdx {
548 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
549 write!(f, "element index {}", self.0)
550 }
551}
552
553impl Idx for ElemIdx {
554 fn new(index: u32) -> Self {
555 Self(index)
556 }
557
558 fn into_inner(self) -> u32 {
559 self.0
560 }
561}
562
563impl ElemIdx {
564 pub fn validate<T>(index: u32, c_elems: &IdxVec<ElemIdx, T>) -> Result<Self, ValidationError> {
569 c_elems
570 .validate_index(index)
571 .ok_or(ValidationError::InvalidElemIdx(index))
572 }
573
574 pub fn read_and_validate<T>(
577 wasm: &mut WasmReader,
578 c_elems: &IdxVec<ElemIdx, T>,
579 ) -> Result<Self, ValidationError> {
580 let index = wasm.read_var_u32()?;
581 Self::validate(index, c_elems)
582 }
583
584 pub unsafe fn read_unchecked(wasm: &mut WasmReader) -> Self {
592 let index = wasm.read_var_u32().unwrap();
593 Self::new(index)
594 }
595}
596
597#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
598pub struct DataIdx(u32);
599
600impl core::fmt::Display for DataIdx {
601 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
602 write!(f, "data index {}", self.0)
603 }
604}
605
606impl Idx for DataIdx {
607 fn new(index: u32) -> Self {
608 Self(index)
609 }
610
611 fn into_inner(self) -> u32 {
612 self.0
613 }
614}
615
616impl DataIdx {
617 pub fn validate(index: u32, data_count: u32) -> Result<Self, ValidationError> {
622 (index < data_count)
623 .then_some(Self(index))
624 .ok_or(ValidationError::InvalidDataIdx(index))
625 }
626
627 pub fn read_and_validate(
630 wasm: &mut WasmReader,
631 data_count: u32,
632 ) -> Result<Self, ValidationError> {
633 let index = wasm.read_var_u32()?;
634 Self::validate(index, data_count)
635 }
636
637 pub unsafe fn read_unchecked(wasm: &mut WasmReader) -> Self {
645 let index = wasm.read_var_u32().unwrap();
646 Self::new(index)
647 }
648}
649
650#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
651pub struct LocalIdx(u32);
652
653impl core::fmt::Display for LocalIdx {
654 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
655 write!(f, "local index {}", self.0)
656 }
657}
658
659impl LocalIdx {
660 pub fn into_inner(self) -> u32 {
661 self.0
662 }
663
664 pub fn read_and_validate(
667 wasm: &mut WasmReader,
668 locals_of_current_function: &[ValType],
669 ) -> Result<Self, ValidationError> {
670 let index = wasm.read_var_u32()?;
671 let index_as_usize = usize::try_from(index).expect("architecture to be at least 32 bits");
672
673 match locals_of_current_function.get(index_as_usize) {
674 Some(_local) => Ok(Self(index)),
675 None => Err(ValidationError::InvalidLocalIdx(index)),
676 }
677 }
678
679 pub unsafe fn read_unchecked(wasm: &mut WasmReader) -> Self {
686 let index = wasm.read_var_u32().unwrap();
687 Self(index)
688 }
689}
690
691pub fn read_label_idx(wasm: &mut WasmReader) -> Result<u32, DecodingError> {
693 wasm.read_var_u32()
694}
695
696pub unsafe fn read_label_idx_unchecked(wasm: &mut WasmReader) -> u32 {
703 wasm.read_var_u32().unwrap()
705}