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