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