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