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