1#[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)] pub 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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#[derive(Debug)]
570pub enum Error<E = Infallible> {
571 CanonicalizedHeapTypeReference,
575 InvalidConstExpr,
578 InvalidCodeSectionSize,
580 UnexpectedNonCoreModuleSection,
582 UnexpectedNonComponentSection,
584 UnsupportedCoreTypeInComponent,
586 ParseError(wasmparser::BinaryReaderError),
588 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#[derive(Debug)]
645pub struct RoundtripReencoder;
646
647impl Reencode for RoundtripReencoder {
648 type Error = Infallible;
649}
650
651#[allow(missing_docs)] pub 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 (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 (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 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 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 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 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}