wasm/core/structure/modules/
element_segments.rs

1use alloc::vec::Vec;
2use core::fmt;
3
4use crate::{
5    core::{
6        decoding::reader::span::Span,
7        structure::modules::indices::{FuncIdx, TableIdx},
8    },
9    RefType,
10};
11
12#[derive(Clone)]
13pub struct ElemType {
14    pub init: ElemItems,
15    pub mode: ElemMode,
16}
17
18impl fmt::Debug for ElemType {
19    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20        write!(
21            f,
22            "ElemType {{\n\tinit: {:?},\n\tmode: {:?},\n\t#ty: {:?}\n}}",
23            self.init,
24            self.mode,
25            self.init.ty()
26        )
27    }
28}
29
30impl ElemType {
31    pub fn ty(&self) -> RefType {
32        self.init.ty()
33    }
34
35    pub fn to_ref_type(&self) -> RefType {
36        match self.init {
37            ElemItems::Exprs(rref, _) => rref,
38            ElemItems::RefFuncs(_) => RefType::FuncRef,
39        }
40    }
41}
42
43#[derive(Debug, Clone)]
44pub enum ElemItems {
45    RefFuncs(Vec<FuncIdx>),
46    Exprs(RefType, Vec<Span>),
47}
48
49impl ElemItems {
50    pub fn ty(&self) -> RefType {
51        match self {
52            Self::RefFuncs(_) => RefType::FuncRef,
53            // the mapping for shortened lists above is always true, as the binary format
54            // either parses an elemkind or assumes funcref, and the current spec always maps a well-formed elemkind to a funcref
55            // https://webassembly.github.io/spec/core/binary/modules.html#element-section
56            Self::Exprs(rty, _) => *rty,
57        }
58    }
59
60    pub fn len(&self) -> usize {
61        match self {
62            Self::RefFuncs(ref_funcs) => ref_funcs.len(),
63            Self::Exprs(_, exprs) => exprs.len(),
64        }
65    }
66}
67
68#[derive(Debug, Clone)]
69pub enum ElemMode {
70    Passive,
71    Active(ActiveElem),
72    Declarative,
73}
74
75#[derive(Debug, Clone)]
76pub struct ActiveElem {
77    pub table_idx: TableIdx,
78    pub init_expr: Span,
79}