makepad_stitch/
module.rs

1use {
2    crate::{
3        code::UncompiledCode,
4        config,
5        const_expr::ConstExpr,
6        data::Data,
7        decode::{Decode, DecodeError, Decoder},
8        elem::{Elem, UnguardedElems},
9        engine::Engine,
10        error::Error,
11        extern_val::{ExternType, ExternTypeDesc, ExternVal, ExternValDesc},
12        func::{Func, FuncType},
13        global::{Global, GlobalType},
14        instance::{Instance, InstanceIniter},
15        linker::{InstantiateError, Linker},
16        mem::{Mem, MemType},
17        ref_::{Ref, RefType},
18        store::Store,
19        table::{Table, TableType},
20        trap::Trap,
21        val::ValType,
22    },
23    std::{
24        collections::{hash_map, HashMap, HashSet},
25        slice,
26        sync::Arc,
27    },
28};
29
30/// A Wasm module.
31#[derive(Debug)]
32pub struct Module {
33    types: Arc<[FuncType]>,
34    imports: Box<[((Arc<str>, Arc<str>), ImportKind)]>,
35    imported_func_count: usize,
36    imported_table_count: usize,
37    imported_memory_count: usize,
38    imported_global_count: usize,
39    func_types: Box<[FuncType]>,
40    table_types: Box<[TableType]>,
41    memory_types: Box<[MemType]>,
42    global_types: Box<[GlobalType]>,
43    global_vals: Box<[ConstExpr]>,
44    exports: HashMap<Arc<str>, ExternValDesc>,
45    start: Option<u32>,
46    codes: Box<[UncompiledCode]>,
47    elems: Box<[ElemDef]>,
48    datas: Box<[DataDef]>,
49}
50
51impl Module {
52    /// Decodes and validates a new [`Module`] from the given byte slice.
53    ///
54    /// # Errors
55    ///
56    /// - If the [`Module`] is malformed.
57    /// - If the [`Module`] is invalid.
58    pub fn new(engine: &Engine, bytes: &[u8]) -> Result<Module, DecodeError> {
59        const MAGIC: [u8; 4] = [0x00, 0x61, 0x73, 0x6D];
60        const VERSION: [u8; 4] = [0x01, 0x00, 0x00, 0x00];
61        const EXPECTED_SECTION_IDS: &[u8] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 10, 11];
62
63        let mut decoder = Decoder::new(bytes);
64        let magic = decoder.read_bytes(4)?;
65        if magic != MAGIC {
66            return Err(DecodeError::new(""))?;
67        }
68        let version = decoder.read_bytes(4)?;
69        if version != VERSION {
70            return Err(DecodeError::new(""))?;
71        }
72        let mut builder = ModuleBuilder::new();
73        let mut expected_section_ids = EXPECTED_SECTION_IDS.iter().copied();
74        while !decoder.is_at_end() {
75            let section_id = decoder.read_byte()?;
76            if section_id != 0 {
77                if !expected_section_ids
78                    .any(|expected_section_id| expected_section_id == section_id)
79                {
80                    return Err(DecodeError::new("section id mismatch"))?;
81                }
82            }
83            let mut section_decoder = decoder.decode_decoder()?;
84            match section_id {
85                // Custom section
86                0 => {
87                    section_decoder.decode_string()?;
88                    section_decoder.read_bytes_until_end();
89                }
90                // Type section
91                1 => {
92                    for type_ in section_decoder.decode_iter()? {
93                        builder.push_type(type_?)?;
94                    }
95                }
96                // Import section
97                2 => {
98                    for import in section_decoder.decode_iter()? {
99                        builder.push_import(import?)?;
100                    }
101                }
102                // Function section
103                3 => {
104                    for type_idx in section_decoder.decode_iter()? {
105                        builder.push_func(type_idx?)?;
106                    }
107                }
108                // Table section
109                4 => {
110                    for table in section_decoder.decode_iter()? {
111                        builder.push_table(table?)?;
112                    }
113                }
114                // Memory section
115                5 => {
116                    for mem in section_decoder.decode_iter()? {
117                        builder.push_memory(mem?)?;
118                    }
119                }
120                // Global section
121                6 => {
122                    for global in section_decoder.decode_iter()? {
123                        builder.push_global(global?)?;
124                    }
125                }
126                // Export section
127                7 => {
128                    for export in section_decoder.decode_iter()? {
129                        builder.push_export(export?)?;
130                    }
131                }
132                // Start section
133                8 => {
134                    builder.set_start(section_decoder.decode()?)?;
135                }
136                // Element section
137                9 => {
138                    for elem in section_decoder.decode_iter()? {
139                        builder.push_elem(elem?)?;
140                    }
141                }
142                // Code section
143                10 => {
144                    for code in section_decoder.decode_iter()? {
145                        builder.push_code(code?)?;
146                    }
147                }
148                // Data section
149                11 => {
150                    for data in section_decoder.decode_iter()? {
151                        builder.push_data(data?)?;
152                    }
153                }
154                // Data count section
155                12 => {
156                    let data_count = section_decoder.decode()?;
157                    builder.set_data_count(data_count);
158                }
159                _ => unreachable!(),
160            }
161            if !section_decoder.is_at_end() {
162                return Err(DecodeError::new(""))?;
163            }
164        }
165        builder.finish(engine)
166    }
167
168    /// Returns an iterator over the imports in this [`Module`].
169    pub fn imports(&self) -> ModuleImports<'_> {
170        ModuleImports {
171            imports: self.imports.iter(),
172            imported_func_types: self.func_types[..self.imported_func_count].iter(),
173            imported_table_types: self.table_types[..self.imported_table_count].iter(),
174            imported_memory_types: self.memory_types[..self.imported_memory_count].iter(),
175            imported_global_types: self.global_types[..self.imported_global_count].iter(),
176        }
177    }
178
179    /// Returns the [`ExternType`] of the export with the given name in this [`Module`], if it exists.
180    pub fn export<'a>(&'a self, name: &'a str) -> Option<ExternType> {
181        self.exports.get(name).map(|&desc| self.extern_type(desc))
182    }
183
184    /// Returns an iterator over the exports in this [`Module`].
185    pub fn exports(&self) -> ModuleExports<'_> {
186        ModuleExports {
187            module: self,
188            iter: self.exports.iter(),
189        }
190    }
191
192    pub(crate) fn instantiate(
193        &self,
194        store: &mut Store,
195        linker: &Linker,
196    ) -> Result<Instance, Error> {
197        let instance = Instance::uninited(store.id());
198        let mut initer = InstanceIniter::new(store.id());
199        for type_ in self.types.iter() {
200            initer.push_type(store.get_or_intern_type(type_));
201        }
202        for ((module, name), type_) in self.imports() {
203            match type_ {
204                ExternType::Func(type_) => {
205                    let val = linker
206                        .lookup(module, name)
207                        .ok_or(InstantiateError::DefNotFound)?;
208                    let func = val.to_func().ok_or(InstantiateError::ImportKindMismatch)?;
209                    if func.type_(store) != &type_ {
210                        return Err(InstantiateError::FuncTypeMismatch)?;
211                    }
212                    initer.push_func(func);
213                }
214                ExternType::Global(type_) => {
215                    let val = linker
216                        .lookup(module, name)
217                        .ok_or(InstantiateError::DefNotFound)?;
218                    let global = val
219                        .to_global()
220                        .ok_or(InstantiateError::ImportKindMismatch)?;
221                    if global.type_(store) != type_ {
222                        return Err(InstantiateError::GlobalTypeMismatch)?;
223                    }
224                    initer.push_global(global);
225                }
226                _ => {}
227            }
228        }
229        for (type_, code) in self.internal_funcs() {
230            let type_ = store.get_or_intern_type(type_);
231            initer.push_func(Func::new_wasm(store, type_, instance.clone(), code.clone()));
232        }
233        let global_init_vals: Vec<_> = self
234            .internal_globals()
235            .map(|(_, val)| val.evaluate(store, &initer))
236            .collect();
237        let elems: Vec<UnguardedElems> = self
238            .elems
239            .iter()
240            .map(|elem| match elem.type_ {
241                RefType::FuncRef => UnguardedElems::FuncRef(
242                    elem.elems
243                        .iter()
244                        .map(|elem| {
245                            elem.evaluate(store, &initer)
246                                .to_func_ref()
247                                .unwrap()
248                                .to_unguarded(store.id())
249                        })
250                        .collect(),
251                ),
252                RefType::ExternRef => UnguardedElems::ExternRef(
253                    elem.elems
254                        .iter()
255                        .map(|elem| {
256                            elem.evaluate(store, &initer)
257                                .to_extern_ref()
258                                .unwrap()
259                                .to_unguarded(store.id())
260                        })
261                        .collect(),
262                ),
263            })
264            .collect();
265        for ((module, name), type_) in self.imports() {
266            match type_ {
267                ExternType::Table(type_) => {
268                    let val = linker
269                        .lookup(module, name)
270                        .ok_or(InstantiateError::DefNotFound)?;
271                    let table = val.to_table().ok_or(InstantiateError::ImportKindMismatch)?;
272                    if !table.type_(store).is_subtype_of(type_) {
273                        return Err(InstantiateError::TableTypeMismatch)?;
274                    }
275                    initer.push_table(table);
276                }
277                ExternType::Mem(type_) => {
278                    let val = linker
279                        .lookup(module, name)
280                        .ok_or(InstantiateError::DefNotFound)?;
281                    let mem = val.to_mem().ok_or(InstantiateError::ImportKindMismatch)?;
282                    if !mem.type_(store).is_subtype_of(type_) {
283                        return Err(InstantiateError::MemTypeMismatch)?;
284                    }
285                    initer.push_mem(mem);
286                }
287                _ => {}
288            }
289        }
290        for type_ in self.internal_tables() {
291            initer.push_table(Table::new(store, type_, Ref::null(type_.elem)).unwrap());
292        }
293        for type_ in self.internal_memories() {
294            initer.push_mem(Mem::new(store, type_));
295        }
296        for ((type_, _), init_val) in self.internal_globals().zip(global_init_vals) {
297            initer.push_global(Global::new(store, type_, init_val).unwrap());
298        }
299        for (name, &desc) in self.exports.iter() {
300            initer.push_export(
301                name.clone(),
302                match desc {
303                    ExternValDesc::Func(idx) => ExternVal::Func(initer.func(idx).unwrap()),
304                    ExternValDesc::Table(idx) => ExternVal::Table(initer.table(idx).unwrap()),
305                    ExternValDesc::Memory(idx) => ExternVal::Memory(initer.mem(idx).unwrap()),
306                    ExternValDesc::Global(idx) => ExternVal::Global(initer.global(idx).unwrap()),
307                },
308            );
309        }
310        for elems in elems {
311            initer.push_elem(unsafe { Elem::new_unguarded(store, elems) });
312        }
313        for data in self.datas.iter() {
314            initer.push_data(Data::new(store, data.bytes.clone()));
315        }
316        instance.init(initer);
317        for (elem_idx, elem) in (0u32..).zip(self.elems.iter()) {
318            let ElemKind::Active {
319                table_idx,
320                ref offset,
321            } = elem.kind
322            else {
323                continue;
324            };
325            instance.table(table_idx).unwrap().init(
326                store,
327                offset.evaluate(store, &instance).to_i32().unwrap() as u32,
328                instance.elem(elem_idx).unwrap(),
329                0,
330                elem.elems.len().try_into().unwrap(),
331            )?;
332            instance.elem(elem_idx).unwrap().drop_elems(store);
333        }
334        for (elem_idx, elem) in (0u32..).zip(self.elems.iter()) {
335            let ElemKind::Declarative = elem.kind else {
336                continue;
337            };
338            instance.elem(elem_idx).unwrap().drop_elems(store);
339        }
340        for (data_idx, data) in (0u32..).zip(self.datas.iter()) {
341            let DataKind::Active {
342                mem_idx,
343                ref offset,
344            } = data.kind
345            else {
346                continue;
347            };
348            instance.mem(mem_idx).unwrap().init(
349                store,
350                offset
351                    .evaluate(store, &instance)
352                    .to_i32()
353                    .ok_or(Trap::Unreachable)? as u32,
354                instance.data(data_idx).unwrap(),
355                0,
356                data.bytes.len().try_into().unwrap(),
357            )?;
358            instance.data(data_idx).unwrap().drop_bytes(store);
359        }
360        if let Some(start) = self.start {
361            instance.func(start).unwrap().call(store, &[], &mut [])?;
362        }
363        Ok(instance)
364    }
365
366    fn func(&self, idx: u32) -> Option<&FuncType> {
367        let idx = usize::try_from(idx).unwrap();
368        self.func_types.get(idx)
369    }
370
371    fn table(&self, idx: u32) -> Option<TableType> {
372        let idx = usize::try_from(idx).unwrap();
373        self.table_types.get(idx).copied()
374    }
375
376    fn memory(&self, idx: u32) -> Option<MemType> {
377        let idx = usize::try_from(idx).unwrap();
378        self.memory_types.get(idx).copied()
379    }
380
381    fn global(&self, idx: u32) -> Option<GlobalType> {
382        let idx = usize::try_from(idx).unwrap();
383        self.global_types.get(idx).copied()
384    }
385
386    fn extern_type(&self, desc: ExternValDesc) -> ExternType {
387        match desc {
388            ExternValDesc::Func(idx) => self.func(idx).cloned().unwrap().into(),
389            ExternValDesc::Table(idx) => self.table(idx).unwrap().into(),
390            ExternValDesc::Memory(idx) => self.memory(idx).unwrap().into(),
391            ExternValDesc::Global(idx) => self.global(idx).unwrap().into(),
392        }
393    }
394
395    fn internal_funcs(&self) -> impl Iterator<Item = (&FuncType, &UncompiledCode)> {
396        self.func_types[self.imported_func_count..]
397            .iter()
398            .zip(self.codes.iter())
399    }
400
401    fn internal_tables(&self) -> impl Iterator<Item = TableType> + '_ {
402        self.table_types[self.imported_table_count..]
403            .iter()
404            .copied()
405    }
406
407    fn internal_memories(&self) -> impl Iterator<Item = MemType> + '_ {
408        self.memory_types[self.imported_memory_count..]
409            .iter()
410            .copied()
411    }
412
413    fn internal_globals(&self) -> impl Iterator<Item = (GlobalType, &ConstExpr)> {
414        self.global_types[self.imported_global_count..]
415            .iter()
416            .copied()
417            .zip(self.global_vals.iter())
418    }
419}
420
421/// An iterator over the imports in a [`Module`].
422#[derive(Clone, Debug)]
423pub struct ModuleImports<'a> {
424    imports: slice::Iter<'a, ((Arc<str>, Arc<str>), ImportKind)>,
425    imported_func_types: slice::Iter<'a, FuncType>,
426    imported_table_types: slice::Iter<'a, TableType>,
427    imported_memory_types: slice::Iter<'a, MemType>,
428    imported_global_types: slice::Iter<'a, GlobalType>,
429}
430
431impl<'a> Iterator for ModuleImports<'a> {
432    type Item = ((&'a str, &'a str), ExternType);
433
434    fn next(&mut self) -> Option<Self::Item> {
435        self.imports.next().map(|((module, name), imported)| {
436            (
437                (&**module, &**name),
438                match imported {
439                    ImportKind::Func => self.imported_func_types.next().cloned().unwrap().into(),
440                    ImportKind::Table => self.imported_table_types.next().copied().unwrap().into(),
441                    ImportKind::Mem => self.imported_memory_types.next().copied().unwrap().into(),
442                    ImportKind::Global => {
443                        self.imported_global_types.next().copied().unwrap().into()
444                    }
445                },
446            )
447        })
448    }
449}
450
451/// An iterator over the exports in a [`Module`].
452#[derive(Clone, Debug)]
453pub struct ModuleExports<'a> {
454    module: &'a Module,
455    iter: hash_map::Iter<'a, Arc<str>, ExternValDesc>,
456}
457
458impl<'a> Iterator for ModuleExports<'a> {
459    type Item = (&'a str, ExternType);
460
461    fn next(&mut self) -> Option<Self::Item> {
462        self.iter
463            .next()
464            .map(|(name, &desc)| (&**name, self.module.extern_type(desc)))
465    }
466}
467
468/// A builder for a [`Module`].
469#[derive(Debug)]
470pub(crate) struct ModuleBuilder {
471    types: Vec<FuncType>,
472    imports: Vec<((Arc<str>, Arc<str>), ImportKind)>,
473    imported_func_count: usize,
474    imported_table_count: usize,
475    imported_memory_count: usize,
476    imported_global_count: usize,
477    func_types: Vec<FuncType>,
478    table_types: Vec<TableType>,
479    memory_types: Vec<MemType>,
480    global_types: Vec<GlobalType>,
481    global_vals: Vec<ConstExpr>,
482    exports: HashMap<Arc<str>, ExternValDesc>,
483    start: Option<u32>,
484    codes: Vec<UncompiledCode>,
485    elems: Vec<ElemDef>,
486    datas: Vec<DataDef>,
487    data_count: Option<u32>,
488    refs: HashSet<u32>,
489}
490
491impl ModuleBuilder {
492    fn new() -> Self {
493        Self {
494            types: Vec::new(),
495            imports: Vec::new(),
496            imported_func_count: 0,
497            imported_table_count: 0,
498            imported_memory_count: 0,
499            imported_global_count: 0,
500            func_types: Vec::new(),
501            table_types: Vec::new(),
502            memory_types: Vec::new(),
503            global_types: Vec::new(),
504            global_vals: Vec::new(),
505            exports: HashMap::new(),
506            start: None,
507            codes: Vec::new(),
508            elems: Vec::new(),
509            datas: Vec::new(),
510            data_count: None,
511            refs: HashSet::new(),
512        }
513    }
514
515    pub(crate) fn type_(&self, idx: u32) -> Result<&FuncType, DecodeError> {
516        let idx = usize::try_from(idx).unwrap();
517        self.types
518            .get(idx)
519            .ok_or_else(|| DecodeError::new("unknown type"))
520    }
521
522    pub(crate) fn func(&self, idx: u32) -> Result<&FuncType, DecodeError> {
523        let idx = usize::try_from(idx).unwrap();
524        self.func_types
525            .get(idx)
526            .ok_or_else(|| DecodeError::new("unknown function"))
527    }
528
529    pub(crate) fn table(&self, idx: u32) -> Result<TableType, DecodeError> {
530        let idx = usize::try_from(idx).unwrap();
531        self.table_types
532            .get(idx)
533            .copied()
534            .ok_or_else(|| DecodeError::new("unknown table"))
535    }
536
537    pub(crate) fn memory(&self, idx: u32) -> Result<MemType, DecodeError> {
538        let idx = usize::try_from(idx).unwrap();
539        self.memory_types
540            .get(idx)
541            .copied()
542            .ok_or_else(|| DecodeError::new("unknown memory"))
543    }
544
545    pub(crate) fn imported_global(&self, idx: u32) -> Result<GlobalType, DecodeError> {
546        let idx = usize::try_from(idx).unwrap();
547        self.global_types[..self.imported_global_count]
548            .get(idx)
549            .copied()
550            .ok_or_else(|| DecodeError::new("unknown global"))
551    }
552
553    pub(crate) fn global(&self, idx: u32) -> Result<GlobalType, DecodeError> {
554        let idx = usize::try_from(idx).unwrap();
555        self.global_types
556            .get(idx)
557            .copied()
558            .ok_or_else(|| DecodeError::new("unknown global"))
559    }
560
561    pub(crate) fn elem(&self, idx: u32) -> Result<RefType, DecodeError> {
562        let idx = usize::try_from(idx).unwrap();
563        self.elems
564            .get(idx)
565            .map(|elem| elem.type_)
566            .ok_or_else(|| DecodeError::new("unknown element segment"))
567    }
568
569    pub(crate) fn data(&self, idx: u32) -> Result<(), DecodeError> {
570        if let Some(data_count) = self.data_count {
571            if idx >= data_count {
572                return Err(DecodeError::new("unknown data segment"));
573            }
574            Ok(())
575        } else {
576            Err(DecodeError::new("missing data count section"))
577        }
578    }
579
580    pub(crate) fn ref_(&self, func_idx: u32) -> Result<(), DecodeError> {
581        if !self.refs.contains(&func_idx) {
582            return Err(DecodeError::new("undeclared reference"));
583        }
584        Ok(())
585    }
586
587    fn push_type(&mut self, type_: FuncType) -> Result<(), DecodeError> {
588        if self.types.len() == config::MAX_TYPE_COUNT {
589            return Err(DecodeError::new("too many types"));
590        }
591        self.types.push(type_);
592        Ok(())
593    }
594
595    fn push_import(&mut self, import: ImportDef) -> Result<(), DecodeError> {
596        if self.imports.len() == config::MAX_IMPORT_COUNT {
597            return Err(DecodeError::new("too many imports"));
598        }
599        let key = (import.module, import.name);
600        match import.desc {
601            ExternTypeDesc::Func(type_idx) => {
602                if self.func_types.len() == config::MAX_FUNC_COUNT {
603                    return Err(DecodeError::new("too many functions"));
604                }
605                self.imports.push((key, ImportKind::Func));
606                self.imported_func_count += 1;
607                self.func_types.push(self.type_(type_idx).cloned()?);
608            }
609            ExternTypeDesc::Table(type_) => {
610                if self.table_types.len() == config::MAX_TABLE_COUNT {
611                    return Err(DecodeError::new("too many tables"));
612                }
613                if !type_.is_valid() {
614                    return Err(DecodeError::new("invalid table type"))?;
615                }
616                self.imports.push((key, ImportKind::Table));
617                self.imported_table_count += 1;
618                self.table_types.push(type_);
619            }
620            ExternTypeDesc::Memory(type_) => {
621                if self.memory_types.len() == config::MAX_MEMORY_COUNT {
622                    return Err(DecodeError::new("too many memories"));
623                }
624                if !type_.is_valid() {
625                    return Err(DecodeError::new("invalid memory type"));
626                }
627                self.imports.push((key, ImportKind::Mem));
628                self.imported_memory_count += 1;
629                self.memory_types.push(type_);
630            }
631            ExternTypeDesc::Global(type_) => {
632                if self.global_types.len() == config::MAX_GLOBAL_COUNT {
633                    return Err(DecodeError::new("too many globals"));
634                }
635                self.imports.push((key, ImportKind::Global));
636                self.imported_global_count += 1;
637                self.global_types.push(type_);
638            }
639        }
640        Ok(())
641    }
642
643    fn push_func(&mut self, type_idx: u32) -> Result<(), DecodeError> {
644        if self.func_types.len() == config::MAX_FUNC_COUNT {
645            return Err(DecodeError::new("too many functions"));
646        }
647        let type_ = self.type_(type_idx).cloned()?;
648        if type_.params().len() > config::MAX_FUNC_PARAM_COUNT {
649            return Err(DecodeError::new("too many function parameters"));
650        }
651        if type_.results().len() > config::MAX_FUNC_RESULT_COUNT {
652            return Err(DecodeError::new("too many function results"));
653        }
654        self.func_types.push(type_);
655        Ok(())
656    }
657
658    fn push_table(&mut self, table: TableDef) -> Result<(), DecodeError> {
659        if self.table_types.len() == config::MAX_TABLE_COUNT {
660            return Err(DecodeError::new("too many tables"));
661        }
662        if !table.type_.is_valid() {
663            return Err(DecodeError::new("invalid table type"))?;
664        }
665        self.table_types.push(table.type_);
666        Ok(())
667    }
668
669    fn push_memory(&mut self, memory: MemDef) -> Result<(), DecodeError> {
670        if self.memory_types.len() == config::MAX_MEMORY_COUNT {
671            return Err(DecodeError::new("too many memories"));
672        }
673        if !memory.type_.is_valid() {
674            return Err(DecodeError::new("invalid memory type"));
675        }
676        self.memory_types.push(memory.type_);
677        Ok(())
678    }
679
680    fn push_global(&mut self, global: GlobalDef) -> Result<(), DecodeError> {
681        if self.global_types.len() == config::MAX_GLOBAL_COUNT {
682            return Err(DecodeError::new("too many globals"));
683        }
684        if global.val.validate(self)? != global.type_.val {
685            return Err(DecodeError::new("type mismatch"));
686        }
687        if let Some(func_idx) = global.val.func_idx() {
688            self.refs.insert(func_idx);
689        }
690        self.global_types.push(global.type_);
691        self.global_vals.push(global.val);
692        Ok(())
693    }
694
695    fn push_export(&mut self, export: ExportDef) -> Result<(), DecodeError> {
696        if self.exports.len() == config::MAX_EXPORT_COUNT {
697            return Err(DecodeError::new("too many exports"));
698        }
699        match export.desc {
700            ExternValDesc::Func(idx) => {
701                self.refs.insert(idx);
702                self.func(idx)?;
703            }
704            ExternValDesc::Table(idx) => {
705                self.table(idx)?;
706            }
707            ExternValDesc::Memory(idx) => {
708                self.memory(idx)?;
709            }
710            ExternValDesc::Global(idx) => {
711                self.global(idx)?;
712            }
713        }
714        if self.exports.contains_key(&export.name) {
715            return Err(DecodeError::new("duplicate export name"));
716        }
717        self.exports.insert(export.name, export.desc);
718        Ok(())
719    }
720
721    fn set_start(&mut self, start: u32) -> Result<(), DecodeError> {
722        let type_ = self.func(start)?;
723        if type_ != &FuncType::from_val_type(None) {
724            return Err(DecodeError::new("type mismatch"));
725        }
726        self.start = Some(start);
727        Ok(())
728    }
729
730    fn push_code(&mut self, code: UncompiledCode) -> Result<(), DecodeError> {
731        if self.codes.len() == self.func_types.len() - self.imported_func_count {
732            return Err(DecodeError::new(
733                "function and code section have inconsistent sizes",
734            ))?;
735        }
736        if code.locals.len() > config::MAX_FUNC_LOCAL_COUNT {
737            return Err(DecodeError::new("too many function locals"));
738        }
739        if code.expr.len() > config::MAX_FUNC_BODY_SIZE {
740            return Err(DecodeError::new("function body too large"));
741        }
742        self.codes.push(code);
743        Ok(())
744    }
745
746    fn push_elem(&mut self, elem: ElemDef) -> Result<(), DecodeError> {
747        if self.elems.len() == config::MAX_ELEM_COUNT {
748            return Err(DecodeError::new("too many element segments"));
749        }
750        if elem.elems.len() > config::MAX_ELEM_SIZE {
751            return Err(DecodeError::new("element segment too large"));
752        }
753        if let ElemKind::Active {
754            table_idx,
755            ref offset,
756        } = elem.kind
757        {
758            let table = self.table(table_idx)?;
759            if elem.type_ != table.elem {
760                return Err(DecodeError::new("type mismatch"));
761            }
762            if offset.validate(self)? != ValType::I32 {
763                return Err(DecodeError::new("type mismatch"));
764            }
765        }
766        for expr in &*elem.elems {
767            if expr.validate(self)? != elem.type_.into() {
768                return Err(DecodeError::new("type mismatch"));
769            }
770        }
771        for elem in elem.elems.iter() {
772            if let Some(func_idx) = elem.func_idx() {
773                self.refs.insert(func_idx);
774            }
775        }
776        self.elems.push(elem);
777        Ok(())
778    }
779
780    fn push_data(&mut self, data: DataDef) -> Result<(), DecodeError> {
781        if self.datas.len() == config::MAX_DATA_COUNT {
782            return Err(DecodeError::new("too many data segments"));
783        }
784        if data.bytes.len() > config::MAX_DATA_SIZE {
785            return Err(DecodeError::new("data segment too large"));
786        }
787        if let DataKind::Active {
788            mem_idx,
789            ref offset,
790        } = data.kind
791        {
792            self.memory(mem_idx)?;
793            if offset.validate(self)? != ValType::I32 {
794                return Err(DecodeError::new("type mismatch"));
795            }
796        }
797        self.datas.push(data);
798        Ok(())
799    }
800
801    fn set_data_count(&mut self, data_count: u32) {
802        self.data_count = Some(data_count);
803    }
804
805    fn finish(self, engine: &Engine) -> Result<Module, DecodeError> {
806        if self.func_types.len() - self.imported_func_count > self.codes.len() {
807            return Err(DecodeError::new(
808                "function and code section have inconsistent sizes",
809            ))?;
810        }
811        for (type_, code) in self.func_types[self.imported_func_count..]
812            .iter()
813            .zip(self.codes.iter())
814        {
815            engine.validate(type_, &self, code)?;
816        }
817        if let Some(data_count) = self.data_count {
818            if data_count != u32::try_from(self.datas.len()).unwrap() {
819                return Err(DecodeError::new(
820                    "data count and data section have inconsistent sizes",
821                ))?;
822            }
823        }
824        Ok(Module {
825            types: self.types.into(),
826            imports: self.imports.into(),
827            imported_func_count: self.imported_func_count,
828            imported_table_count: self.imported_table_count,
829            imported_memory_count: self.imported_memory_count,
830            imported_global_count: self.imported_global_count,
831            func_types: self.func_types.into(),
832            table_types: self.table_types.into(),
833            memory_types: self.memory_types.into(),
834            global_types: self.global_types.into(),
835            global_vals: self.global_vals.into(),
836            exports: self.exports,
837            start: self.start,
838            codes: self.codes.into(),
839            elems: self.elems.into(),
840            datas: self.datas.into(),
841        })
842    }
843}
844
845/// The kind of an import
846#[derive(Clone, Copy, Debug)]
847enum ImportKind {
848    Func,
849    Table,
850    Mem,
851    Global,
852}
853
854/// A definition for an import.
855#[derive(Clone, Debug)]
856struct ImportDef {
857    module: Arc<str>,
858    name: Arc<str>,
859    desc: ExternTypeDesc,
860}
861
862impl Decode for ImportDef {
863    fn decode(decoder: &mut Decoder<'_>) -> Result<Self, DecodeError> {
864        Ok(ImportDef {
865            module: decoder.decode()?,
866            name: decoder.decode()?,
867            desc: decoder.decode()?,
868        })
869    }
870}
871
872/// A definition for a [`Table`].
873#[derive(Debug)]
874struct TableDef {
875    type_: TableType,
876}
877
878impl Decode for TableDef {
879    fn decode(decoder: &mut Decoder) -> Result<Self, DecodeError> {
880        Ok(Self {
881            type_: decoder.decode()?,
882        })
883    }
884}
885
886/// A definition for a [`Mem`].
887#[derive(Debug)]
888struct MemDef {
889    type_: MemType,
890}
891
892impl Decode for MemDef {
893    fn decode(decoder: &mut Decoder) -> Result<Self, DecodeError> {
894        Ok(Self {
895            type_: decoder.decode()?,
896        })
897    }
898}
899
900/// A definition for a [`Global`].
901#[derive(Clone, Debug)]
902struct GlobalDef {
903    type_: GlobalType,
904    val: ConstExpr,
905}
906
907impl Decode for GlobalDef {
908    fn decode(decoder: &mut Decoder) -> Result<Self, DecodeError> {
909        Ok(Self {
910            type_: decoder.decode()?,
911            val: decoder.decode()?,
912        })
913    }
914}
915
916/// A definition for an [`Export`].
917#[derive(Clone, Debug)]
918struct ExportDef {
919    name: Arc<str>,
920    desc: ExternValDesc,
921}
922
923impl Decode for ExportDef {
924    fn decode(decoder: &mut Decoder<'_>) -> Result<Self, DecodeError> {
925        Ok(Self {
926            name: decoder.decode()?,
927            desc: decoder.decode()?,
928        })
929    }
930}
931
932/// A definition for an [`Elem`].
933#[derive(Clone, Debug)]
934struct ElemDef {
935    kind: ElemKind,
936    type_: RefType,
937    elems: Arc<[ConstExpr]>,
938}
939
940impl Decode for ElemDef {
941    fn decode(decoder: &mut Decoder<'_>) -> Result<Self, DecodeError> {
942        let flags: u32 = decoder.decode()?;
943        Ok(Self {
944            kind: if flags & 0x01 != 0 {
945                if flags & 0x02 != 0 {
946                    ElemKind::Declarative
947                } else {
948                    ElemKind::Passive
949                }
950            } else {
951                ElemKind::Active {
952                    table_idx: if flags & 0x02 != 0 {
953                        decoder.decode()?
954                    } else {
955                        0
956                    },
957                    offset: decoder.decode()?,
958                }
959            },
960            type_: if flags & 0x03 != 0 {
961                if flags & 0x04 != 0 {
962                    decoder.decode()?
963                } else {
964                    match decoder.decode()? {
965                        0x00 => RefType::FuncRef,
966                        _ => {
967                            return Err(DecodeError::new("malformed element kind"));
968                        }
969                    }
970                }
971            } else {
972                RefType::FuncRef
973            },
974            elems: if flags & 0x04 != 0 {
975                decoder.decode_iter()?.collect::<Result<_, _>>()?
976            } else {
977                decoder
978                    .decode_iter::<u32>()?
979                    .map(|func_idx| func_idx.map(|func_idx| ConstExpr::new_ref_func(func_idx)))
980                    .collect::<Result<_, _>>()?
981            },
982        })
983    }
984}
985
986/// The kind of an [`Elem`].
987#[derive(Clone, Debug)]
988enum ElemKind {
989    /// Passive [`Elem`]s are used to initialize [`Table`]s during execution.
990    Passive,
991    /// Active [`Elem`]s are used to initialize [`Table`]s during instantiation.
992    Active { table_idx: u32, offset: ConstExpr },
993    /// Declarative [`Elem`]s are only used during validation.
994    Declarative,
995}
996
997/// A definition for a [`Data`].
998#[derive(Clone, Debug)]
999pub(crate) struct DataDef {
1000    kind: DataKind,
1001    bytes: Arc<[u8]>,
1002}
1003
1004impl Decode for DataDef {
1005    fn decode(decoder: &mut Decoder<'_>) -> Result<Self, DecodeError> {
1006        Ok(Self {
1007            kind: {
1008                let flags: u32 = decoder.decode()?;
1009                if flags & 0x1 != 0 {
1010                    DataKind::Passive
1011                } else {
1012                    DataKind::Active {
1013                        mem_idx: if flags & 0x02 != 0 {
1014                            decoder.decode()?
1015                        } else {
1016                            0
1017                        },
1018                        offset: decoder.decode()?,
1019                    }
1020                }
1021            },
1022            bytes: decoder.decode_decoder()?.read_bytes_until_end().into(),
1023        })
1024    }
1025}
1026
1027/// The kind of a [`Data`].
1028#[derive(Clone, Debug)]
1029enum DataKind {
1030    /// Passive [`Data`]s are used to initialize a [`Mem`] during execution.
1031    Passive,
1032    /// Active [`Data`]s are used to initialize a [`Mem`] during instantiation.
1033    Active { mem_idx: u32, offset: ConstExpr },
1034}