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        })
1174    }
1175
1176    pub fn func_type<T: ?Sized + Reencode>(
1177        reencoder: &mut T,
1178        func_ty: wasmparser::FuncType,
1179    ) -> Result<crate::FuncType, Error<T::Error>> {
1180        let mut buf = Vec::with_capacity(func_ty.params().len() + func_ty.results().len());
1181        for ty in func_ty.params().iter().chain(func_ty.results()).copied() {
1182            buf.push(reencoder.val_type(ty)?);
1183        }
1184        Ok(crate::FuncType::from_parts(
1185            buf.into(),
1186            func_ty.params().len(),
1187        ))
1188    }
1189
1190    pub fn array_type<T: ?Sized + Reencode>(
1191        reencoder: &mut T,
1192        array_ty: wasmparser::ArrayType,
1193    ) -> Result<crate::ArrayType, Error<T::Error>> {
1194        Ok(crate::ArrayType(reencoder.field_type(array_ty.0)?))
1195    }
1196
1197    pub fn struct_type<T: ?Sized + Reencode>(
1198        reencoder: &mut T,
1199        struct_ty: wasmparser::StructType,
1200    ) -> Result<crate::StructType, Error<T::Error>> {
1201        Ok(crate::StructType {
1202            fields: struct_ty
1203                .fields
1204                .iter()
1205                .map(|field_ty| reencoder.field_type(*field_ty))
1206                .collect::<Result<_, _>>()?,
1207        })
1208    }
1209
1210    pub fn field_type<T: ?Sized + Reencode>(
1211        reencoder: &mut T,
1212        field_ty: wasmparser::FieldType,
1213    ) -> Result<crate::FieldType, Error<T::Error>> {
1214        Ok(crate::FieldType {
1215            element_type: reencoder.storage_type(field_ty.element_type)?,
1216            mutable: field_ty.mutable,
1217        })
1218    }
1219
1220    pub fn storage_type<T: ?Sized + Reencode>(
1221        reencoder: &mut T,
1222        storage_ty: wasmparser::StorageType,
1223    ) -> Result<crate::StorageType, Error<T::Error>> {
1224        Ok(match storage_ty {
1225            wasmparser::StorageType::I8 => crate::StorageType::I8,
1226            wasmparser::StorageType::I16 => crate::StorageType::I16,
1227            wasmparser::StorageType::Val(v) => crate::StorageType::Val(reencoder.val_type(v)?),
1228        })
1229    }
1230
1231    pub fn cont_type<T: ?Sized + Reencode>(
1232        reencoder: &mut T,
1233        cont_ty: wasmparser::ContType,
1234    ) -> Result<crate::ContType, Error<T::Error>> {
1235        Ok(crate::ContType(
1236            reencoder.type_index_unpacked(cont_ty.0.unpack())?,
1237        ))
1238    }
1239
1240    pub fn val_type<T: ?Sized + Reencode>(
1241        reencoder: &mut T,
1242        val_ty: wasmparser::ValType,
1243    ) -> Result<crate::ValType, Error<T::Error>> {
1244        Ok(match val_ty {
1245            wasmparser::ValType::I32 => crate::ValType::I32,
1246            wasmparser::ValType::I64 => crate::ValType::I64,
1247            wasmparser::ValType::F32 => crate::ValType::F32,
1248            wasmparser::ValType::F64 => crate::ValType::F64,
1249            wasmparser::ValType::V128 => crate::ValType::V128,
1250            wasmparser::ValType::Ref(r) => crate::ValType::Ref(reencoder.ref_type(r)?),
1251        })
1252    }
1253
1254    pub fn ref_type<T: ?Sized + Reencode>(
1255        reencoder: &mut T,
1256        ref_type: wasmparser::RefType,
1257    ) -> Result<crate::RefType, Error<T::Error>> {
1258        Ok(crate::RefType {
1259            nullable: ref_type.is_nullable(),
1260            heap_type: reencoder.heap_type(ref_type.heap_type())?,
1261        })
1262    }
1263
1264    pub fn heap_type<T: ?Sized + Reencode>(
1265        reencoder: &mut T,
1266        heap_type: wasmparser::HeapType,
1267    ) -> Result<crate::HeapType, Error<T::Error>> {
1268        Ok(match heap_type {
1269            wasmparser::HeapType::Concrete(i) => {
1270                crate::HeapType::Concrete(reencoder.type_index_unpacked(i)?)
1271            }
1272            wasmparser::HeapType::Abstract { shared, ty } => crate::HeapType::Abstract {
1273                shared,
1274                ty: reencoder.abstract_heap_type(ty)?,
1275            },
1276        })
1277    }
1278
1279    /// Parses the input `section` given from the `wasmparser` crate and adds
1280    /// all the tables to the `tables` section.
1281    pub fn parse_table_section<T: ?Sized + Reencode>(
1282        reencoder: &mut T,
1283        tables: &mut crate::TableSection,
1284        section: wasmparser::TableSectionReader<'_>,
1285    ) -> Result<(), Error<T::Error>> {
1286        for table in section {
1287            reencoder.parse_table(tables, table?)?;
1288        }
1289        Ok(())
1290    }
1291
1292    /// Parses a single [`wasmparser::Table`] and adds it to the `tables` section.
1293    pub fn parse_table<T: ?Sized + Reencode>(
1294        reencoder: &mut T,
1295        tables: &mut crate::TableSection,
1296        table: wasmparser::Table<'_>,
1297    ) -> Result<(), Error<T::Error>> {
1298        let ty = reencoder.table_type(table.ty)?;
1299        match table.init {
1300            wasmparser::TableInit::RefNull => {
1301                tables.table(ty);
1302            }
1303            wasmparser::TableInit::Expr(e) => {
1304                tables.table_with_init(ty, &reencoder.const_expr(e)?);
1305            }
1306        }
1307        Ok(())
1308    }
1309
1310    pub fn table_type<T: ?Sized + Reencode>(
1311        reencoder: &mut T,
1312        table_ty: wasmparser::TableType,
1313    ) -> Result<crate::TableType, Error<T::Error>> {
1314        Ok(crate::TableType {
1315            element_type: reencoder.ref_type(table_ty.element_type)?,
1316            minimum: table_ty.initial,
1317            maximum: table_ty.maximum,
1318            table64: table_ty.table64,
1319            shared: table_ty.shared,
1320        })
1321    }
1322
1323    /// Parses the input `section` given from the `wasmparser` crate and adds
1324    /// all the tags to the `tags` section.
1325    pub fn parse_tag_section<T: ?Sized + Reencode>(
1326        reencoder: &mut T,
1327        tags: &mut crate::TagSection,
1328        section: wasmparser::TagSectionReader<'_>,
1329    ) -> Result<(), Error<T::Error>> {
1330        for tag in section {
1331            let tag = tag?;
1332            tags.tag(reencoder.tag_type(tag)?);
1333        }
1334        Ok(())
1335    }
1336
1337    /// Parses the input `section` given from the `wasmparser` crate and adds
1338    /// all the exports to the `exports` section.
1339    pub fn parse_export_section<T: ?Sized + Reencode>(
1340        reencoder: &mut T,
1341        exports: &mut crate::ExportSection,
1342        section: wasmparser::ExportSectionReader<'_>,
1343    ) -> Result<(), Error<T::Error>> {
1344        for export in section {
1345            reencoder.parse_export(exports, export?)?;
1346        }
1347        Ok(())
1348    }
1349
1350    /// Parses the single [`wasmparser::Export`] provided and adds it to the
1351    /// `exports` section.
1352    pub fn parse_export<T: ?Sized + Reencode>(
1353        reencoder: &mut T,
1354        exports: &mut crate::ExportSection,
1355        export: wasmparser::Export<'_>,
1356    ) -> Result<(), Error<T::Error>> {
1357        exports.export(
1358            export.name,
1359            reencoder.export_kind(export.kind)?,
1360            reencoder.external_index(export.kind, export.index)?,
1361        );
1362        Ok(())
1363    }
1364
1365    /// Parses the input `section` given from the `wasmparser` crate and adds
1366    /// all the globals to the `globals` section.
1367    pub fn parse_global_section<T: ?Sized + Reencode>(
1368        reencoder: &mut T,
1369        globals: &mut crate::GlobalSection,
1370        section: wasmparser::GlobalSectionReader<'_>,
1371    ) -> Result<(), Error<T::Error>> {
1372        for global in section {
1373            reencoder.parse_global(globals, global?)?;
1374        }
1375        Ok(())
1376    }
1377
1378    /// Parses the single [`wasmparser::Global`] provided and adds it to the
1379    /// `globals` section.
1380    pub fn parse_global<T: ?Sized + Reencode>(
1381        reencoder: &mut T,
1382        globals: &mut crate::GlobalSection,
1383        global: wasmparser::Global<'_>,
1384    ) -> Result<(), Error<T::Error>> {
1385        globals.global(
1386            reencoder.global_type(global.ty)?,
1387            &reencoder.const_expr(global.init_expr)?,
1388        );
1389        Ok(())
1390    }
1391
1392    pub fn global_type<T: ?Sized + Reencode>(
1393        reencoder: &mut T,
1394        global_ty: wasmparser::GlobalType,
1395    ) -> Result<crate::GlobalType, Error<T::Error>> {
1396        Ok(crate::GlobalType {
1397            val_type: reencoder.val_type(global_ty.content_type)?,
1398            mutable: global_ty.mutable,
1399            shared: global_ty.shared,
1400        })
1401    }
1402
1403    pub fn entity_type<T: ?Sized + Reencode>(
1404        reencoder: &mut T,
1405        type_ref: wasmparser::TypeRef,
1406    ) -> Result<crate::EntityType, Error<T::Error>> {
1407        Ok(match type_ref {
1408            wasmparser::TypeRef::Func(i) => crate::EntityType::Function(reencoder.type_index(i)?),
1409            wasmparser::TypeRef::Table(t) => crate::EntityType::Table(reencoder.table_type(t)?),
1410            wasmparser::TypeRef::Memory(m) => crate::EntityType::Memory(reencoder.memory_type(m)?),
1411            wasmparser::TypeRef::Global(g) => crate::EntityType::Global(reencoder.global_type(g)?),
1412            wasmparser::TypeRef::Tag(t) => crate::EntityType::Tag(reencoder.tag_type(t)?),
1413        })
1414    }
1415
1416    /// Parses the input `section` given from the `wasmparser` crate and adds
1417    /// all the imports to the `import` section.
1418    pub fn parse_import_section<T: ?Sized + Reencode>(
1419        reencoder: &mut T,
1420        imports: &mut crate::ImportSection,
1421        section: wasmparser::ImportSectionReader<'_>,
1422    ) -> Result<(), Error<T::Error>> {
1423        for import in section {
1424            reencoder.parse_import(imports, import?)?;
1425        }
1426        Ok(())
1427    }
1428
1429    /// Parses the single [`wasmparser::Import`] provided and adds it to the
1430    /// `import` section.
1431    pub fn parse_import<T: ?Sized + Reencode>(
1432        reencoder: &mut T,
1433        imports: &mut crate::ImportSection,
1434        import: wasmparser::Import<'_>,
1435    ) -> Result<(), Error<T::Error>> {
1436        imports.import(
1437            import.module,
1438            import.name,
1439            reencoder.entity_type(import.ty)?,
1440        );
1441        Ok(())
1442    }
1443
1444    /// Parses the input `section` given from the `wasmparser` crate and adds
1445    /// all the memories to the `memories` section.
1446    pub fn parse_memory_section<T: ?Sized + Reencode>(
1447        reencoder: &mut T,
1448        memories: &mut crate::MemorySection,
1449        section: wasmparser::MemorySectionReader<'_>,
1450    ) -> Result<(), Error<T::Error>> {
1451        for memory in section {
1452            let memory = memory?;
1453            memories.memory(reencoder.memory_type(memory)?);
1454        }
1455        Ok(())
1456    }
1457
1458    /// Parses the input `section` given from the `wasmparser` crate and adds
1459    /// all the functions to the `functions` section.
1460    pub fn parse_function_section<T: ?Sized + Reencode>(
1461        reencoder: &mut T,
1462        functions: &mut crate::FunctionSection,
1463        section: wasmparser::FunctionSectionReader<'_>,
1464    ) -> Result<(), Error<T::Error>> {
1465        for func in section {
1466            functions.function(reencoder.type_index(func?)?);
1467        }
1468        Ok(())
1469    }
1470
1471    /// Parses the input `section` given from the `wasmparser` crate and adds
1472    /// all the data to the `data` section.
1473    pub fn parse_data_section<T: ?Sized + Reencode>(
1474        reencoder: &mut T,
1475        data: &mut crate::DataSection,
1476        section: wasmparser::DataSectionReader<'_>,
1477    ) -> Result<(), Error<T::Error>> {
1478        for datum in section {
1479            reencoder.parse_data(data, datum?)?;
1480        }
1481        Ok(())
1482    }
1483
1484    /// Parses a single [`wasmparser::Data`] and adds it to the `data` section.
1485    pub fn parse_data<T: ?Sized + Reencode>(
1486        reencoder: &mut T,
1487        data: &mut crate::DataSection,
1488        datum: wasmparser::Data<'_>,
1489    ) -> Result<(), Error<T::Error>> {
1490        match datum.kind {
1491            wasmparser::DataKind::Active {
1492                memory_index,
1493                offset_expr,
1494            } => data.active(
1495                reencoder.memory_index(memory_index)?,
1496                &reencoder.const_expr(offset_expr)?,
1497                datum.data.iter().copied(),
1498            ),
1499            wasmparser::DataKind::Passive => data.passive(datum.data.iter().copied()),
1500        };
1501        Ok(())
1502    }
1503
1504    /// Parses the input `section` given from the `wasmparser` crate and adds
1505    /// all the elements to the `element` section.
1506    pub fn parse_element_section<T: ?Sized + Reencode>(
1507        reencoder: &mut T,
1508        elements: &mut crate::ElementSection,
1509        section: wasmparser::ElementSectionReader<'_>,
1510    ) -> Result<(), Error<T::Error>> {
1511        for element in section {
1512            reencoder.parse_element(elements, element?)?;
1513        }
1514        Ok(())
1515    }
1516
1517    /// Parses the single [`wasmparser::Element`] provided and adds it to the
1518    /// `element` section.
1519    pub fn parse_element<T: ?Sized + Reencode>(
1520        reencoder: &mut T,
1521        elements: &mut crate::ElementSection,
1522        element: wasmparser::Element<'_>,
1523    ) -> Result<(), Error<T::Error>> {
1524        let elems = reencoder.element_items(element.items)?;
1525        match element.kind {
1526            wasmparser::ElementKind::Active {
1527                table_index,
1528                offset_expr,
1529            } => elements.active(
1530                // Inform the reencoder that a table index is being used even if
1531                // it's not actually present here. That helps wasm-mutate for
1532                // example which wants to track uses to know when it's ok to
1533                // remove a table.
1534                //
1535                // If the table index started at `None` and is still zero then
1536                // preserve this encoding and keep it at `None`. Otherwise if
1537                // the result is nonzero or it was previously nonzero then keep
1538                // that encoding too.
1539                match (
1540                    table_index,
1541                    reencoder.table_index(table_index.unwrap_or(0))?,
1542                ) {
1543                    (None, 0) => None,
1544                    (_, n) => Some(n),
1545                },
1546                &reencoder.const_expr(offset_expr)?,
1547                elems,
1548            ),
1549            wasmparser::ElementKind::Passive => elements.passive(elems),
1550            wasmparser::ElementKind::Declared => elements.declared(elems),
1551        };
1552        Ok(())
1553    }
1554
1555    pub fn element_items<'a, T: ?Sized + Reencode>(
1556        reencoder: &mut T,
1557        items: wasmparser::ElementItems<'a>,
1558    ) -> Result<crate::Elements<'a>, Error<T::Error>> {
1559        Ok(match items {
1560            wasmparser::ElementItems::Functions(f) => {
1561                let mut funcs = Vec::new();
1562                for func in f {
1563                    funcs.push(reencoder.function_index(func?)?);
1564                }
1565                crate::Elements::Functions(funcs.into())
1566            }
1567            wasmparser::ElementItems::Expressions(ty, e) => {
1568                let mut exprs = Vec::new();
1569                for expr in e {
1570                    exprs.push(reencoder.const_expr(expr?)?);
1571                }
1572                crate::Elements::Expressions(reencoder.ref_type(ty)?, exprs.into())
1573            }
1574        })
1575    }
1576
1577    pub fn table_index<T: ?Sized + Reencode>(_reencoder: &mut T, table: u32) -> u32 {
1578        table
1579    }
1580
1581    pub fn global_index<T: ?Sized + Reencode>(_reencoder: &mut T, global: u32) -> u32 {
1582        global
1583    }
1584
1585    pub fn data_index<T: ?Sized + Reencode>(_reencoder: &mut T, data: u32) -> u32 {
1586        data
1587    }
1588
1589    pub fn element_index<T: ?Sized + Reencode>(_reencoder: &mut T, element: u32) -> u32 {
1590        element
1591    }
1592
1593    pub fn const_expr<T: ?Sized + Reencode>(
1594        reencoder: &mut T,
1595        const_expr: wasmparser::ConstExpr,
1596    ) -> Result<crate::ConstExpr, Error<T::Error>> {
1597        let mut ops = const_expr.get_operators_reader();
1598        let mut bytes = Vec::new();
1599
1600        while !ops.is_end_then_eof() {
1601            let insn = reencoder.parse_instruction(&mut ops)?;
1602            insn.encode(&mut bytes);
1603        }
1604
1605        Ok(crate::ConstExpr::raw(bytes))
1606    }
1607
1608    pub fn block_type<T: ?Sized + Reencode>(
1609        reencoder: &mut T,
1610        arg: wasmparser::BlockType,
1611    ) -> Result<crate::BlockType, Error<T::Error>> {
1612        match arg {
1613            wasmparser::BlockType::Empty => Ok(crate::BlockType::Empty),
1614            wasmparser::BlockType::FuncType(n) => {
1615                Ok(crate::BlockType::FunctionType(reencoder.type_index(n)?))
1616            }
1617            wasmparser::BlockType::Type(t) => Ok(crate::BlockType::Result(reencoder.val_type(t)?)),
1618        }
1619    }
1620
1621    pub fn instruction<'a, T: ?Sized + Reencode>(
1622        reencoder: &mut T,
1623        arg: wasmparser::Operator<'a>,
1624    ) -> Result<crate::Instruction<'a>, Error<T::Error>> {
1625        use crate::Instruction;
1626        use alloc::borrow::Cow;
1627
1628        macro_rules! translate {
1629            ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {
1630                Ok(match arg {
1631                    $(
1632                        wasmparser::Operator::$op $({ $($arg),* })? => {
1633                            $(
1634                                $(let $arg = translate!(map $arg $arg);)*
1635                            )?
1636                            translate!(build $op $($($arg)*)?)
1637                        }
1638                    )*
1639                    unexpected => unreachable!("encountered unexpected Wasm operator: {unexpected:?}"),
1640                })
1641            };
1642
1643            // This case is used to map, based on the name of the field, from the
1644            // wasmparser payload type to the wasm-encoder payload type through
1645            // `Translator` as applicable.
1646            (map $arg:ident tag_index) => (reencoder.tag_index($arg)?);
1647            (map $arg:ident function_index) => (reencoder.function_index($arg)?);
1648            (map $arg:ident table) => (reencoder.table_index($arg)?);
1649            (map $arg:ident table_index) => (reencoder.table_index($arg)?);
1650            (map $arg:ident dst_table) => (reencoder.table_index($arg)?);
1651            (map $arg:ident src_table) => (reencoder.table_index($arg)?);
1652            (map $arg:ident type_index) => (reencoder.type_index($arg)?);
1653            (map $arg:ident array_type_index) => (reencoder.type_index($arg)?);
1654            (map $arg:ident array_type_index_dst) => (reencoder.type_index($arg)?);
1655            (map $arg:ident array_type_index_src) => (reencoder.type_index($arg)?);
1656            (map $arg:ident struct_type_index) => (reencoder.type_index($arg)?);
1657            (map $arg:ident global_index) => (reencoder.global_index($arg)?);
1658            (map $arg:ident mem) => (reencoder.memory_index($arg)?);
1659            (map $arg:ident src_mem) => (reencoder.memory_index($arg)?);
1660            (map $arg:ident dst_mem) => (reencoder.memory_index($arg)?);
1661            (map $arg:ident data_index) => (reencoder.data_index($arg)?);
1662            (map $arg:ident elem_index) => (reencoder.element_index($arg)?);
1663            (map $arg:ident array_data_index) => (reencoder.data_index($arg)?);
1664            (map $arg:ident array_elem_index) => (reencoder.element_index($arg)?);
1665            (map $arg:ident blockty) => (reencoder.block_type($arg)?);
1666            (map $arg:ident relative_depth) => ($arg);
1667            (map $arg:ident targets) => ((
1668                $arg
1669                    .targets()
1670                    .collect::<Result<Vec<_>, wasmparser::BinaryReaderError>>()?
1671                    .into(),
1672                $arg.default(),
1673            ));
1674            (map $arg:ident ty) => (reencoder.val_type($arg)?);
1675            (map $arg:ident tys) => (reencoder.val_types($arg)?);
1676            (map $arg:ident hty) => (reencoder.heap_type($arg)?);
1677            (map $arg:ident from_ref_type) => (reencoder.ref_type($arg)?);
1678            (map $arg:ident to_ref_type) => (reencoder.ref_type($arg)?);
1679            (map $arg:ident memarg) => (reencoder.mem_arg($arg)?);
1680            (map $arg:ident ordering) => (reencoder.ordering($arg)?);
1681            (map $arg:ident local_index) => ($arg);
1682            (map $arg:ident value) => ($arg);
1683            (map $arg:ident lane) => ($arg);
1684            (map $arg:ident lanes) => ($arg);
1685            (map $arg:ident array_size) => ($arg);
1686            (map $arg:ident field_index) => ($arg);
1687            (map $arg:ident try_table) => ($arg);
1688            (map $arg:ident argument_index) => (reencoder.type_index($arg)?);
1689            (map $arg:ident result_index) => (reencoder.type_index($arg)?);
1690            (map $arg:ident cont_type_index) => (reencoder.type_index($arg)?);
1691            (map $arg:ident resume_table) => ((
1692                $arg.handlers.into_iter()
1693                    .map(|h| reencoder.handle(h))
1694                    .collect::<Result<Vec<_>, _>>()?
1695                    .into()
1696            ));
1697
1698            // This case takes the arguments of a wasmparser instruction and creates
1699            // a wasm-encoder instruction. There are a few special cases for where
1700            // the structure of a wasmparser instruction differs from that of
1701            // wasm-encoder.
1702            (build $op:ident) => (Instruction::$op);
1703            (build BrTable $arg:ident) => (Instruction::BrTable($arg.0, $arg.1));
1704            (build TypedSelectMulti $arg:ident) => (Instruction::TypedSelectMulti(Cow::from($arg)));
1705            (build I32Const $arg:ident) => (Instruction::I32Const($arg));
1706            (build I64Const $arg:ident) => (Instruction::I64Const($arg));
1707            (build F32Const $arg:ident) => (Instruction::F32Const($arg.into()));
1708            (build F64Const $arg:ident) => (Instruction::F64Const($arg.into()));
1709            (build V128Const $arg:ident) => (Instruction::V128Const($arg.i128()));
1710            (build TryTable $table:ident) => (Instruction::TryTable(reencoder.block_type($table.ty)?, {
1711                $table.catches.into_iter()
1712                    .map(|c| reencoder.catch(c))
1713                    .collect::<Result<Vec<_>, _>>()?
1714                    .into()
1715            }));
1716            (build $op:ident $arg:ident) => (Instruction::$op($arg));
1717            (build $op:ident $($arg:ident)*) => (Instruction::$op { $($arg),* });
1718        }
1719
1720        wasmparser::for_each_operator!(translate)
1721    }
1722
1723    /// Parses the input `section` given from the `wasmparser` crate and adds
1724    /// all the code to the `code` section.
1725    pub fn parse_code_section<T: ?Sized + Reencode>(
1726        reencoder: &mut T,
1727        code: &mut crate::CodeSection,
1728        section: wasmparser::CodeSectionReader<'_>,
1729    ) -> Result<(), Error<T::Error>> {
1730        for func in section {
1731            reencoder.parse_function_body(code, func?)?;
1732        }
1733        Ok(())
1734    }
1735
1736    /// Parses a single [`wasmparser::FunctionBody`] and adds it to the `code` section.
1737    pub fn parse_function_body<T: ?Sized + Reencode>(
1738        reencoder: &mut T,
1739        code: &mut crate::CodeSection,
1740        func: wasmparser::FunctionBody<'_>,
1741    ) -> Result<(), Error<T::Error>> {
1742        let mut f = reencoder.new_function_with_parsed_locals(&func)?;
1743        let mut reader = func.get_operators_reader()?;
1744        while !reader.eof() {
1745            f.instruction(&reencoder.parse_instruction(&mut reader)?);
1746        }
1747        code.function(&f);
1748        Ok(())
1749    }
1750
1751    /// Create a new [`crate::Function`] by parsing the locals declarations from the
1752    /// provided [`wasmparser::FunctionBody`].
1753    pub fn new_function_with_parsed_locals<T: ?Sized + Reencode>(
1754        reencoder: &mut T,
1755        func: &wasmparser::FunctionBody<'_>,
1756    ) -> Result<crate::Function, Error<T::Error>> {
1757        let mut locals = Vec::new();
1758        for pair in func.get_locals_reader()? {
1759            let (cnt, ty) = pair?;
1760            locals.push((cnt, reencoder.val_type(ty)?));
1761        }
1762        Ok(crate::Function::new(locals))
1763    }
1764
1765    /// Parses a single instruction from `reader` and adds it to `function`.
1766    pub fn parse_instruction<'a, T: ?Sized + Reencode>(
1767        reencoder: &mut T,
1768        reader: &mut wasmparser::OperatorsReader<'a>,
1769    ) -> Result<crate::Instruction<'a>, Error<T::Error>> {
1770        let instruction = reencoder.instruction(reader.read()?)?;
1771        Ok(instruction)
1772    }
1773
1774    pub fn parse_unknown_section<T: ?Sized + Reencode>(
1775        _reencoder: &mut T,
1776        module: &mut crate::Module,
1777        id: u8,
1778        contents: &[u8],
1779    ) -> Result<(), Error<T::Error>> {
1780        module.section(&crate::RawSection { id, data: contents });
1781        Ok(())
1782    }
1783
1784    pub fn custom_name_section<T: ?Sized + Reencode>(
1785        reencoder: &mut T,
1786        section: wasmparser::NameSectionReader<'_>,
1787    ) -> Result<crate::NameSection, Error<T::Error>> {
1788        let mut ret = crate::NameSection::new();
1789        for subsection in section {
1790            reencoder.parse_custom_name_subsection(&mut ret, subsection?)?;
1791        }
1792        Ok(ret)
1793    }
1794
1795    pub fn parse_custom_name_subsection<T: ?Sized + Reencode>(
1796        reencoder: &mut T,
1797        names: &mut crate::NameSection,
1798        section: wasmparser::Name<'_>,
1799    ) -> Result<(), Error<T::Error>> {
1800        match section {
1801            wasmparser::Name::Module { name, .. } => {
1802                names.module(name);
1803            }
1804            wasmparser::Name::Function(map) => {
1805                names.functions(&name_map(map, |i| reencoder.function_index(i))?);
1806            }
1807            wasmparser::Name::Type(map) => {
1808                names.types(&name_map(map, |i| reencoder.type_index(i))?);
1809            }
1810            wasmparser::Name::Local(map) => {
1811                names.locals(&indirect_name_map(map, |i| reencoder.function_index(i))?);
1812            }
1813            wasmparser::Name::Label(map) => {
1814                names.labels(&indirect_name_map(map, |i| reencoder.function_index(i))?);
1815            }
1816            wasmparser::Name::Table(map) => {
1817                names.tables(&name_map(map, |i| reencoder.table_index(i))?);
1818            }
1819            wasmparser::Name::Memory(map) => {
1820                names.memories(&name_map(map, |i| reencoder.memory_index(i))?);
1821            }
1822            wasmparser::Name::Global(map) => {
1823                names.globals(&name_map(map, |i| reencoder.global_index(i))?);
1824            }
1825            wasmparser::Name::Element(map) => {
1826                names.elements(&name_map(map, |i| reencoder.element_index(i))?);
1827            }
1828            wasmparser::Name::Data(map) => {
1829                names.data(&name_map(map, |i| reencoder.data_index(i))?);
1830            }
1831            wasmparser::Name::Tag(map) => {
1832                names.tags(&name_map(map, |i| reencoder.tag_index(i))?);
1833            }
1834            wasmparser::Name::Field(map) => {
1835                names.fields(&indirect_name_map(map, |i| reencoder.type_index(i))?);
1836            }
1837            wasmparser::Name::Unknown { ty, data, .. } => {
1838                names.raw(ty, data);
1839            }
1840        }
1841        Ok(())
1842    }
1843
1844    pub fn name_map<E>(
1845        map: wasmparser::NameMap<'_>,
1846        mut map_index: impl FnMut(u32) -> Result<u32, Error<E>>,
1847    ) -> Result<crate::NameMap, Error<E>> {
1848        let mut ret = crate::NameMap::new();
1849        for naming in map {
1850            let naming = naming?;
1851            ret.append(map_index(naming.index)?, naming.name);
1852        }
1853        Ok(ret)
1854    }
1855
1856    pub fn indirect_name_map<E>(
1857        map: wasmparser::IndirectNameMap<'_>,
1858        mut map_index: impl FnMut(u32) -> Result<u32, Error<E>>,
1859    ) -> Result<crate::IndirectNameMap, Error<E>> {
1860        let mut ret = crate::IndirectNameMap::new();
1861        for naming in map {
1862            let naming = naming?;
1863            ret.append(
1864                map_index(naming.index)?,
1865                &name_map(naming.names, |i| Ok(i))?,
1866            );
1867        }
1868        Ok(ret)
1869    }
1870}
1871
1872impl From<wasmparser::Ieee32> for crate::Ieee32 {
1873    fn from(arg: wasmparser::Ieee32) -> Self {
1874        utils::ieee32_arg(&mut RoundtripReencoder, arg)
1875    }
1876}
1877
1878impl From<wasmparser::Ieee64> for crate::Ieee64 {
1879    fn from(arg: wasmparser::Ieee64) -> Self {
1880        utils::ieee64_arg(&mut RoundtripReencoder, arg)
1881    }
1882}
1883
1884impl TryFrom<wasmparser::MemArg> for crate::MemArg {
1885    type Error = Error;
1886    fn try_from(arg: wasmparser::MemArg) -> Result<Self, Self::Error> {
1887        RoundtripReencoder.mem_arg(arg)
1888    }
1889}
1890
1891impl From<wasmparser::Ordering> for crate::Ordering {
1892    fn from(arg: wasmparser::Ordering) -> Self {
1893        utils::ordering(&mut RoundtripReencoder, arg)
1894    }
1895}
1896
1897impl TryFrom<wasmparser::BlockType> for crate::BlockType {
1898    type Error = Error;
1899
1900    fn try_from(arg: wasmparser::BlockType) -> Result<Self, Self::Error> {
1901        RoundtripReencoder.block_type(arg)
1902    }
1903}
1904
1905impl<'a> TryFrom<wasmparser::Operator<'a>> for crate::Instruction<'a> {
1906    type Error = Error;
1907
1908    fn try_from(arg: wasmparser::Operator<'a>) -> Result<Self, Self::Error> {
1909        RoundtripReencoder.instruction(arg)
1910    }
1911}
1912
1913impl TryFrom<wasmparser::Catch> for crate::Catch {
1914    type Error = Error;
1915
1916    fn try_from(arg: wasmparser::Catch) -> Result<Self, Self::Error> {
1917        RoundtripReencoder.catch(arg)
1918    }
1919}
1920
1921impl<'a> TryFrom<wasmparser::ConstExpr<'a>> for crate::ConstExpr {
1922    type Error = Error;
1923
1924    fn try_from(const_expr: wasmparser::ConstExpr) -> Result<Self, Self::Error> {
1925        RoundtripReencoder.const_expr(const_expr)
1926    }
1927}
1928
1929impl<'a> From<wasmparser::CustomSectionReader<'a>> for crate::CustomSection<'a> {
1930    fn from(section: wasmparser::CustomSectionReader<'a>) -> Self {
1931        utils::custom_section(&mut RoundtripReencoder, section)
1932    }
1933}
1934
1935impl From<wasmparser::ExternalKind> for crate::ExportKind {
1936    fn from(external_kind: wasmparser::ExternalKind) -> Self {
1937        utils::export_kind(&mut RoundtripReencoder, external_kind)
1938    }
1939}
1940
1941impl TryFrom<wasmparser::GlobalType> for crate::GlobalType {
1942    type Error = Error;
1943
1944    fn try_from(global_ty: wasmparser::GlobalType) -> Result<Self, Self::Error> {
1945        RoundtripReencoder.global_type(global_ty)
1946    }
1947}
1948
1949impl TryFrom<wasmparser::Handle> for crate::Handle {
1950    type Error = Error;
1951    fn try_from(arg: wasmparser::Handle) -> Result<Self, Self::Error> {
1952        RoundtripReencoder.handle(arg)
1953    }
1954}
1955
1956impl TryFrom<wasmparser::TypeRef> for crate::EntityType {
1957    type Error = Error;
1958
1959    fn try_from(type_ref: wasmparser::TypeRef) -> Result<Self, Self::Error> {
1960        RoundtripReencoder.entity_type(type_ref)
1961    }
1962}
1963
1964impl From<wasmparser::MemoryType> for crate::MemoryType {
1965    fn from(memory_ty: wasmparser::MemoryType) -> Self {
1966        utils::memory_type(&mut RoundtripReencoder, memory_ty)
1967    }
1968}
1969
1970impl TryFrom<wasmparser::TableType> for crate::TableType {
1971    type Error = Error;
1972
1973    fn try_from(table_ty: wasmparser::TableType) -> Result<Self, Self::Error> {
1974        RoundtripReencoder.table_type(table_ty)
1975    }
1976}
1977
1978impl From<wasmparser::TagKind> for crate::TagKind {
1979    fn from(kind: wasmparser::TagKind) -> Self {
1980        utils::tag_kind(&mut RoundtripReencoder, kind)
1981    }
1982}
1983
1984impl TryFrom<wasmparser::TagType> for crate::TagType {
1985    type Error = Error;
1986    fn try_from(tag_ty: wasmparser::TagType) -> Result<Self, Self::Error> {
1987        RoundtripReencoder.tag_type(tag_ty)
1988    }
1989}
1990
1991impl TryFrom<wasmparser::SubType> for crate::SubType {
1992    type Error = Error;
1993
1994    fn try_from(sub_ty: wasmparser::SubType) -> Result<Self, Self::Error> {
1995        RoundtripReencoder.sub_type(sub_ty)
1996    }
1997}
1998
1999impl TryFrom<wasmparser::CompositeType> for crate::CompositeType {
2000    type Error = Error;
2001
2002    fn try_from(composite_ty: wasmparser::CompositeType) -> Result<Self, Self::Error> {
2003        RoundtripReencoder.composite_type(composite_ty)
2004    }
2005}
2006
2007impl TryFrom<wasmparser::FuncType> for crate::FuncType {
2008    type Error = Error;
2009
2010    fn try_from(func_ty: wasmparser::FuncType) -> Result<Self, Self::Error> {
2011        RoundtripReencoder.func_type(func_ty)
2012    }
2013}
2014
2015impl TryFrom<wasmparser::ArrayType> for crate::ArrayType {
2016    type Error = Error;
2017
2018    fn try_from(array_ty: wasmparser::ArrayType) -> Result<Self, Self::Error> {
2019        RoundtripReencoder.array_type(array_ty)
2020    }
2021}
2022
2023impl TryFrom<wasmparser::StructType> for crate::StructType {
2024    type Error = Error;
2025
2026    fn try_from(struct_ty: wasmparser::StructType) -> Result<Self, Self::Error> {
2027        RoundtripReencoder.struct_type(struct_ty)
2028    }
2029}
2030
2031impl TryFrom<wasmparser::FieldType> for crate::FieldType {
2032    type Error = Error;
2033
2034    fn try_from(field_ty: wasmparser::FieldType) -> Result<Self, Self::Error> {
2035        RoundtripReencoder.field_type(field_ty)
2036    }
2037}
2038
2039impl TryFrom<wasmparser::StorageType> for crate::StorageType {
2040    type Error = Error;
2041
2042    fn try_from(storage_ty: wasmparser::StorageType) -> Result<Self, Self::Error> {
2043        RoundtripReencoder.storage_type(storage_ty)
2044    }
2045}
2046
2047impl TryFrom<wasmparser::ValType> for crate::ValType {
2048    type Error = Error;
2049
2050    fn try_from(val_ty: wasmparser::ValType) -> Result<Self, Self::Error> {
2051        RoundtripReencoder.val_type(val_ty)
2052    }
2053}
2054
2055impl TryFrom<wasmparser::RefType> for crate::RefType {
2056    type Error = Error;
2057
2058    fn try_from(ref_type: wasmparser::RefType) -> Result<Self, Self::Error> {
2059        RoundtripReencoder.ref_type(ref_type)
2060    }
2061}
2062
2063impl TryFrom<wasmparser::HeapType> for crate::HeapType {
2064    type Error = Error;
2065
2066    fn try_from(heap_type: wasmparser::HeapType) -> Result<Self, Self::Error> {
2067        crate::reencode::utils::heap_type(&mut crate::reencode::RoundtripReencoder, heap_type)
2068    }
2069}
2070
2071impl From<wasmparser::AbstractHeapType> for crate::AbstractHeapType {
2072    fn from(value: wasmparser::AbstractHeapType) -> Self {
2073        utils::abstract_heap_type(&mut RoundtripReencoder, value)
2074    }
2075}