Skip to main content

wasm_encoder/
reencode.rs

1//! Conversions from `wasmparser` to `wasm-encoder` to [`Reencode`] parsed wasm.
2//!
3//! The [`RoundtripReencoder`] allows encoding identical wasm to the parsed
4//! input.
5
6use crate::CoreTypeEncoder;
7use core::convert::Infallible;
8use core::error::Error as StdError;
9
10#[cfg(feature = "component-model")]
11mod component;
12
13#[cfg(feature = "component-model")]
14pub use self::component::*;
15
16#[cfg(feature = "wasmparser")]
17use alloc::vec::Vec;
18
19#[allow(missing_docs)] // FIXME
20pub trait Reencode {
21    type Error;
22
23    fn data_index(&mut self, data: u32) -> Result<u32, Error<Self::Error>> {
24        Ok(utils::data_index(self, data))
25    }
26
27    fn element_index(&mut self, element: u32) -> Result<u32, Error<Self::Error>> {
28        Ok(utils::element_index(self, element))
29    }
30
31    fn function_index(&mut self, func: u32) -> Result<u32, Error<Self::Error>> {
32        Ok(utils::function_index(self, func))
33    }
34
35    fn global_index(&mut self, global: u32) -> Result<u32, Error<Self::Error>> {
36        Ok(utils::global_index(self, global))
37    }
38
39    fn memory_index(&mut self, memory: u32) -> Result<u32, Error<Self::Error>> {
40        Ok(utils::memory_index(self, memory))
41    }
42
43    fn table_index(&mut self, table: u32) -> Result<u32, Error<Self::Error>> {
44        Ok(utils::table_index(self, table))
45    }
46
47    fn tag_index(&mut self, tag: u32) -> Result<u32, Error<Self::Error>> {
48        Ok(utils::tag_index(self, tag))
49    }
50
51    fn type_index(&mut self, ty: u32) -> Result<u32, Error<Self::Error>> {
52        Ok(utils::type_index(self, ty))
53    }
54
55    fn type_index_unpacked(
56        &mut self,
57        ty: wasmparser::UnpackedIndex,
58    ) -> Result<u32, Error<Self::Error>> {
59        utils::type_index_unpacked(self, ty)
60    }
61
62    fn external_index(
63        &mut self,
64        kind: wasmparser::ExternalKind,
65        index: u32,
66    ) -> Result<u32, Error<Self::Error>> {
67        match kind {
68            wasmparser::ExternalKind::Func | wasmparser::ExternalKind::FuncExact => {
69                self.function_index(index)
70            }
71            wasmparser::ExternalKind::Table => self.table_index(index),
72            wasmparser::ExternalKind::Memory => self.memory_index(index),
73            wasmparser::ExternalKind::Global => self.global_index(index),
74            wasmparser::ExternalKind::Tag => self.tag_index(index),
75        }
76    }
77
78    fn abstract_heap_type(
79        &mut self,
80        value: wasmparser::AbstractHeapType,
81    ) -> Result<crate::AbstractHeapType, Error<Self::Error>> {
82        Ok(utils::abstract_heap_type(self, value))
83    }
84
85    fn array_type(
86        &mut self,
87        array_ty: wasmparser::ArrayType,
88    ) -> Result<crate::ArrayType, Error<Self::Error>> {
89        utils::array_type(self, array_ty)
90    }
91
92    fn block_type(
93        &mut self,
94        arg: wasmparser::BlockType,
95    ) -> Result<crate::BlockType, Error<Self::Error>> {
96        utils::block_type(self, arg)
97    }
98
99    fn const_expr(
100        &mut self,
101        const_expr: wasmparser::ConstExpr,
102    ) -> Result<crate::ConstExpr, Error<Self::Error>> {
103        utils::const_expr(self, const_expr)
104    }
105
106    fn catch(&mut self, arg: wasmparser::Catch) -> Result<crate::Catch, Error<Self::Error>> {
107        utils::catch(self, arg)
108    }
109
110    fn composite_type(
111        &mut self,
112        composite_ty: wasmparser::CompositeType,
113    ) -> Result<crate::CompositeType, Error<Self::Error>> {
114        utils::composite_type(self, composite_ty)
115    }
116
117    fn entity_type(
118        &mut self,
119        type_ref: wasmparser::TypeRef,
120    ) -> Result<crate::EntityType, Error<Self::Error>> {
121        utils::entity_type(self, type_ref)
122    }
123
124    fn export_kind(
125        &mut self,
126        external_kind: wasmparser::ExternalKind,
127    ) -> Result<crate::ExportKind, Error<Self::Error>> {
128        Ok(utils::export_kind(self, external_kind))
129    }
130
131    fn field_type(
132        &mut self,
133        field_ty: wasmparser::FieldType,
134    ) -> Result<crate::FieldType, Error<Self::Error>> {
135        utils::field_type(self, field_ty)
136    }
137
138    fn func_type(
139        &mut self,
140        func_ty: wasmparser::FuncType,
141    ) -> Result<crate::FuncType, Error<Self::Error>> {
142        utils::func_type(self, func_ty)
143    }
144
145    fn cont_type(
146        &mut self,
147        cont_ty: wasmparser::ContType,
148    ) -> Result<crate::ContType, Error<Self::Error>> {
149        utils::cont_type(self, cont_ty)
150    }
151
152    fn global_type(
153        &mut self,
154        global_ty: wasmparser::GlobalType,
155    ) -> Result<crate::GlobalType, Error<Self::Error>> {
156        utils::global_type(self, global_ty)
157    }
158
159    fn handle(&mut self, on: wasmparser::Handle) -> Result<crate::Handle, Error<Self::Error>> {
160        utils::handle(self, on)
161    }
162
163    fn heap_type(
164        &mut self,
165        heap_type: wasmparser::HeapType,
166    ) -> Result<crate::HeapType, Error<Self::Error>> {
167        utils::heap_type(self, heap_type)
168    }
169
170    fn instruction<'a>(
171        &mut self,
172        arg: wasmparser::Operator<'a>,
173    ) -> Result<crate::Instruction<'a>, Error<Self::Error>> {
174        utils::instruction(self, arg)
175    }
176
177    fn memory_type(
178        &mut self,
179        memory_ty: wasmparser::MemoryType,
180    ) -> Result<crate::MemoryType, Error<Self::Error>> {
181        Ok(utils::memory_type(self, memory_ty))
182    }
183
184    fn ieee32_arg(&mut self, arg: wasmparser::Ieee32) -> Result<crate::Ieee32, Error<Self::Error>> {
185        Ok(utils::ieee32_arg(self, arg))
186    }
187
188    fn ieee64_arg(&mut self, arg: wasmparser::Ieee64) -> Result<crate::Ieee64, Error<Self::Error>> {
189        Ok(utils::ieee64_arg(self, arg))
190    }
191
192    fn mem_arg(&mut self, arg: wasmparser::MemArg) -> Result<crate::MemArg, Error<Self::Error>> {
193        utils::mem_arg(self, arg)
194    }
195
196    fn ordering(
197        &mut self,
198        arg: wasmparser::Ordering,
199    ) -> Result<crate::Ordering, Error<Self::Error>> {
200        Ok(utils::ordering(self, arg))
201    }
202
203    fn ref_type(
204        &mut self,
205        ref_type: wasmparser::RefType,
206    ) -> Result<crate::RefType, Error<Self::Error>> {
207        utils::ref_type(self, ref_type)
208    }
209
210    fn storage_type(
211        &mut self,
212        storage_ty: wasmparser::StorageType,
213    ) -> Result<crate::StorageType, Error<Self::Error>> {
214        utils::storage_type(self, storage_ty)
215    }
216
217    fn struct_type(
218        &mut self,
219        struct_ty: wasmparser::StructType,
220    ) -> Result<crate::StructType, Error<Self::Error>> {
221        utils::struct_type(self, struct_ty)
222    }
223
224    fn sub_type(
225        &mut self,
226        sub_ty: wasmparser::SubType,
227    ) -> Result<crate::SubType, Error<Self::Error>> {
228        utils::sub_type(self, sub_ty)
229    }
230
231    fn table_type(
232        &mut self,
233        table_ty: wasmparser::TableType,
234    ) -> Result<crate::TableType, Error<Self::Error>> {
235        utils::table_type(self, table_ty)
236    }
237
238    fn tag_kind(
239        &mut self,
240        kind: wasmparser::TagKind,
241    ) -> Result<crate::TagKind, Error<Self::Error>> {
242        Ok(utils::tag_kind(self, kind))
243    }
244
245    fn tag_type(
246        &mut self,
247        tag_ty: wasmparser::TagType,
248    ) -> Result<crate::TagType, Error<Self::Error>> {
249        utils::tag_type(self, tag_ty)
250    }
251
252    fn val_type(
253        &mut self,
254        val_ty: wasmparser::ValType,
255    ) -> Result<crate::ValType, Error<Self::Error>> {
256        utils::val_type(self, val_ty)
257    }
258
259    fn val_types(
260        &mut self,
261        val_tys: Vec<wasmparser::ValType>,
262    ) -> Result<Vec<crate::ValType>, Error<Self::Error>> {
263        val_tys
264            .iter()
265            .map(|ty| utils::val_type(self, *ty))
266            .collect()
267    }
268
269    /// Parses the input `section` given from the `wasmparser` crate and
270    /// adds the custom section to the `module`.
271    fn parse_custom_section(
272        &mut self,
273        module: &mut crate::Module,
274        section: wasmparser::CustomSectionReader<'_>,
275    ) -> Result<(), Error<Self::Error>> {
276        utils::parse_custom_section(self, module, section)
277    }
278
279    /// Converts the input `section` given from the `wasmparser` crate into an
280    /// encoded custom section.
281    fn custom_section<'a>(
282        &mut self,
283        section: wasmparser::CustomSectionReader<'a>,
284    ) -> Result<crate::CustomSection<'a>, Error<Self::Error>> {
285        Ok(utils::custom_section(self, section))
286    }
287
288    /// Parses the input `section` given from the `wasmparser` crate and adds
289    /// all the code to the `code` section.
290    fn parse_code_section(
291        &mut self,
292        code: &mut crate::CodeSection,
293        section: wasmparser::CodeSectionReader<'_>,
294    ) -> Result<(), Error<Self::Error>> {
295        utils::parse_code_section(self, code, section)
296    }
297
298    /// Parses a single [`wasmparser::FunctionBody`] and adds it to the `code` section.
299    fn parse_function_body(
300        &mut self,
301        code: &mut crate::CodeSection,
302        func: wasmparser::FunctionBody<'_>,
303    ) -> Result<(), Error<Self::Error>> {
304        utils::parse_function_body(self, code, func)
305    }
306
307    /// Create a new [`crate::Function`] by parsing the locals declarations from the
308    /// provided [`wasmparser::FunctionBody`].
309    fn new_function_with_parsed_locals(
310        &mut self,
311        func: &wasmparser::FunctionBody<'_>,
312    ) -> Result<crate::Function, Error<Self::Error>> {
313        utils::new_function_with_parsed_locals(self, func)
314    }
315
316    /// Parses a single instruction from `reader` and adds it to `function`.
317    fn parse_instruction<'a>(
318        &mut self,
319        reader: &mut wasmparser::OperatorsReader<'a>,
320    ) -> Result<crate::Instruction<'a>, Error<Self::Error>> {
321        utils::parse_instruction(self, reader)
322    }
323
324    /// Parses the input `section` given from the `wasmparser` crate and adds
325    /// all the data to the `data` section.
326    fn parse_data_section(
327        &mut self,
328        data: &mut crate::DataSection,
329        section: wasmparser::DataSectionReader<'_>,
330    ) -> Result<(), Error<Self::Error>> {
331        utils::parse_data_section(self, data, section)
332    }
333
334    /// Parses a single [`wasmparser::Data`] and adds it to the `data` section.
335    fn parse_data(
336        &mut self,
337        data: &mut crate::DataSection,
338        datum: wasmparser::Data<'_>,
339    ) -> Result<(), Error<Self::Error>> {
340        utils::parse_data(self, data, datum)
341    }
342
343    /// Parses the input `section` given from the `wasmparser` crate and adds
344    /// all the elements to the `element` section.
345    fn parse_element_section(
346        &mut self,
347        elements: &mut crate::ElementSection,
348        section: wasmparser::ElementSectionReader<'_>,
349    ) -> Result<(), Error<Self::Error>> {
350        utils::parse_element_section(self, elements, section)
351    }
352
353    /// Parses the single [`wasmparser::Element`] provided and adds it to the
354    /// `element` section.
355    fn parse_element(
356        &mut self,
357        elements: &mut crate::ElementSection,
358        element: wasmparser::Element<'_>,
359    ) -> Result<(), Error<Self::Error>> {
360        utils::parse_element(self, elements, element)
361    }
362
363    fn element_items<'a>(
364        &mut self,
365        items: wasmparser::ElementItems<'a>,
366    ) -> Result<crate::Elements<'a>, Error<Self::Error>> {
367        utils::element_items(self, items)
368    }
369
370    /// Parses the input `section` given from the `wasmparser` crate and adds
371    /// all the exports to the `exports` section.
372    fn parse_export_section(
373        &mut self,
374        exports: &mut crate::ExportSection,
375        section: wasmparser::ExportSectionReader<'_>,
376    ) -> Result<(), Error<Self::Error>> {
377        utils::parse_export_section(self, exports, section)
378    }
379
380    /// Parses the single [`wasmparser::Export`] provided and adds it to the
381    /// `exports` section.
382    fn parse_export(
383        &mut self,
384        exports: &mut crate::ExportSection,
385        export: wasmparser::Export<'_>,
386    ) -> Result<(), Error<Self::Error>> {
387        utils::parse_export(self, exports, export)
388    }
389
390    /// Parses the input `section` given from the `wasmparser` crate and adds
391    /// all the functions to the `functions` section.
392    fn parse_function_section(
393        &mut self,
394        functions: &mut crate::FunctionSection,
395        section: wasmparser::FunctionSectionReader<'_>,
396    ) -> Result<(), Error<Self::Error>> {
397        utils::parse_function_section(self, functions, section)
398    }
399
400    /// Parses the input `section` given from the `wasmparser` crate and adds
401    /// all the globals to the `globals` section.
402    fn parse_global_section(
403        &mut self,
404        globals: &mut crate::GlobalSection,
405        section: wasmparser::GlobalSectionReader<'_>,
406    ) -> Result<(), Error<Self::Error>> {
407        utils::parse_global_section(self, globals, section)
408    }
409
410    /// Parses the single [`wasmparser::Global`] provided and adds it to the
411    /// `globals` section.
412    fn parse_global(
413        &mut self,
414        globals: &mut crate::GlobalSection,
415        global: wasmparser::Global<'_>,
416    ) -> Result<(), Error<Self::Error>> {
417        utils::parse_global(self, globals, global)
418    }
419
420    /// Parses the input `section` given from the `wasmparser` crate and adds
421    /// all the imports to the `import` section.
422    fn parse_import_section(
423        &mut self,
424        imports: &mut crate::ImportSection,
425        section: wasmparser::ImportSectionReader<'_>,
426    ) -> Result<(), Error<Self::Error>> {
427        utils::parse_import_section(self, imports, section)
428    }
429
430    /// Parses a [`wasmparser::Imports`] and adds all of its contents to the
431    /// `import` section.
432    fn parse_imports(
433        &mut self,
434        import_section: &mut crate::ImportSection,
435        imports: wasmparser::Imports<'_>,
436    ) -> Result<(), Error<Self::Error>> {
437        utils::parse_imports(self, import_section, imports)
438    }
439
440    /// Parses the single [`wasmparser::Import`] provided and adds it to the
441    /// `import` section.
442    fn parse_import(
443        &mut self,
444        imports: &mut crate::ImportSection,
445        import: wasmparser::Import<'_>,
446    ) -> Result<(), Error<Self::Error>> {
447        utils::parse_import(self, imports, import)
448    }
449
450    /// Parses the input `section` given from the `wasmparser` crate and adds
451    /// all the memories to the `memories` section.
452    fn parse_memory_section(
453        &mut self,
454        memories: &mut crate::MemorySection,
455        section: wasmparser::MemorySectionReader<'_>,
456    ) -> Result<(), Error<Self::Error>> {
457        utils::parse_memory_section(self, memories, section)
458    }
459
460    /// Parses the input `section` given from the `wasmparser` crate and adds
461    /// all the tables to the `tables` section.
462    fn parse_table_section(
463        &mut self,
464        tables: &mut crate::TableSection,
465        section: wasmparser::TableSectionReader<'_>,
466    ) -> Result<(), Error<Self::Error>> {
467        utils::parse_table_section(self, tables, section)
468    }
469
470    /// Parses a single [`wasmparser::Table`] and adds it to the `tables` section.
471    fn parse_table(
472        &mut self,
473        tables: &mut crate::TableSection,
474        table: wasmparser::Table<'_>,
475    ) -> Result<(), Error<Self::Error>> {
476        utils::parse_table(self, tables, table)
477    }
478
479    /// Parses the input `section` given from the `wasmparser` crate and adds
480    /// all the tags to the `tags` section.
481    fn parse_tag_section(
482        &mut self,
483        tags: &mut crate::TagSection,
484        section: wasmparser::TagSectionReader<'_>,
485    ) -> Result<(), Error<Self::Error>> {
486        utils::parse_tag_section(self, tags, section)
487    }
488
489    /// Parses the input `section` given from the `wasmparser` crate and adds
490    /// all the types to the `types` section.
491    fn parse_type_section(
492        &mut self,
493        types: &mut crate::TypeSection,
494        section: wasmparser::TypeSectionReader<'_>,
495    ) -> Result<(), Error<Self::Error>> {
496        utils::parse_type_section(self, types, section)
497    }
498
499    /// Parses a single [`wasmparser::RecGroup`] and adds it to the `types` section.
500    fn parse_recursive_type_group(
501        &mut self,
502        encoder: CoreTypeEncoder,
503        rec_group: wasmparser::RecGroup,
504    ) -> Result<(), Error<Self::Error>> {
505        utils::parse_recursive_type_group(self, encoder, rec_group)
506    }
507
508    fn parse_unknown_section(
509        &mut self,
510        module: &mut crate::Module,
511        id: u8,
512        contents: &[u8],
513    ) -> Result<(), Error<Self::Error>> {
514        utils::parse_unknown_section(self, module, id, contents)
515    }
516
517    /// A hook method that is called inside [`Reencode::parse_core_module`]
518    /// before and after every non-custom core wasm section.
519    ///
520    /// This method can be used to insert new custom sections in between those
521    /// sections, or to detect when a non-custom section is missing and insert
522    /// it in the [proper order].
523    ///
524    /// The `after` parameter is `None` iff the hook is called before the first
525    /// non-custom section, and `Some(s)` afterwards, where `s` is the
526    /// [`SectionId`] of the previous non-custom section.
527    ///
528    /// The `before` parameter is `None` iff the hook is called after the last
529    /// non-custom section, and `Some(s)` beforehand, where `s` is the
530    /// [`SectionId`] of the following non-custom section.
531    ///
532    /// [proper order]: https://webassembly.github.io/spec/core/binary/modules.html#binary-module
533    /// [`SectionId`]: crate::SectionId
534    fn intersperse_section_hook(
535        &mut self,
536        module: &mut crate::Module,
537        after: Option<crate::SectionId>,
538        before: Option<crate::SectionId>,
539    ) -> Result<(), Error<Self::Error>> {
540        utils::intersperse_section_hook(self, module, after, before)
541    }
542
543    fn parse_core_module(
544        &mut self,
545        module: &mut crate::Module,
546        parser: wasmparser::Parser,
547        data: &[u8],
548    ) -> Result<(), Error<Self::Error>> {
549        utils::parse_core_module(self, module, parser, data)
550    }
551
552    fn custom_name_section(
553        &mut self,
554        section: wasmparser::NameSectionReader<'_>,
555    ) -> Result<crate::NameSection, Error<Self::Error>> {
556        utils::custom_name_section(self, section)
557    }
558
559    fn parse_custom_name_subsection(
560        &mut self,
561        names: &mut crate::NameSection,
562        section: wasmparser::Name<'_>,
563    ) -> Result<(), Error<Self::Error>> {
564        utils::parse_custom_name_subsection(self, names, section)
565    }
566
567    fn data_count(&mut self, count: u32) -> Result<u32, Error<Self::Error>> {
568        Ok(count)
569    }
570
571    fn start_section(&mut self, start: u32) -> Result<u32, Error<Self::Error>> {
572        self.function_index(start)
573    }
574}
575
576/// An error when re-encoding from `wasmparser` to `wasm-encoder`.
577#[derive(Debug)]
578pub enum Error<E = Infallible> {
579    /// There was a type reference that was canonicalized and no longer
580    /// references an index into a module's types space, so we cannot encode it
581    /// into a Wasm binary again.
582    CanonicalizedHeapTypeReference,
583    /// The const expression is invalid: not actually constant or something like
584    /// that.
585    InvalidConstExpr,
586    /// The code section size listed was not valid for the wasm binary provided.
587    InvalidCodeSectionSize,
588    /// There was a section that does not belong in a core wasm module.
589    UnexpectedNonCoreModuleSection,
590    /// There was a section that does not belong in a component module.
591    UnexpectedNonComponentSection,
592    /// A core type definition was found in a component that's not supported.
593    UnsupportedCoreTypeInComponent,
594    /// There was an error when parsing.
595    ParseError(wasmparser::Error),
596    /// There was a user-defined error when re-encoding.
597    UserError(E),
598}
599
600impl<E> From<wasmparser::Error> for Error<E> {
601    fn from(err: wasmparser::Error) -> Self {
602        Self::ParseError(err)
603    }
604}
605
606impl<E: core::fmt::Display> core::fmt::Display for Error<E> {
607    fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
608        match self {
609            Self::ParseError(_e) => {
610                write!(fmt, "There was an error when parsing")
611            }
612            Self::UserError(e) => write!(fmt, "{e}"),
613            Self::InvalidConstExpr => write!(fmt, "The const expression was invalid"),
614            Self::UnexpectedNonCoreModuleSection => write!(
615                fmt,
616                "There was a section that does not belong in a core wasm module"
617            ),
618            Self::UnexpectedNonComponentSection => write!(
619                fmt,
620                "There was a section that does not belong in a component"
621            ),
622            Self::CanonicalizedHeapTypeReference => write!(
623                fmt,
624                "There was a canonicalized heap type reference without type index information"
625            ),
626            Self::UnsupportedCoreTypeInComponent => {
627                fmt.write_str("unsupported core type in a component")
628            }
629            Self::InvalidCodeSectionSize => fmt.write_str("invalid code section size"),
630        }
631    }
632}
633
634impl<E: 'static + StdError> StdError for Error<E> {
635    fn source(&self) -> Option<&(dyn StdError + 'static)> {
636        match self {
637            Self::ParseError(e) => Some(e),
638            Self::UserError(e) => Some(e),
639            Self::InvalidConstExpr
640            | Self::CanonicalizedHeapTypeReference
641            | Self::UnexpectedNonCoreModuleSection
642            | Self::UnexpectedNonComponentSection
643            | Self::UnsupportedCoreTypeInComponent
644            | Self::InvalidCodeSectionSize => None,
645        }
646    }
647}
648
649/// Reencodes `wasmparser` into `wasm-encoder` so that the encoded wasm is
650/// identical to the input and can be parsed and encoded again.
651#[derive(Debug)]
652pub struct RoundtripReencoder;
653
654impl Reencode for RoundtripReencoder {
655    type Error = Infallible;
656}
657
658#[allow(missing_docs)] // FIXME
659pub mod utils {
660    use super::{Error, Reencode};
661    use crate::{CoreTypeEncoder, Encode, Imports};
662    use alloc::vec::Vec;
663    use core::ops::Range;
664
665    pub fn parse_core_module<T: ?Sized + Reencode>(
666        reencoder: &mut T,
667        module: &mut crate::Module,
668        parser: wasmparser::Parser,
669        data: &[u8],
670    ) -> Result<(), Error<T::Error>> {
671        fn handle_intersperse_section_hook<T: ?Sized + Reencode>(
672            reencoder: &mut T,
673            module: &mut crate::Module,
674            last_section: &mut Option<crate::SectionId>,
675            next_section: Option<crate::SectionId>,
676        ) -> Result<(), Error<T::Error>> {
677            let after = core::mem::replace(last_section, next_section);
678            let before = next_section;
679            reencoder.intersperse_section_hook(module, after, before)
680        }
681
682        let mut last_section = None;
683
684        let start_offset = parser.offset();
685        // Convert from `range` to a byte range within `data` while
686        // accounting for various offsets.
687        let get_original_section = |range: Range<u64>| {
688            let start = range.start - start_offset;
689            let end = range.end - start_offset;
690            let Ok(end) = usize::try_from(end) else {
691                return Err(Error::InvalidCodeSectionSize);
692            };
693            let data_range = start as usize..end;
694            data.get(data_range).ok_or(Error::InvalidCodeSectionSize)
695        };
696        for section in parser.clone().parse_all(data) {
697            match section? {
698                wasmparser::Payload::Version {
699                    encoding: wasmparser::Encoding::Module,
700                    ..
701                } => (),
702                wasmparser::Payload::Version { .. } => {
703                    return Err(Error::UnexpectedNonCoreModuleSection);
704                }
705                wasmparser::Payload::TypeSection(section) => {
706                    handle_intersperse_section_hook(
707                        reencoder,
708                        module,
709                        &mut last_section,
710                        Some(crate::SectionId::Type),
711                    )?;
712                    let mut types = crate::TypeSection::new();
713                    reencoder.parse_type_section(&mut types, section)?;
714                    module.section(&types);
715                }
716                wasmparser::Payload::ImportSection(section) => {
717                    handle_intersperse_section_hook(
718                        reencoder,
719                        module,
720                        &mut last_section,
721                        Some(crate::SectionId::Import),
722                    )?;
723                    let mut imports = crate::ImportSection::new();
724                    reencoder.parse_import_section(&mut imports, section)?;
725                    module.section(&imports);
726                }
727                wasmparser::Payload::FunctionSection(section) => {
728                    handle_intersperse_section_hook(
729                        reencoder,
730                        module,
731                        &mut last_section,
732                        Some(crate::SectionId::Function),
733                    )?;
734                    let mut functions = crate::FunctionSection::new();
735                    reencoder.parse_function_section(&mut functions, section)?;
736                    module.section(&functions);
737                }
738                wasmparser::Payload::TableSection(section) => {
739                    handle_intersperse_section_hook(
740                        reencoder,
741                        module,
742                        &mut last_section,
743                        Some(crate::SectionId::Table),
744                    )?;
745                    let mut tables = crate::TableSection::new();
746                    reencoder.parse_table_section(&mut tables, section)?;
747                    module.section(&tables);
748                }
749                wasmparser::Payload::MemorySection(section) => {
750                    handle_intersperse_section_hook(
751                        reencoder,
752                        module,
753                        &mut last_section,
754                        Some(crate::SectionId::Memory),
755                    )?;
756                    let mut memories = crate::MemorySection::new();
757                    reencoder.parse_memory_section(&mut memories, section)?;
758                    module.section(&memories);
759                }
760                wasmparser::Payload::TagSection(section) => {
761                    handle_intersperse_section_hook(
762                        reencoder,
763                        module,
764                        &mut last_section,
765                        Some(crate::SectionId::Tag),
766                    )?;
767                    let mut tags = crate::TagSection::new();
768                    reencoder.parse_tag_section(&mut tags, section)?;
769                    module.section(&tags);
770                }
771                wasmparser::Payload::GlobalSection(section) => {
772                    handle_intersperse_section_hook(
773                        reencoder,
774                        module,
775                        &mut last_section,
776                        Some(crate::SectionId::Global),
777                    )?;
778                    let mut globals = crate::GlobalSection::new();
779                    reencoder.parse_global_section(&mut globals, section)?;
780                    module.section(&globals);
781                }
782                wasmparser::Payload::ExportSection(section) => {
783                    handle_intersperse_section_hook(
784                        reencoder,
785                        module,
786                        &mut last_section,
787                        Some(crate::SectionId::Export),
788                    )?;
789                    let mut exports = crate::ExportSection::new();
790                    reencoder.parse_export_section(&mut exports, section)?;
791                    module.section(&exports);
792                }
793                wasmparser::Payload::StartSection { func, .. } => {
794                    handle_intersperse_section_hook(
795                        reencoder,
796                        module,
797                        &mut last_section,
798                        Some(crate::SectionId::Start),
799                    )?;
800                    module.section(&crate::StartSection {
801                        function_index: reencoder.start_section(func)?,
802                    });
803                }
804                wasmparser::Payload::ElementSection(section) => {
805                    handle_intersperse_section_hook(
806                        reencoder,
807                        module,
808                        &mut last_section,
809                        Some(crate::SectionId::Element),
810                    )?;
811                    let mut elements = crate::ElementSection::new();
812                    reencoder.parse_element_section(&mut elements, section)?;
813                    module.section(&elements);
814                }
815                wasmparser::Payload::DataCountSection { count, .. } => {
816                    handle_intersperse_section_hook(
817                        reencoder,
818                        module,
819                        &mut last_section,
820                        Some(crate::SectionId::DataCount),
821                    )?;
822                    let count = reencoder.data_count(count)?;
823                    module.section(&crate::DataCountSection { count });
824                }
825                wasmparser::Payload::DataSection(section) => {
826                    handle_intersperse_section_hook(
827                        reencoder,
828                        module,
829                        &mut last_section,
830                        Some(crate::SectionId::Data),
831                    )?;
832                    let mut data = crate::DataSection::new();
833                    reencoder.parse_data_section(&mut data, section)?;
834                    module.section(&data);
835                }
836                wasmparser::Payload::CodeSectionStart {
837                    unchecked_range, ..
838                } => {
839                    handle_intersperse_section_hook(
840                        reencoder,
841                        module,
842                        &mut last_section,
843                        Some(crate::SectionId::Code),
844                    )?;
845                    let mut codes = crate::CodeSection::new();
846
847                    // Crate a `CodeSectionReader` (which notably the payload
848                    // does not give us here) and recurse with that. This means
849                    // that users overriding `parse_code_section` always get
850                    // that function called.
851                    let section = get_original_section(unchecked_range.clone())?;
852                    let reader = parser.binary_reader(section, unchecked_range.start);
853                    let section = wasmparser::CodeSectionReader::new(reader)?;
854                    reencoder.parse_code_section(&mut codes, section)?;
855                    module.section(&codes);
856                }
857
858                // Parsing of code section entries (function bodies) happens
859                // above during the handling of the code section. That means
860                // that we just skip all these payloads.
861                wasmparser::Payload::CodeSectionEntry(_) => {}
862
863                #[cfg(feature = "component-model")]
864                wasmparser::Payload::ModuleSection { .. }
865                | wasmparser::Payload::InstanceSection(_)
866                | wasmparser::Payload::CoreTypeSection(_)
867                | wasmparser::Payload::ComponentSection { .. }
868                | wasmparser::Payload::ComponentInstanceSection(_)
869                | wasmparser::Payload::ComponentAliasSection(_)
870                | wasmparser::Payload::ComponentTypeSection(_)
871                | wasmparser::Payload::ComponentCanonicalSection(_)
872                | wasmparser::Payload::ComponentStartSection { .. }
873                | wasmparser::Payload::ComponentImportSection(_)
874                | wasmparser::Payload::ComponentExportSection(_) => {
875                    return Err(Error::UnexpectedNonCoreModuleSection);
876                }
877                wasmparser::Payload::CustomSection(section) => {
878                    reencoder.parse_custom_section(module, section)?;
879                }
880                wasmparser::Payload::End(_) => {
881                    handle_intersperse_section_hook(reencoder, module, &mut last_section, None)?;
882                }
883
884                other => match other.as_section() {
885                    Some((id, range)) => {
886                        let section = get_original_section(range)?;
887                        reencoder.parse_unknown_section(module, id, section)?;
888                    }
889                    None => unreachable!(),
890                },
891            }
892        }
893
894        Ok(())
895    }
896
897    /// A hook method that is called inside [`Reencode::parse_core_module`]
898    /// before and after every non-custom core wasm section.
899    ///
900    /// This method can be used to insert new custom sections in between those
901    /// sections, or to detect when a non-custom section is missing and insert
902    /// it in the [proper order].
903    ///
904    /// The `after` parameter is `None` iff the hook is called before the first
905    /// non-custom section, and `Some(s)` afterwards, where `s` is the
906    /// [`SectionId`] of the previous non-custom section.
907    ///
908    /// The `before` parameter is `None` iff the hook is called after the last
909    /// non-custom section, and `Some(s)` beforehand, where `s` is the
910    /// [`SectionId`] of the following non-custom section.
911    ///
912    /// [proper order]: https://webassembly.github.io/spec/core/binary/modules.html#binary-module
913    /// [`SectionId`]: crate::SectionId
914    pub fn intersperse_section_hook<T: ?Sized + Reencode>(
915        _reencoder: &mut T,
916        _module: &mut crate::Module,
917        _after: Option<crate::SectionId>,
918        _before: Option<crate::SectionId>,
919    ) -> Result<(), Error<T::Error>> {
920        Ok(())
921    }
922
923    pub fn memory_index<T: ?Sized + Reencode>(_reencoder: &mut T, memory: u32) -> u32 {
924        memory
925    }
926
927    pub fn ieee32_arg<T: ?Sized + Reencode>(
928        _reencoder: &mut T,
929        arg: wasmparser::Ieee32,
930    ) -> crate::Ieee32 {
931        crate::Ieee32(arg.bits())
932    }
933
934    pub fn ieee64_arg<T: ?Sized + Reencode>(
935        _reencoder: &mut T,
936        arg: wasmparser::Ieee64,
937    ) -> crate::Ieee64 {
938        crate::Ieee64(arg.bits())
939    }
940
941    pub fn mem_arg<T: ?Sized + Reencode>(
942        reencoder: &mut T,
943        arg: wasmparser::MemArg,
944    ) -> Result<crate::MemArg, Error<T::Error>> {
945        Ok(crate::MemArg {
946            offset: arg.offset,
947            align: arg.align.into(),
948            target: match arg.target {
949                wasmparser::MemArgTarget::Memory(i) => {
950                    crate::MemArgTarget::Memory(reencoder.memory_index(i)?)
951                }
952                wasmparser::MemArgTarget::Array(ty) => {
953                    crate::MemArgTarget::Array(reencoder.type_index(ty)?)
954                }
955            },
956            ordering: match arg.ordering {
957                None => None,
958                Some(wasmparser::MemArgOrdering::Op(o)) => {
959                    Some(crate::MemArgOrdering::Op(reencoder.ordering(o)?))
960                }
961                Some(wasmparser::MemArgOrdering::Rmw(o)) => {
962                    Some(crate::MemArgOrdering::Rmw(reencoder.ordering(o)?))
963                }
964            },
965        })
966    }
967
968    pub fn ordering<T: ?Sized + Reencode>(
969        _reencoder: &mut T,
970        arg: wasmparser::Ordering,
971    ) -> crate::Ordering {
972        match arg {
973            wasmparser::Ordering::SeqCst => crate::Ordering::SeqCst,
974            wasmparser::Ordering::AcqRel => crate::Ordering::AcqRel,
975        }
976    }
977
978    pub fn function_index<T: ?Sized + Reencode>(_reencoder: &mut T, func: u32) -> u32 {
979        func
980    }
981
982    pub fn tag_index<T: ?Sized + Reencode>(_reencoder: &mut T, tag: u32) -> u32 {
983        tag
984    }
985
986    pub fn catch<T: ?Sized + Reencode>(
987        reencoder: &mut T,
988        arg: wasmparser::Catch,
989    ) -> Result<crate::Catch, Error<T::Error>> {
990        Ok(match arg {
991            wasmparser::Catch::One { tag, label } => crate::Catch::One {
992                tag: reencoder.tag_index(tag)?,
993                label,
994            },
995            wasmparser::Catch::OneRef { tag, label } => crate::Catch::OneRef {
996                tag: reencoder.tag_index(tag)?,
997                label,
998            },
999            wasmparser::Catch::All { label } => crate::Catch::All { label },
1000            wasmparser::Catch::AllRef { label } => crate::Catch::AllRef { label },
1001        })
1002    }
1003
1004    pub fn handle<T: ?Sized + Reencode>(
1005        reencoder: &mut T,
1006        arg: wasmparser::Handle,
1007    ) -> Result<crate::Handle, Error<T::Error>> {
1008        Ok(match arg {
1009            wasmparser::Handle::OnLabel { tag, label } => crate::Handle::OnLabel {
1010                tag: reencoder.tag_index(tag)?,
1011                label,
1012            },
1013            wasmparser::Handle::OnSwitch { tag } => crate::Handle::OnSwitch {
1014                tag: reencoder.tag_index(tag)?,
1015            },
1016        })
1017    }
1018
1019    /// Parses the input `section` given from the `wasmparser` crate and
1020    /// adds the custom section to the `module`.
1021    pub fn parse_custom_section<T: ?Sized + Reencode>(
1022        reencoder: &mut T,
1023        module: &mut crate::Module,
1024        section: wasmparser::CustomSectionReader<'_>,
1025    ) -> Result<(), Error<T::Error>> {
1026        match section.as_known() {
1027            wasmparser::KnownCustom::Name(name) => {
1028                module.section(&reencoder.custom_name_section(name)?);
1029            }
1030            _ => {
1031                module.section(&reencoder.custom_section(section)?);
1032            }
1033        }
1034        Ok(())
1035    }
1036
1037    /// Converts the input `section` given from the `wasmparser` crate into an
1038    /// encoded custom section.
1039    pub fn custom_section<'a, T: ?Sized + Reencode>(
1040        _reencoder: &mut T,
1041        section: wasmparser::CustomSectionReader<'a>,
1042    ) -> crate::CustomSection<'a> {
1043        crate::CustomSection {
1044            data: section.data().into(),
1045            name: section.name().into(),
1046        }
1047    }
1048
1049    pub fn export_kind<T: ?Sized + Reencode>(
1050        _reencoder: &mut T,
1051        external_kind: wasmparser::ExternalKind,
1052    ) -> crate::ExportKind {
1053        match external_kind {
1054            wasmparser::ExternalKind::Func | wasmparser::ExternalKind::FuncExact => {
1055                crate::ExportKind::Func
1056            }
1057            wasmparser::ExternalKind::Table => crate::ExportKind::Table,
1058            wasmparser::ExternalKind::Memory => crate::ExportKind::Memory,
1059            wasmparser::ExternalKind::Global => crate::ExportKind::Global,
1060            wasmparser::ExternalKind::Tag => crate::ExportKind::Tag,
1061        }
1062    }
1063
1064    pub fn memory_type<T: ?Sized + Reencode>(
1065        _reencoder: &mut T,
1066        memory_ty: wasmparser::MemoryType,
1067    ) -> crate::MemoryType {
1068        crate::MemoryType {
1069            minimum: memory_ty.initial,
1070            maximum: memory_ty.maximum,
1071            memory64: memory_ty.memory64,
1072            shared: memory_ty.shared,
1073            page_size_log2: memory_ty.page_size_log2,
1074        }
1075    }
1076
1077    pub fn tag_kind<T: ?Sized + Reencode>(
1078        _reencoder: &mut T,
1079        kind: wasmparser::TagKind,
1080    ) -> crate::TagKind {
1081        match kind {
1082            wasmparser::TagKind::Exception => crate::TagKind::Exception,
1083        }
1084    }
1085
1086    pub fn type_index<T: ?Sized + Reencode>(_reencoder: &mut T, ty: u32) -> u32 {
1087        ty
1088    }
1089
1090    pub fn type_index_unpacked<T: ?Sized + Reencode>(
1091        reencoder: &mut T,
1092        ty: wasmparser::UnpackedIndex,
1093    ) -> Result<u32, Error<T::Error>> {
1094        ty.as_module_index()
1095            .ok_or(Error::CanonicalizedHeapTypeReference)
1096            .and_then(|ty| reencoder.type_index(ty))
1097    }
1098
1099    pub fn tag_type<T: ?Sized + Reencode>(
1100        reencoder: &mut T,
1101        tag_ty: wasmparser::TagType,
1102    ) -> Result<crate::TagType, Error<T::Error>> {
1103        Ok(crate::TagType {
1104            kind: reencoder.tag_kind(tag_ty.kind)?,
1105            func_type_idx: reencoder.type_index(tag_ty.func_type_idx)?,
1106        })
1107    }
1108
1109    pub fn abstract_heap_type<T: ?Sized + Reencode>(
1110        _reencoder: &mut T,
1111        value: wasmparser::AbstractHeapType,
1112    ) -> crate::AbstractHeapType {
1113        use wasmparser::AbstractHeapType::*;
1114        match value {
1115            Func => crate::AbstractHeapType::Func,
1116            Extern => crate::AbstractHeapType::Extern,
1117            Any => crate::AbstractHeapType::Any,
1118            None => crate::AbstractHeapType::None,
1119            NoExtern => crate::AbstractHeapType::NoExtern,
1120            NoFunc => crate::AbstractHeapType::NoFunc,
1121            Eq => crate::AbstractHeapType::Eq,
1122            Struct => crate::AbstractHeapType::Struct,
1123            Array => crate::AbstractHeapType::Array,
1124            I31 => crate::AbstractHeapType::I31,
1125            Exn => crate::AbstractHeapType::Exn,
1126            NoExn => crate::AbstractHeapType::NoExn,
1127            Cont => crate::AbstractHeapType::Cont,
1128            NoCont => crate::AbstractHeapType::NoCont,
1129        }
1130    }
1131
1132    /// Parses the input `section` given from the `wasmparser` crate and adds
1133    /// all the types to the `types` section.
1134    pub fn parse_type_section<T: ?Sized + Reencode>(
1135        reencoder: &mut T,
1136        types: &mut crate::TypeSection,
1137        section: wasmparser::TypeSectionReader<'_>,
1138    ) -> Result<(), Error<T::Error>> {
1139        for rec_group in section {
1140            reencoder.parse_recursive_type_group(types.ty(), rec_group?)?;
1141        }
1142        Ok(())
1143    }
1144
1145    /// Parses a single [`wasmparser::RecGroup`] and adds it to the `types` section.
1146    pub fn parse_recursive_type_group<T: ?Sized + Reencode>(
1147        reencoder: &mut T,
1148        encoder: CoreTypeEncoder,
1149        rec_group: wasmparser::RecGroup,
1150    ) -> Result<(), Error<T::Error>> {
1151        if rec_group.is_explicit_rec_group() {
1152            let subtypes = rec_group
1153                .into_types()
1154                .map(|t| reencoder.sub_type(t))
1155                .collect::<Result<Vec<_>, _>>()?;
1156            encoder.rec(subtypes);
1157        } else {
1158            let ty = rec_group.into_types().next().unwrap();
1159            encoder.subtype(&reencoder.sub_type(ty)?);
1160        }
1161        Ok(())
1162    }
1163
1164    pub fn sub_type<T: ?Sized + Reencode>(
1165        reencoder: &mut T,
1166        sub_ty: wasmparser::SubType,
1167    ) -> Result<crate::SubType, Error<T::Error>> {
1168        Ok(crate::SubType {
1169            is_final: sub_ty.is_final,
1170            supertype_idxs: sub_ty
1171                .supertype_idxs
1172                .iter()
1173                .map(|i| reencoder.type_index_unpacked(i.unpack()))
1174                .collect::<Result<Vec<_>, _>>()?,
1175            composite_type: reencoder.composite_type(sub_ty.composite_type)?,
1176        })
1177    }
1178
1179    pub fn composite_type<T: ?Sized + Reencode>(
1180        reencoder: &mut T,
1181        composite_ty: wasmparser::CompositeType,
1182    ) -> Result<crate::CompositeType, Error<T::Error>> {
1183        let inner = match composite_ty.inner {
1184            wasmparser::CompositeInnerType::Func(f) => {
1185                crate::CompositeInnerType::Func(reencoder.func_type(f)?)
1186            }
1187            wasmparser::CompositeInnerType::Array(a) => {
1188                crate::CompositeInnerType::Array(reencoder.array_type(a)?)
1189            }
1190            wasmparser::CompositeInnerType::Struct(s) => {
1191                crate::CompositeInnerType::Struct(reencoder.struct_type(s)?)
1192            }
1193            wasmparser::CompositeInnerType::Cont(c) => {
1194                crate::CompositeInnerType::Cont(reencoder.cont_type(c)?)
1195            }
1196        };
1197        Ok(crate::CompositeType {
1198            inner,
1199            shared: composite_ty.shared,
1200            descriptor: composite_ty
1201                .descriptor_idx
1202                .map(|i| reencoder.type_index_unpacked(i.unpack()))
1203                .transpose()?,
1204            describes: composite_ty
1205                .describes_idx
1206                .map(|i| reencoder.type_index_unpacked(i.unpack()))
1207                .transpose()?,
1208        })
1209    }
1210
1211    pub fn func_type<T: ?Sized + Reencode>(
1212        reencoder: &mut T,
1213        func_ty: wasmparser::FuncType,
1214    ) -> Result<crate::FuncType, Error<T::Error>> {
1215        let mut buf = Vec::with_capacity(func_ty.params().len() + func_ty.results().len());
1216        for ty in func_ty.params().iter().chain(func_ty.results()).copied() {
1217            buf.push(reencoder.val_type(ty)?);
1218        }
1219        Ok(crate::FuncType::from_parts(
1220            buf.into(),
1221            func_ty.params().len(),
1222        ))
1223    }
1224
1225    pub fn array_type<T: ?Sized + Reencode>(
1226        reencoder: &mut T,
1227        array_ty: wasmparser::ArrayType,
1228    ) -> Result<crate::ArrayType, Error<T::Error>> {
1229        Ok(crate::ArrayType(reencoder.field_type(array_ty.0)?))
1230    }
1231
1232    pub fn struct_type<T: ?Sized + Reencode>(
1233        reencoder: &mut T,
1234        struct_ty: wasmparser::StructType,
1235    ) -> Result<crate::StructType, Error<T::Error>> {
1236        Ok(crate::StructType {
1237            fields: struct_ty
1238                .fields
1239                .iter()
1240                .map(|field_ty| reencoder.field_type(*field_ty))
1241                .collect::<Result<_, _>>()?,
1242        })
1243    }
1244
1245    pub fn field_type<T: ?Sized + Reencode>(
1246        reencoder: &mut T,
1247        field_ty: wasmparser::FieldType,
1248    ) -> Result<crate::FieldType, Error<T::Error>> {
1249        Ok(crate::FieldType {
1250            element_type: reencoder.storage_type(field_ty.element_type)?,
1251            mutable: field_ty.mutable,
1252        })
1253    }
1254
1255    pub fn storage_type<T: ?Sized + Reencode>(
1256        reencoder: &mut T,
1257        storage_ty: wasmparser::StorageType,
1258    ) -> Result<crate::StorageType, Error<T::Error>> {
1259        Ok(match storage_ty {
1260            wasmparser::StorageType::I8 => crate::StorageType::I8,
1261            wasmparser::StorageType::I16 => crate::StorageType::I16,
1262            wasmparser::StorageType::Val(v) => crate::StorageType::Val(reencoder.val_type(v)?),
1263        })
1264    }
1265
1266    pub fn cont_type<T: ?Sized + Reencode>(
1267        reencoder: &mut T,
1268        cont_ty: wasmparser::ContType,
1269    ) -> Result<crate::ContType, Error<T::Error>> {
1270        Ok(crate::ContType(
1271            reencoder.type_index_unpacked(cont_ty.0.unpack())?,
1272        ))
1273    }
1274
1275    pub fn val_type<T: ?Sized + Reencode>(
1276        reencoder: &mut T,
1277        val_ty: wasmparser::ValType,
1278    ) -> Result<crate::ValType, Error<T::Error>> {
1279        Ok(match val_ty {
1280            wasmparser::ValType::I32 => crate::ValType::I32,
1281            wasmparser::ValType::I64 => crate::ValType::I64,
1282            wasmparser::ValType::F32 => crate::ValType::F32,
1283            wasmparser::ValType::F64 => crate::ValType::F64,
1284            wasmparser::ValType::V128 => crate::ValType::V128,
1285            wasmparser::ValType::Ref(r) => crate::ValType::Ref(reencoder.ref_type(r)?),
1286        })
1287    }
1288
1289    pub fn ref_type<T: ?Sized + Reencode>(
1290        reencoder: &mut T,
1291        ref_type: wasmparser::RefType,
1292    ) -> Result<crate::RefType, Error<T::Error>> {
1293        Ok(crate::RefType {
1294            nullable: ref_type.is_nullable(),
1295            heap_type: reencoder.heap_type(ref_type.heap_type())?,
1296        })
1297    }
1298
1299    pub fn heap_type<T: ?Sized + Reencode>(
1300        reencoder: &mut T,
1301        heap_type: wasmparser::HeapType,
1302    ) -> Result<crate::HeapType, Error<T::Error>> {
1303        Ok(match heap_type {
1304            wasmparser::HeapType::Concrete(i) => {
1305                crate::HeapType::Concrete(reencoder.type_index_unpacked(i)?)
1306            }
1307            wasmparser::HeapType::Exact(i) => {
1308                crate::HeapType::Exact(reencoder.type_index_unpacked(i)?)
1309            }
1310            wasmparser::HeapType::Abstract { shared, ty } => crate::HeapType::Abstract {
1311                shared,
1312                ty: reencoder.abstract_heap_type(ty)?,
1313            },
1314        })
1315    }
1316
1317    /// Parses the input `section` given from the `wasmparser` crate and adds
1318    /// all the tables to the `tables` section.
1319    pub fn parse_table_section<T: ?Sized + Reencode>(
1320        reencoder: &mut T,
1321        tables: &mut crate::TableSection,
1322        section: wasmparser::TableSectionReader<'_>,
1323    ) -> Result<(), Error<T::Error>> {
1324        for table in section {
1325            reencoder.parse_table(tables, table?)?;
1326        }
1327        Ok(())
1328    }
1329
1330    /// Parses a single [`wasmparser::Table`] and adds it to the `tables` section.
1331    pub fn parse_table<T: ?Sized + Reencode>(
1332        reencoder: &mut T,
1333        tables: &mut crate::TableSection,
1334        table: wasmparser::Table<'_>,
1335    ) -> Result<(), Error<T::Error>> {
1336        let ty = reencoder.table_type(table.ty)?;
1337        match table.init {
1338            wasmparser::TableInit::RefNull => {
1339                tables.table(ty);
1340            }
1341            wasmparser::TableInit::Expr(e) => {
1342                tables.table_with_init(ty, &reencoder.const_expr(e)?);
1343            }
1344        }
1345        Ok(())
1346    }
1347
1348    pub fn table_type<T: ?Sized + Reencode>(
1349        reencoder: &mut T,
1350        table_ty: wasmparser::TableType,
1351    ) -> Result<crate::TableType, Error<T::Error>> {
1352        Ok(crate::TableType {
1353            element_type: reencoder.ref_type(table_ty.element_type)?,
1354            minimum: table_ty.initial,
1355            maximum: table_ty.maximum,
1356            table64: table_ty.table64,
1357            shared: table_ty.shared,
1358        })
1359    }
1360
1361    /// Parses the input `section` given from the `wasmparser` crate and adds
1362    /// all the tags to the `tags` section.
1363    pub fn parse_tag_section<T: ?Sized + Reencode>(
1364        reencoder: &mut T,
1365        tags: &mut crate::TagSection,
1366        section: wasmparser::TagSectionReader<'_>,
1367    ) -> Result<(), Error<T::Error>> {
1368        for tag in section {
1369            let tag = tag?;
1370            tags.tag(reencoder.tag_type(tag)?);
1371        }
1372        Ok(())
1373    }
1374
1375    /// Parses the input `section` given from the `wasmparser` crate and adds
1376    /// all the exports to the `exports` section.
1377    pub fn parse_export_section<T: ?Sized + Reencode>(
1378        reencoder: &mut T,
1379        exports: &mut crate::ExportSection,
1380        section: wasmparser::ExportSectionReader<'_>,
1381    ) -> Result<(), Error<T::Error>> {
1382        for export in section {
1383            reencoder.parse_export(exports, export?)?;
1384        }
1385        Ok(())
1386    }
1387
1388    /// Parses the single [`wasmparser::Export`] provided and adds it to the
1389    /// `exports` section.
1390    pub fn parse_export<T: ?Sized + Reencode>(
1391        reencoder: &mut T,
1392        exports: &mut crate::ExportSection,
1393        export: wasmparser::Export<'_>,
1394    ) -> Result<(), Error<T::Error>> {
1395        exports.export(
1396            export.name,
1397            reencoder.export_kind(export.kind)?,
1398            reencoder.external_index(export.kind, export.index)?,
1399        );
1400        Ok(())
1401    }
1402
1403    /// Parses the input `section` given from the `wasmparser` crate and adds
1404    /// all the globals to the `globals` section.
1405    pub fn parse_global_section<T: ?Sized + Reencode>(
1406        reencoder: &mut T,
1407        globals: &mut crate::GlobalSection,
1408        section: wasmparser::GlobalSectionReader<'_>,
1409    ) -> Result<(), Error<T::Error>> {
1410        for global in section {
1411            reencoder.parse_global(globals, global?)?;
1412        }
1413        Ok(())
1414    }
1415
1416    /// Parses the single [`wasmparser::Global`] provided and adds it to the
1417    /// `globals` section.
1418    pub fn parse_global<T: ?Sized + Reencode>(
1419        reencoder: &mut T,
1420        globals: &mut crate::GlobalSection,
1421        global: wasmparser::Global<'_>,
1422    ) -> Result<(), Error<T::Error>> {
1423        globals.global(
1424            reencoder.global_type(global.ty)?,
1425            &reencoder.const_expr(global.init_expr)?,
1426        );
1427        Ok(())
1428    }
1429
1430    pub fn global_type<T: ?Sized + Reencode>(
1431        reencoder: &mut T,
1432        global_ty: wasmparser::GlobalType,
1433    ) -> Result<crate::GlobalType, Error<T::Error>> {
1434        Ok(crate::GlobalType {
1435            val_type: reencoder.val_type(global_ty.content_type)?,
1436            mutable: global_ty.mutable,
1437            shared: global_ty.shared,
1438        })
1439    }
1440
1441    pub fn entity_type<T: ?Sized + Reencode>(
1442        reencoder: &mut T,
1443        type_ref: wasmparser::TypeRef,
1444    ) -> Result<crate::EntityType, Error<T::Error>> {
1445        Ok(match type_ref {
1446            wasmparser::TypeRef::Func(i) => crate::EntityType::Function(reencoder.type_index(i)?),
1447            wasmparser::TypeRef::FuncExact(i) => {
1448                crate::EntityType::FunctionExact(reencoder.type_index(i)?)
1449            }
1450            wasmparser::TypeRef::Table(t) => crate::EntityType::Table(reencoder.table_type(t)?),
1451            wasmparser::TypeRef::Memory(m) => crate::EntityType::Memory(reencoder.memory_type(m)?),
1452            wasmparser::TypeRef::Global(g) => crate::EntityType::Global(reencoder.global_type(g)?),
1453            wasmparser::TypeRef::Tag(t) => crate::EntityType::Tag(reencoder.tag_type(t)?),
1454        })
1455    }
1456
1457    /// Parses the input `section` given from the `wasmparser` crate and adds
1458    /// all the imports to the `import` section.
1459    pub fn parse_import_section<T: ?Sized + Reencode>(
1460        reencoder: &mut T,
1461        import_section: &mut crate::ImportSection,
1462        section: wasmparser::ImportSectionReader<'_>,
1463    ) -> Result<(), Error<T::Error>> {
1464        for imports in section {
1465            let imports = imports?;
1466            reencoder.parse_imports(import_section, imports)?;
1467        }
1468        Ok(())
1469    }
1470
1471    /// Parses a [`wasmparser::Imports`] and adds all of its contents to the
1472    /// `import` section.
1473    pub fn parse_imports<T: ?Sized + Reencode>(
1474        reencoder: &mut T,
1475        import_section: &mut crate::ImportSection,
1476        imports: wasmparser::Imports<'_>,
1477    ) -> Result<(), Error<T::Error>> {
1478        import_section.imports(match imports {
1479            wasmparser::Imports::Single(_, import) => Imports::Single(crate::Import {
1480                module: import.module,
1481                name: import.name,
1482                ty: reencoder.entity_type(import.ty)?,
1483            }),
1484            wasmparser::Imports::Compact1 { module, items } => {
1485                let mut new_items: Vec<crate::ImportCompact> = Vec::new();
1486                for item in items {
1487                    let item = item?;
1488                    new_items.push(crate::ImportCompact {
1489                        name: item.name,
1490                        ty: reencoder.entity_type(item.ty)?,
1491                    })
1492                }
1493                Imports::Compact1 {
1494                    module: module,
1495                    items: new_items.into(),
1496                }
1497            }
1498            wasmparser::Imports::Compact2 { module, ty, names } => {
1499                let names = names.into_iter().collect::<wasmparser::Result<Vec<_>>>()?;
1500                Imports::Compact2 {
1501                    module: module,
1502                    ty: reencoder.entity_type(ty)?,
1503                    names: names.into(),
1504                }
1505            }
1506        });
1507        Ok(())
1508    }
1509
1510    /// Parses the single [`wasmparser::Import`] provided and adds it to the
1511    /// `import` section.
1512    pub fn parse_import<T: ?Sized + Reencode>(
1513        reencoder: &mut T,
1514        imports: &mut crate::ImportSection,
1515        import: wasmparser::Import<'_>,
1516    ) -> Result<(), Error<T::Error>> {
1517        reencoder.parse_imports(imports, wasmparser::Imports::Single(0, import))?;
1518        Ok(())
1519    }
1520
1521    /// Parses the input `section` given from the `wasmparser` crate and adds
1522    /// all the memories to the `memories` section.
1523    pub fn parse_memory_section<T: ?Sized + Reencode>(
1524        reencoder: &mut T,
1525        memories: &mut crate::MemorySection,
1526        section: wasmparser::MemorySectionReader<'_>,
1527    ) -> Result<(), Error<T::Error>> {
1528        for memory in section {
1529            let memory = memory?;
1530            memories.memory(reencoder.memory_type(memory)?);
1531        }
1532        Ok(())
1533    }
1534
1535    /// Parses the input `section` given from the `wasmparser` crate and adds
1536    /// all the functions to the `functions` section.
1537    pub fn parse_function_section<T: ?Sized + Reencode>(
1538        reencoder: &mut T,
1539        functions: &mut crate::FunctionSection,
1540        section: wasmparser::FunctionSectionReader<'_>,
1541    ) -> Result<(), Error<T::Error>> {
1542        for func in section {
1543            functions.function(reencoder.type_index(func?)?);
1544        }
1545        Ok(())
1546    }
1547
1548    /// Parses the input `section` given from the `wasmparser` crate and adds
1549    /// all the data to the `data` section.
1550    pub fn parse_data_section<T: ?Sized + Reencode>(
1551        reencoder: &mut T,
1552        data: &mut crate::DataSection,
1553        section: wasmparser::DataSectionReader<'_>,
1554    ) -> Result<(), Error<T::Error>> {
1555        for datum in section {
1556            reencoder.parse_data(data, datum?)?;
1557        }
1558        Ok(())
1559    }
1560
1561    /// Parses a single [`wasmparser::Data`] and adds it to the `data` section.
1562    pub fn parse_data<T: ?Sized + Reencode>(
1563        reencoder: &mut T,
1564        data: &mut crate::DataSection,
1565        datum: wasmparser::Data<'_>,
1566    ) -> Result<(), Error<T::Error>> {
1567        match datum.kind {
1568            wasmparser::DataKind::Active {
1569                memory_index,
1570                offset_expr,
1571            } => data.active(
1572                reencoder.memory_index(memory_index)?,
1573                &reencoder.const_expr(offset_expr)?,
1574                datum.data.iter().copied(),
1575            ),
1576            wasmparser::DataKind::Passive => data.passive(datum.data.iter().copied()),
1577        };
1578        Ok(())
1579    }
1580
1581    /// Parses the input `section` given from the `wasmparser` crate and adds
1582    /// all the elements to the `element` section.
1583    pub fn parse_element_section<T: ?Sized + Reencode>(
1584        reencoder: &mut T,
1585        elements: &mut crate::ElementSection,
1586        section: wasmparser::ElementSectionReader<'_>,
1587    ) -> Result<(), Error<T::Error>> {
1588        for element in section {
1589            reencoder.parse_element(elements, element?)?;
1590        }
1591        Ok(())
1592    }
1593
1594    /// Parses the single [`wasmparser::Element`] provided and adds it to the
1595    /// `element` section.
1596    pub fn parse_element<T: ?Sized + Reencode>(
1597        reencoder: &mut T,
1598        elements: &mut crate::ElementSection,
1599        element: wasmparser::Element<'_>,
1600    ) -> Result<(), Error<T::Error>> {
1601        let elems = reencoder.element_items(element.items)?;
1602        match element.kind {
1603            wasmparser::ElementKind::Active {
1604                table_index,
1605                offset_expr,
1606            } => elements.active(
1607                // Inform the reencoder that a table index is being used even if
1608                // it's not actually present here. That helps wasm-mutate for
1609                // example which wants to track uses to know when it's ok to
1610                // remove a table.
1611                //
1612                // If the table index started at `None` and is still zero then
1613                // preserve this encoding and keep it at `None`. Otherwise if
1614                // the result is nonzero or it was previously nonzero then keep
1615                // that encoding too.
1616                match (
1617                    table_index,
1618                    reencoder.table_index(table_index.unwrap_or(0))?,
1619                ) {
1620                    (None, 0) => None,
1621                    (_, n) => Some(n),
1622                },
1623                &reencoder.const_expr(offset_expr)?,
1624                elems,
1625            ),
1626            wasmparser::ElementKind::Passive => elements.passive(elems),
1627            wasmparser::ElementKind::Declared => elements.declared(elems),
1628        };
1629        Ok(())
1630    }
1631
1632    pub fn element_items<'a, T: ?Sized + Reencode>(
1633        reencoder: &mut T,
1634        items: wasmparser::ElementItems<'a>,
1635    ) -> Result<crate::Elements<'a>, Error<T::Error>> {
1636        Ok(match items {
1637            wasmparser::ElementItems::Functions(f) => {
1638                let mut funcs = Vec::new();
1639                for func in f {
1640                    funcs.push(reencoder.function_index(func?)?);
1641                }
1642                crate::Elements::Functions(funcs.into())
1643            }
1644            wasmparser::ElementItems::Expressions(ty, e) => {
1645                let mut exprs = Vec::new();
1646                for expr in e {
1647                    exprs.push(reencoder.const_expr(expr?)?);
1648                }
1649                crate::Elements::Expressions(reencoder.ref_type(ty)?, exprs.into())
1650            }
1651        })
1652    }
1653
1654    pub fn table_index<T: ?Sized + Reencode>(_reencoder: &mut T, table: u32) -> u32 {
1655        table
1656    }
1657
1658    pub fn global_index<T: ?Sized + Reencode>(_reencoder: &mut T, global: u32) -> u32 {
1659        global
1660    }
1661
1662    pub fn data_index<T: ?Sized + Reencode>(_reencoder: &mut T, data: u32) -> u32 {
1663        data
1664    }
1665
1666    pub fn element_index<T: ?Sized + Reencode>(_reencoder: &mut T, element: u32) -> u32 {
1667        element
1668    }
1669
1670    pub fn const_expr<T: ?Sized + Reencode>(
1671        reencoder: &mut T,
1672        const_expr: wasmparser::ConstExpr,
1673    ) -> Result<crate::ConstExpr, Error<T::Error>> {
1674        let mut ops = const_expr.get_operators_reader();
1675        let mut bytes = Vec::new();
1676
1677        while !ops.is_end_then_eof() {
1678            let insn = reencoder.parse_instruction(&mut ops)?;
1679            insn.encode(&mut bytes);
1680        }
1681
1682        Ok(crate::ConstExpr::raw(bytes))
1683    }
1684
1685    pub fn block_type<T: ?Sized + Reencode>(
1686        reencoder: &mut T,
1687        arg: wasmparser::BlockType,
1688    ) -> Result<crate::BlockType, Error<T::Error>> {
1689        match arg {
1690            wasmparser::BlockType::Empty => Ok(crate::BlockType::Empty),
1691            wasmparser::BlockType::FuncType(n) => {
1692                Ok(crate::BlockType::FunctionType(reencoder.type_index(n)?))
1693            }
1694            wasmparser::BlockType::Type(t) => Ok(crate::BlockType::Result(reencoder.val_type(t)?)),
1695        }
1696    }
1697
1698    pub fn instruction<'a, T: ?Sized + Reencode>(
1699        reencoder: &mut T,
1700        arg: wasmparser::Operator<'a>,
1701    ) -> Result<crate::Instruction<'a>, Error<T::Error>> {
1702        use crate::Instruction;
1703        use alloc::borrow::Cow;
1704
1705        macro_rules! translate {
1706            ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {
1707                Ok(match arg {
1708                    $(
1709                        wasmparser::Operator::$op $({ $($arg),* })? => {
1710                            $(
1711                                $(let $arg = translate!(map $arg $arg);)*
1712                            )?
1713                            translate!(build $op $($($arg)*)?)
1714                        }
1715                    )*
1716                    unexpected => unreachable!("encountered unexpected Wasm operator: {unexpected:?}"),
1717                })
1718            };
1719
1720            // This case is used to map, based on the name of the field, from the
1721            // wasmparser payload type to the wasm-encoder payload type through
1722            // `Translator` as applicable.
1723            (map $arg:ident tag_index) => (reencoder.tag_index($arg)?);
1724            (map $arg:ident function_index) => (reencoder.function_index($arg)?);
1725            (map $arg:ident table) => (reencoder.table_index($arg)?);
1726            (map $arg:ident table_index) => (reencoder.table_index($arg)?);
1727            (map $arg:ident dst_table) => (reencoder.table_index($arg)?);
1728            (map $arg:ident src_table) => (reencoder.table_index($arg)?);
1729            (map $arg:ident type_index) => (reencoder.type_index($arg)?);
1730            (map $arg:ident array_type_index) => (reencoder.type_index($arg)?);
1731            (map $arg:ident array_type_index_dst) => (reencoder.type_index($arg)?);
1732            (map $arg:ident array_type_index_src) => (reencoder.type_index($arg)?);
1733            (map $arg:ident struct_type_index) => (reencoder.type_index($arg)?);
1734            (map $arg:ident global_index) => (reencoder.global_index($arg)?);
1735            (map $arg:ident mem) => (reencoder.memory_index($arg)?);
1736            (map $arg:ident src_mem) => (reencoder.memory_index($arg)?);
1737            (map $arg:ident dst_mem) => (reencoder.memory_index($arg)?);
1738            (map $arg:ident data_index) => (reencoder.data_index($arg)?);
1739            (map $arg:ident elem_index) => (reencoder.element_index($arg)?);
1740            (map $arg:ident array_data_index) => (reencoder.data_index($arg)?);
1741            (map $arg:ident array_elem_index) => (reencoder.element_index($arg)?);
1742            (map $arg:ident blockty) => (reencoder.block_type($arg)?);
1743            (map $arg:ident relative_depth) => ($arg);
1744            (map $arg:ident targets) => ((
1745                $arg
1746                    .targets()
1747                    .collect::<Result<Vec<_>, wasmparser::Error>>()?
1748                    .into(),
1749                $arg.default(),
1750            ));
1751            (map $arg:ident ty) => (reencoder.val_type($arg)?);
1752            (map $arg:ident tys) => (reencoder.val_types($arg)?);
1753            (map $arg:ident hty) => (reencoder.heap_type($arg)?);
1754            (map $arg:ident from_ref_type) => (reencoder.ref_type($arg)?);
1755            (map $arg:ident to_ref_type) => (reencoder.ref_type($arg)?);
1756            (map $arg:ident memarg) => (reencoder.mem_arg($arg)?);
1757            (map $arg:ident ordering) => (reencoder.ordering($arg)?);
1758            (map $arg:ident local_index) => ($arg);
1759            (map $arg:ident value) => ($arg);
1760            (map $arg:ident lane) => ($arg);
1761            (map $arg:ident lanes) => ($arg);
1762            (map $arg:ident array_size) => ($arg);
1763            (map $arg:ident field_index) => ($arg);
1764            (map $arg:ident try_table) => ($arg);
1765            (map $arg:ident argument_index) => (reencoder.type_index($arg)?);
1766            (map $arg:ident result_index) => (reencoder.type_index($arg)?);
1767            (map $arg:ident cont_type_index) => (reencoder.type_index($arg)?);
1768            (map $arg:ident resume_table) => ((
1769                $arg.handlers.into_iter()
1770                    .map(|h| reencoder.handle(h))
1771                    .collect::<Result<Vec<_>, _>>()?
1772                    .into()
1773            ));
1774
1775            // This case takes the arguments of a wasmparser instruction and creates
1776            // a wasm-encoder instruction. There are a few special cases for where
1777            // the structure of a wasmparser instruction differs from that of
1778            // wasm-encoder.
1779            (build $op:ident) => (Instruction::$op);
1780            (build BrTable $arg:ident) => (Instruction::BrTable($arg.0, $arg.1));
1781            (build TypedSelectMulti $arg:ident) => (Instruction::TypedSelectMulti(Cow::from($arg)));
1782            (build I32Const $arg:ident) => (Instruction::I32Const($arg));
1783            (build I64Const $arg:ident) => (Instruction::I64Const($arg));
1784            (build F32Const $arg:ident) => (Instruction::F32Const($arg.into()));
1785            (build F64Const $arg:ident) => (Instruction::F64Const($arg.into()));
1786            (build V128Const $arg:ident) => (Instruction::V128Const($arg.i128()));
1787            (build TryTable $table:ident) => (Instruction::TryTable(reencoder.block_type($table.ty)?, {
1788                $table.catches.into_iter()
1789                    .map(|c| reencoder.catch(c))
1790                    .collect::<Result<Vec<_>, _>>()?
1791                    .into()
1792            }));
1793            (build $op:ident $arg:ident) => (Instruction::$op($arg));
1794            (build $op:ident $($arg:ident)*) => (Instruction::$op { $($arg),* });
1795        }
1796
1797        wasmparser::for_each_operator!(translate)
1798    }
1799
1800    /// Parses the input `section` given from the `wasmparser` crate and adds
1801    /// all the code to the `code` section.
1802    pub fn parse_code_section<T: ?Sized + Reencode>(
1803        reencoder: &mut T,
1804        code: &mut crate::CodeSection,
1805        section: wasmparser::CodeSectionReader<'_>,
1806    ) -> Result<(), Error<T::Error>> {
1807        for func in section {
1808            reencoder.parse_function_body(code, func?)?;
1809        }
1810        Ok(())
1811    }
1812
1813    /// Parses a single [`wasmparser::FunctionBody`] and adds it to the `code` section.
1814    pub fn parse_function_body<T: ?Sized + Reencode>(
1815        reencoder: &mut T,
1816        code: &mut crate::CodeSection,
1817        func: wasmparser::FunctionBody<'_>,
1818    ) -> Result<(), Error<T::Error>> {
1819        let mut f = reencoder.new_function_with_parsed_locals(&func)?;
1820        let mut reader = func.get_operators_reader()?;
1821        while !reader.eof() {
1822            f.instruction(&reencoder.parse_instruction(&mut reader)?);
1823        }
1824        code.function(&f);
1825        Ok(())
1826    }
1827
1828    /// Create a new [`crate::Function`] by parsing the locals declarations from the
1829    /// provided [`wasmparser::FunctionBody`].
1830    pub fn new_function_with_parsed_locals<T: ?Sized + Reencode>(
1831        reencoder: &mut T,
1832        func: &wasmparser::FunctionBody<'_>,
1833    ) -> Result<crate::Function, Error<T::Error>> {
1834        let mut locals = Vec::new();
1835        for pair in func.get_locals_reader()? {
1836            let (cnt, ty) = pair?;
1837            locals.push((cnt, reencoder.val_type(ty)?));
1838        }
1839        Ok(crate::Function::new(locals))
1840    }
1841
1842    /// Parses a single instruction from `reader` and adds it to `function`.
1843    pub fn parse_instruction<'a, T: ?Sized + Reencode>(
1844        reencoder: &mut T,
1845        reader: &mut wasmparser::OperatorsReader<'a>,
1846    ) -> Result<crate::Instruction<'a>, Error<T::Error>> {
1847        let instruction = reencoder.instruction(reader.read()?)?;
1848        Ok(instruction)
1849    }
1850
1851    pub fn parse_unknown_section<T: ?Sized + Reencode>(
1852        _reencoder: &mut T,
1853        module: &mut crate::Module,
1854        id: u8,
1855        contents: &[u8],
1856    ) -> Result<(), Error<T::Error>> {
1857        module.section(&crate::RawSection { id, data: contents });
1858        Ok(())
1859    }
1860
1861    pub fn custom_name_section<T: ?Sized + Reencode>(
1862        reencoder: &mut T,
1863        section: wasmparser::NameSectionReader<'_>,
1864    ) -> Result<crate::NameSection, Error<T::Error>> {
1865        let mut ret = crate::NameSection::new();
1866        for subsection in section {
1867            reencoder.parse_custom_name_subsection(&mut ret, subsection?)?;
1868        }
1869        Ok(ret)
1870    }
1871
1872    pub fn parse_custom_name_subsection<T: ?Sized + Reencode>(
1873        reencoder: &mut T,
1874        names: &mut crate::NameSection,
1875        section: wasmparser::Name<'_>,
1876    ) -> Result<(), Error<T::Error>> {
1877        match section {
1878            wasmparser::Name::Module { name, .. } => {
1879                names.module(name);
1880            }
1881            wasmparser::Name::Function(map) => {
1882                names.functions(&name_map(map, |i| reencoder.function_index(i))?);
1883            }
1884            wasmparser::Name::Type(map) => {
1885                names.types(&name_map(map, |i| reencoder.type_index(i))?);
1886            }
1887            wasmparser::Name::Local(map) => {
1888                names.locals(&indirect_name_map(map, |i| reencoder.function_index(i))?);
1889            }
1890            wasmparser::Name::Label(map) => {
1891                names.labels(&indirect_name_map(map, |i| reencoder.function_index(i))?);
1892            }
1893            wasmparser::Name::Table(map) => {
1894                names.tables(&name_map(map, |i| reencoder.table_index(i))?);
1895            }
1896            wasmparser::Name::Memory(map) => {
1897                names.memories(&name_map(map, |i| reencoder.memory_index(i))?);
1898            }
1899            wasmparser::Name::Global(map) => {
1900                names.globals(&name_map(map, |i| reencoder.global_index(i))?);
1901            }
1902            wasmparser::Name::Element(map) => {
1903                names.elements(&name_map(map, |i| reencoder.element_index(i))?);
1904            }
1905            wasmparser::Name::Data(map) => {
1906                names.data(&name_map(map, |i| reencoder.data_index(i))?);
1907            }
1908            wasmparser::Name::Tag(map) => {
1909                names.tags(&name_map(map, |i| reencoder.tag_index(i))?);
1910            }
1911            wasmparser::Name::Field(map) => {
1912                names.fields(&indirect_name_map(map, |i| reencoder.type_index(i))?);
1913            }
1914            wasmparser::Name::Parameter(map) => {
1915                names.parameters(&indirect_name_map(map, |i| reencoder.type_index(i))?);
1916            }
1917            wasmparser::Name::TagParameter(map) => {
1918                names.tag_parameters(&indirect_name_map(map, |i| reencoder.tag_index(i))?);
1919            }
1920            wasmparser::Name::Unknown { ty, data, .. } => {
1921                names.raw(ty, data);
1922            }
1923        }
1924        Ok(())
1925    }
1926
1927    pub fn name_map<E>(
1928        map: wasmparser::NameMap<'_>,
1929        mut map_index: impl FnMut(u32) -> Result<u32, Error<E>>,
1930    ) -> Result<crate::NameMap, Error<E>> {
1931        let mut ret = crate::NameMap::new();
1932        for naming in map {
1933            let naming = naming?;
1934            ret.append(map_index(naming.index)?, naming.name);
1935        }
1936        Ok(ret)
1937    }
1938
1939    pub fn indirect_name_map<E>(
1940        map: wasmparser::IndirectNameMap<'_>,
1941        mut map_index: impl FnMut(u32) -> Result<u32, Error<E>>,
1942    ) -> Result<crate::IndirectNameMap, Error<E>> {
1943        let mut ret = crate::IndirectNameMap::new();
1944        for naming in map {
1945            let naming = naming?;
1946            ret.append(
1947                map_index(naming.index)?,
1948                &name_map(naming.names, |i| Ok(i))?,
1949            );
1950        }
1951        Ok(ret)
1952    }
1953}
1954
1955impl From<wasmparser::Ieee32> for crate::Ieee32 {
1956    fn from(arg: wasmparser::Ieee32) -> Self {
1957        utils::ieee32_arg(&mut RoundtripReencoder, arg)
1958    }
1959}
1960
1961impl From<wasmparser::Ieee64> for crate::Ieee64 {
1962    fn from(arg: wasmparser::Ieee64) -> Self {
1963        utils::ieee64_arg(&mut RoundtripReencoder, arg)
1964    }
1965}
1966
1967impl TryFrom<wasmparser::MemArg> for crate::MemArg {
1968    type Error = Error;
1969    fn try_from(arg: wasmparser::MemArg) -> Result<Self, Self::Error> {
1970        RoundtripReencoder.mem_arg(arg)
1971    }
1972}
1973
1974impl From<wasmparser::Ordering> for crate::Ordering {
1975    fn from(arg: wasmparser::Ordering) -> Self {
1976        utils::ordering(&mut RoundtripReencoder, arg)
1977    }
1978}
1979
1980impl TryFrom<wasmparser::BlockType> for crate::BlockType {
1981    type Error = Error;
1982
1983    fn try_from(arg: wasmparser::BlockType) -> Result<Self, Self::Error> {
1984        RoundtripReencoder.block_type(arg)
1985    }
1986}
1987
1988impl<'a> TryFrom<wasmparser::Operator<'a>> for crate::Instruction<'a> {
1989    type Error = Error;
1990
1991    fn try_from(arg: wasmparser::Operator<'a>) -> Result<Self, Self::Error> {
1992        RoundtripReencoder.instruction(arg)
1993    }
1994}
1995
1996impl TryFrom<wasmparser::Catch> for crate::Catch {
1997    type Error = Error;
1998
1999    fn try_from(arg: wasmparser::Catch) -> Result<Self, Self::Error> {
2000        RoundtripReencoder.catch(arg)
2001    }
2002}
2003
2004impl<'a> TryFrom<wasmparser::ConstExpr<'a>> for crate::ConstExpr {
2005    type Error = Error;
2006
2007    fn try_from(const_expr: wasmparser::ConstExpr) -> Result<Self, Self::Error> {
2008        RoundtripReencoder.const_expr(const_expr)
2009    }
2010}
2011
2012impl<'a> From<wasmparser::CustomSectionReader<'a>> for crate::CustomSection<'a> {
2013    fn from(section: wasmparser::CustomSectionReader<'a>) -> Self {
2014        utils::custom_section(&mut RoundtripReencoder, section)
2015    }
2016}
2017
2018impl From<wasmparser::ExternalKind> for crate::ExportKind {
2019    fn from(external_kind: wasmparser::ExternalKind) -> Self {
2020        utils::export_kind(&mut RoundtripReencoder, external_kind)
2021    }
2022}
2023
2024impl TryFrom<wasmparser::GlobalType> for crate::GlobalType {
2025    type Error = Error;
2026
2027    fn try_from(global_ty: wasmparser::GlobalType) -> Result<Self, Self::Error> {
2028        RoundtripReencoder.global_type(global_ty)
2029    }
2030}
2031
2032impl TryFrom<wasmparser::Handle> for crate::Handle {
2033    type Error = Error;
2034    fn try_from(arg: wasmparser::Handle) -> Result<Self, Self::Error> {
2035        RoundtripReencoder.handle(arg)
2036    }
2037}
2038
2039impl TryFrom<wasmparser::TypeRef> for crate::EntityType {
2040    type Error = Error;
2041
2042    fn try_from(type_ref: wasmparser::TypeRef) -> Result<Self, Self::Error> {
2043        RoundtripReencoder.entity_type(type_ref)
2044    }
2045}
2046
2047impl From<wasmparser::MemoryType> for crate::MemoryType {
2048    fn from(memory_ty: wasmparser::MemoryType) -> Self {
2049        utils::memory_type(&mut RoundtripReencoder, memory_ty)
2050    }
2051}
2052
2053impl TryFrom<wasmparser::TableType> for crate::TableType {
2054    type Error = Error;
2055
2056    fn try_from(table_ty: wasmparser::TableType) -> Result<Self, Self::Error> {
2057        RoundtripReencoder.table_type(table_ty)
2058    }
2059}
2060
2061impl From<wasmparser::TagKind> for crate::TagKind {
2062    fn from(kind: wasmparser::TagKind) -> Self {
2063        utils::tag_kind(&mut RoundtripReencoder, kind)
2064    }
2065}
2066
2067impl TryFrom<wasmparser::TagType> for crate::TagType {
2068    type Error = Error;
2069    fn try_from(tag_ty: wasmparser::TagType) -> Result<Self, Self::Error> {
2070        RoundtripReencoder.tag_type(tag_ty)
2071    }
2072}
2073
2074impl TryFrom<wasmparser::SubType> for crate::SubType {
2075    type Error = Error;
2076
2077    fn try_from(sub_ty: wasmparser::SubType) -> Result<Self, Self::Error> {
2078        RoundtripReencoder.sub_type(sub_ty)
2079    }
2080}
2081
2082impl TryFrom<wasmparser::CompositeType> for crate::CompositeType {
2083    type Error = Error;
2084
2085    fn try_from(composite_ty: wasmparser::CompositeType) -> Result<Self, Self::Error> {
2086        RoundtripReencoder.composite_type(composite_ty)
2087    }
2088}
2089
2090impl TryFrom<wasmparser::FuncType> for crate::FuncType {
2091    type Error = Error;
2092
2093    fn try_from(func_ty: wasmparser::FuncType) -> Result<Self, Self::Error> {
2094        RoundtripReencoder.func_type(func_ty)
2095    }
2096}
2097
2098impl TryFrom<wasmparser::ArrayType> for crate::ArrayType {
2099    type Error = Error;
2100
2101    fn try_from(array_ty: wasmparser::ArrayType) -> Result<Self, Self::Error> {
2102        RoundtripReencoder.array_type(array_ty)
2103    }
2104}
2105
2106impl TryFrom<wasmparser::StructType> for crate::StructType {
2107    type Error = Error;
2108
2109    fn try_from(struct_ty: wasmparser::StructType) -> Result<Self, Self::Error> {
2110        RoundtripReencoder.struct_type(struct_ty)
2111    }
2112}
2113
2114impl TryFrom<wasmparser::FieldType> for crate::FieldType {
2115    type Error = Error;
2116
2117    fn try_from(field_ty: wasmparser::FieldType) -> Result<Self, Self::Error> {
2118        RoundtripReencoder.field_type(field_ty)
2119    }
2120}
2121
2122impl TryFrom<wasmparser::StorageType> for crate::StorageType {
2123    type Error = Error;
2124
2125    fn try_from(storage_ty: wasmparser::StorageType) -> Result<Self, Self::Error> {
2126        RoundtripReencoder.storage_type(storage_ty)
2127    }
2128}
2129
2130impl TryFrom<wasmparser::ValType> for crate::ValType {
2131    type Error = Error;
2132
2133    fn try_from(val_ty: wasmparser::ValType) -> Result<Self, Self::Error> {
2134        RoundtripReencoder.val_type(val_ty)
2135    }
2136}
2137
2138impl TryFrom<wasmparser::RefType> for crate::RefType {
2139    type Error = Error;
2140
2141    fn try_from(ref_type: wasmparser::RefType) -> Result<Self, Self::Error> {
2142        RoundtripReencoder.ref_type(ref_type)
2143    }
2144}
2145
2146impl TryFrom<wasmparser::HeapType> for crate::HeapType {
2147    type Error = Error;
2148
2149    fn try_from(heap_type: wasmparser::HeapType) -> Result<Self, Self::Error> {
2150        crate::reencode::utils::heap_type(&mut crate::reencode::RoundtripReencoder, heap_type)
2151    }
2152}
2153
2154impl From<wasmparser::AbstractHeapType> for crate::AbstractHeapType {
2155    fn from(value: wasmparser::AbstractHeapType) -> Self {
2156        utils::abstract_heap_type(&mut RoundtripReencoder, value)
2157    }
2158}