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