1use super::{
2 serialize, CountedList, CountedListWriter, CountedWriter, DataSegment, Deserialize,
3 ElementSegment, Error, ExportEntry, External, Func, FuncBody, GlobalEntry, ImportEntry,
4 MemoryType, Serialize, TableType, VarUint32, VarUint7,
5};
6use crate::{elements, io};
7use alloc::{borrow::ToOwned, string::String, vec::Vec};
8
9use super::{name_section::NameSection, reloc_section::RelocSection, types::Type};
10
11#[cfg(feature = "reduced-stack-buffer")]
12const ENTRIES_BUFFER_LENGTH: usize = 256;
13
14#[cfg(not(feature = "reduced-stack-buffer"))]
15const ENTRIES_BUFFER_LENGTH: usize = 16384;
16
17#[derive(Debug, Clone, PartialEq)]
19pub enum Section {
20 Unparsed {
22 id: u8,
24 payload: Vec<u8>,
26 },
27 Custom(CustomSection),
29 Type(TypeSection),
31 Import(ImportSection),
33 Function(FunctionSection),
35 Table(TableSection),
37 Memory(MemorySection),
39 Global(GlobalSection),
41 Export(ExportSection),
43 Start(u32),
45 Element(ElementSection),
47 DataCount(u32),
49 Code(CodeSection),
51 Data(DataSection),
53 Name(NameSection),
57 Reloc(RelocSection),
63}
64
65impl Deserialize for Section {
66 type Error = Error;
67
68 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
69 let id = match VarUint7::deserialize(reader) {
70 Err(_) => return Err(Error::UnexpectedEof),
72 Ok(id) => id,
73 };
74
75 Ok(match id.into() {
76 0 => Section::Custom(CustomSection::deserialize(reader)?),
77 1 => Section::Type(TypeSection::deserialize(reader)?),
78 2 => Section::Import(ImportSection::deserialize(reader)?),
79 3 => Section::Function(FunctionSection::deserialize(reader)?),
80 4 => Section::Table(TableSection::deserialize(reader)?),
81 5 => Section::Memory(MemorySection::deserialize(reader)?),
82 6 => Section::Global(GlobalSection::deserialize(reader)?),
83 7 => Section::Export(ExportSection::deserialize(reader)?),
84 8 => {
85 let mut section_reader = SectionReader::new(reader)?;
86 let start_idx = VarUint32::deserialize(&mut section_reader)?;
87 section_reader.close()?;
88 Section::Start(start_idx.into())
89 },
90 9 => Section::Element(ElementSection::deserialize(reader)?),
91 10 => Section::Code(CodeSection::deserialize(reader)?),
92 11 => Section::Data(DataSection::deserialize(reader)?),
93 12 => {
94 let mut section_reader = SectionReader::new(reader)?;
95 let count = VarUint32::deserialize(&mut section_reader)?;
96 section_reader.close()?;
97 Section::DataCount(count.into())
98 },
99 invalid_id => return Err(Error::InvalidSectionId(invalid_id)),
100 })
101 }
102}
103
104impl Serialize for Section {
105 type Error = Error;
106
107 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
108 match self {
109 Section::Custom(custom_section) => {
110 VarUint7::from(0x00).serialize(writer)?;
111 custom_section.serialize(writer)?;
112 },
113 Section::Unparsed { id, payload } => {
114 VarUint7::from(id).serialize(writer)?;
115 writer.write(&payload[..])?;
116 },
117 Section::Type(type_section) => {
118 VarUint7::from(0x01).serialize(writer)?;
119 type_section.serialize(writer)?;
120 },
121 Section::Import(import_section) => {
122 VarUint7::from(0x02).serialize(writer)?;
123 import_section.serialize(writer)?;
124 },
125 Section::Function(function_section) => {
126 VarUint7::from(0x03).serialize(writer)?;
127 function_section.serialize(writer)?;
128 },
129 Section::Table(table_section) => {
130 VarUint7::from(0x04).serialize(writer)?;
131 table_section.serialize(writer)?;
132 },
133 Section::Memory(memory_section) => {
134 VarUint7::from(0x05).serialize(writer)?;
135 memory_section.serialize(writer)?;
136 },
137 Section::Global(global_section) => {
138 VarUint7::from(0x06).serialize(writer)?;
139 global_section.serialize(writer)?;
140 },
141 Section::Export(export_section) => {
142 VarUint7::from(0x07).serialize(writer)?;
143 export_section.serialize(writer)?;
144 },
145 Section::Start(index) => {
146 VarUint7::from(0x08).serialize(writer)?;
147 let mut counted_writer = CountedWriter::new(writer);
148 VarUint32::from(index).serialize(&mut counted_writer)?;
149 counted_writer.done()?;
150 },
151 Section::DataCount(count) => {
152 VarUint7::from(0x0c).serialize(writer)?;
153 let mut counted_writer = CountedWriter::new(writer);
154 VarUint32::from(count).serialize(&mut counted_writer)?;
155 counted_writer.done()?;
156 },
157 Section::Element(element_section) => {
158 VarUint7::from(0x09).serialize(writer)?;
159 element_section.serialize(writer)?;
160 },
161 Section::Code(code_section) => {
162 VarUint7::from(0x0a).serialize(writer)?;
163 code_section.serialize(writer)?;
164 },
165 Section::Data(data_section) => {
166 VarUint7::from(0x0b).serialize(writer)?;
167 data_section.serialize(writer)?;
168 },
169 Section::Name(name_section) => {
170 VarUint7::from(0x00).serialize(writer)?;
171 let custom =
172 CustomSection { name: "name".to_owned(), payload: serialize(name_section)? };
173 custom.serialize(writer)?;
174 },
175 Section::Reloc(reloc_section) => {
176 VarUint7::from(0x00).serialize(writer)?;
177 reloc_section.serialize(writer)?;
178 },
179 }
180 Ok(())
181 }
182}
183
184impl Section {
185 pub(crate) fn order(&self) -> u8 {
186 match *self {
187 Section::Custom(_) => 0x00,
188 Section::Unparsed { .. } => 0x00,
189 Section::Type(_) => 0x1,
190 Section::Import(_) => 0x2,
191 Section::Function(_) => 0x3,
192 Section::Table(_) => 0x4,
193 Section::Memory(_) => 0x5,
194 Section::Global(_) => 0x6,
195 Section::Export(_) => 0x7,
196 Section::Start(_) => 0x8,
197 Section::Element(_) => 0x9,
198 Section::DataCount(_) => 0x0a,
199 Section::Code(_) => 0x0b,
200 Section::Data(_) => 0x0c,
201 Section::Name(_) => 0x00,
202 Section::Reloc(_) => 0x00,
203 }
204 }
205}
206
207pub(crate) struct SectionReader {
208 cursor: io::Cursor<Vec<u8>>,
209 declared_length: usize,
210}
211
212impl SectionReader {
213 pub fn new<R: io::Read>(reader: &mut R) -> Result<Self, elements::Error> {
214 let length = u32::from(VarUint32::deserialize(reader)?) as usize;
215 let inner_buffer = buffered_read!(ENTRIES_BUFFER_LENGTH, length, reader);
216 let declared_length = inner_buffer.len();
217 let cursor = io::Cursor::new(inner_buffer);
218
219 Ok(SectionReader { cursor, declared_length })
220 }
221
222 pub fn close(self) -> Result<(), io::Error> {
223 let cursor = self.cursor;
224 let buf_length = self.declared_length;
225
226 if cursor.position() != buf_length {
227 Err(io::Error::InvalidData)
228 } else {
229 Ok(())
230 }
231 }
232}
233
234impl io::Read for SectionReader {
235 fn read(&mut self, buf: &mut [u8]) -> io::Result<()> {
236 self.cursor.read(buf)?;
237 Ok(())
238 }
239}
240
241fn read_entries<R: io::Read, T: Deserialize<Error = elements::Error>>(
242 reader: &mut R,
243) -> Result<Vec<T>, elements::Error> {
244 let mut section_reader = SectionReader::new(reader)?;
245 let result = CountedList::<T>::deserialize(&mut section_reader)?.into_inner();
246 section_reader.close()?;
247 Ok(result)
248}
249
250#[derive(Debug, Default, Clone, PartialEq)]
252pub struct CustomSection {
253 name: String,
254 payload: Vec<u8>,
255}
256
257impl CustomSection {
258 pub fn new(name: String, payload: Vec<u8>) -> CustomSection {
260 CustomSection { name, payload }
261 }
262
263 pub fn name(&self) -> &str {
265 &self.name
266 }
267
268 pub fn payload(&self) -> &[u8] {
270 &self.payload
271 }
272
273 pub fn name_mut(&mut self) -> &mut String {
275 &mut self.name
276 }
277
278 pub fn payload_mut(&mut self) -> &mut Vec<u8> {
280 &mut self.payload
281 }
282}
283
284impl Deserialize for CustomSection {
285 type Error = Error;
286
287 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
288 let section_length: usize = u32::from(VarUint32::deserialize(reader)?) as usize;
289 let buf = buffered_read!(ENTRIES_BUFFER_LENGTH, section_length, reader);
290 let mut cursor = io::Cursor::new(&buf[..]);
291 let name = String::deserialize(&mut cursor)?;
292 let payload = buf[cursor.position() as usize..].to_vec();
293 Ok(CustomSection { name, payload })
294 }
295}
296
297impl Serialize for CustomSection {
298 type Error = Error;
299
300 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
301 use io::Write;
302
303 let mut counted_writer = CountedWriter::new(writer);
304 self.name.serialize(&mut counted_writer)?;
305 counted_writer.write(&self.payload[..])?;
306 counted_writer.done()?;
307 Ok(())
308 }
309}
310
311#[derive(Debug, Default, Clone, PartialEq)]
313pub struct TypeSection(Vec<Type>);
314
315impl TypeSection {
316 pub fn with_types(types: Vec<Type>) -> Self {
318 TypeSection(types)
319 }
320
321 pub fn types(&self) -> &[Type] {
323 &self.0
324 }
325
326 pub fn types_mut(&mut self) -> &mut Vec<Type> {
328 &mut self.0
329 }
330}
331
332impl Deserialize for TypeSection {
333 type Error = Error;
334
335 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
336 Ok(TypeSection(read_entries(reader)?))
337 }
338}
339
340impl Serialize for TypeSection {
341 type Error = Error;
342
343 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
344 let mut counted_writer = CountedWriter::new(writer);
345 let data = self.0;
346 let counted_list =
347 CountedListWriter::<Type, _>(data.len(), data.into_iter().map(Into::into));
348 counted_list.serialize(&mut counted_writer)?;
349 counted_writer.done()?;
350 Ok(())
351 }
352}
353
354#[derive(Debug, Default, Clone, PartialEq)]
356pub struct ImportSection(Vec<ImportEntry>);
357
358impl ImportSection {
359 pub fn with_entries(entries: Vec<ImportEntry>) -> Self {
361 ImportSection(entries)
362 }
363
364 pub fn entries(&self) -> &[ImportEntry] {
366 &self.0
367 }
368
369 pub fn entries_mut(&mut self) -> &mut Vec<ImportEntry> {
371 &mut self.0
372 }
373
374 pub fn functions(&self) -> usize {
376 self.0
377 .iter()
378 .filter(|entry| matches!(*entry.external(), External::Function(_)))
379 .count()
380 }
381
382 pub fn globals(&self) -> usize {
384 self.0
385 .iter()
386 .filter(|entry| matches!(entry.external(), &External::Global(_)))
387 .count()
388 }
389}
390
391impl Deserialize for ImportSection {
392 type Error = Error;
393
394 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
395 Ok(ImportSection(read_entries(reader)?))
396 }
397}
398
399impl Serialize for ImportSection {
400 type Error = Error;
401
402 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
403 let mut counted_writer = CountedWriter::new(writer);
404 let data = self.0;
405 let counted_list =
406 CountedListWriter::<ImportEntry, _>(data.len(), data.into_iter().map(Into::into));
407 counted_list.serialize(&mut counted_writer)?;
408 counted_writer.done()?;
409 Ok(())
410 }
411}
412
413#[derive(Default, Debug, Clone, PartialEq)]
415pub struct FunctionSection(Vec<Func>);
416
417impl FunctionSection {
418 pub fn with_entries(entries: Vec<Func>) -> Self {
420 FunctionSection(entries)
421 }
422
423 pub fn entries_mut(&mut self) -> &mut Vec<Func> {
425 &mut self.0
426 }
427
428 pub fn entries(&self) -> &[Func] {
430 &self.0
431 }
432}
433
434impl Deserialize for FunctionSection {
435 type Error = Error;
436
437 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
438 Ok(FunctionSection(read_entries(reader)?))
439 }
440}
441
442impl Serialize for FunctionSection {
443 type Error = Error;
444
445 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
446 let mut counted_writer = CountedWriter::new(writer);
447 let data = self.0;
448 let counted_list = CountedListWriter::<VarUint32, _>(
449 data.len(),
450 data.into_iter().map(|func| func.type_ref().into()),
451 );
452 counted_list.serialize(&mut counted_writer)?;
453 counted_writer.done()?;
454 Ok(())
455 }
456}
457
458#[derive(Default, Debug, Clone, PartialEq)]
460pub struct TableSection(Vec<TableType>);
461
462impl TableSection {
463 pub fn entries(&self) -> &[TableType] {
465 &self.0
466 }
467
468 pub fn with_entries(entries: Vec<TableType>) -> Self {
470 TableSection(entries)
471 }
472
473 pub fn entries_mut(&mut self) -> &mut Vec<TableType> {
475 &mut self.0
476 }
477}
478
479impl Deserialize for TableSection {
480 type Error = Error;
481
482 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
483 Ok(TableSection(read_entries(reader)?))
484 }
485}
486
487impl Serialize for TableSection {
488 type Error = Error;
489
490 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
491 let mut counted_writer = CountedWriter::new(writer);
492 let data = self.0;
493 let counted_list =
494 CountedListWriter::<TableType, _>(data.len(), data.into_iter().map(Into::into));
495 counted_list.serialize(&mut counted_writer)?;
496 counted_writer.done()?;
497 Ok(())
498 }
499}
500
501#[derive(Default, Debug, Clone, PartialEq)]
503pub struct MemorySection(Vec<MemoryType>);
504
505impl MemorySection {
506 pub fn entries(&self) -> &[MemoryType] {
508 &self.0
509 }
510
511 pub fn with_entries(entries: Vec<MemoryType>) -> Self {
513 MemorySection(entries)
514 }
515
516 pub fn entries_mut(&mut self) -> &mut Vec<MemoryType> {
518 &mut self.0
519 }
520}
521
522impl Deserialize for MemorySection {
523 type Error = Error;
524
525 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
526 Ok(MemorySection(read_entries(reader)?))
527 }
528}
529
530impl Serialize for MemorySection {
531 type Error = Error;
532
533 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
534 let mut counted_writer = CountedWriter::new(writer);
535 let data = self.0;
536 let counted_list =
537 CountedListWriter::<MemoryType, _>(data.len(), data.into_iter().map(Into::into));
538 counted_list.serialize(&mut counted_writer)?;
539 counted_writer.done()?;
540 Ok(())
541 }
542}
543
544#[derive(Default, Debug, Clone, PartialEq)]
546pub struct GlobalSection(Vec<GlobalEntry>);
547
548impl GlobalSection {
549 pub fn entries(&self) -> &[GlobalEntry] {
551 &self.0
552 }
553
554 pub fn with_entries(entries: Vec<GlobalEntry>) -> Self {
556 GlobalSection(entries)
557 }
558
559 pub fn entries_mut(&mut self) -> &mut Vec<GlobalEntry> {
561 &mut self.0
562 }
563}
564
565impl Deserialize for GlobalSection {
566 type Error = Error;
567
568 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
569 Ok(GlobalSection(read_entries(reader)?))
570 }
571}
572
573impl Serialize for GlobalSection {
574 type Error = Error;
575
576 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
577 let mut counted_writer = CountedWriter::new(writer);
578 let data = self.0;
579 let counted_list =
580 CountedListWriter::<GlobalEntry, _>(data.len(), data.into_iter().map(Into::into));
581 counted_list.serialize(&mut counted_writer)?;
582 counted_writer.done()?;
583 Ok(())
584 }
585}
586
587#[derive(Debug, Default, Clone, PartialEq)]
589pub struct ExportSection(Vec<ExportEntry>);
590
591impl ExportSection {
592 pub fn entries(&self) -> &[ExportEntry] {
594 &self.0
595 }
596
597 pub fn with_entries(entries: Vec<ExportEntry>) -> Self {
599 ExportSection(entries)
600 }
601
602 pub fn entries_mut(&mut self) -> &mut Vec<ExportEntry> {
604 &mut self.0
605 }
606}
607
608impl Deserialize for ExportSection {
609 type Error = Error;
610
611 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
612 Ok(ExportSection(read_entries(reader)?))
613 }
614}
615
616impl Serialize for ExportSection {
617 type Error = Error;
618
619 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
620 let mut counted_writer = CountedWriter::new(writer);
621 let data = self.0;
622 let counted_list =
623 CountedListWriter::<ExportEntry, _>(data.len(), data.into_iter().map(Into::into));
624 counted_list.serialize(&mut counted_writer)?;
625 counted_writer.done()?;
626 Ok(())
627 }
628}
629
630#[derive(Default, Debug, Clone, PartialEq)]
632pub struct CodeSection(Vec<FuncBody>);
633
634impl CodeSection {
635 pub fn with_bodies(bodies: Vec<FuncBody>) -> Self {
637 CodeSection(bodies)
638 }
639
640 pub fn bodies(&self) -> &[FuncBody] {
642 &self.0
643 }
644
645 pub fn bodies_mut(&mut self) -> &mut Vec<FuncBody> {
647 &mut self.0
648 }
649}
650
651impl Deserialize for CodeSection {
652 type Error = Error;
653
654 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
655 Ok(CodeSection(read_entries(reader)?))
656 }
657}
658
659impl Serialize for CodeSection {
660 type Error = Error;
661
662 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
663 let mut counted_writer = CountedWriter::new(writer);
664 let data = self.0;
665 let counted_list =
666 CountedListWriter::<FuncBody, _>(data.len(), data.into_iter().map(Into::into));
667 counted_list.serialize(&mut counted_writer)?;
668 counted_writer.done()?;
669 Ok(())
670 }
671}
672
673#[derive(Default, Debug, Clone, PartialEq)]
675pub struct ElementSection(Vec<ElementSegment>);
676
677impl ElementSection {
678 pub fn with_entries(entries: Vec<ElementSegment>) -> Self {
680 ElementSection(entries)
681 }
682
683 pub fn entries(&self) -> &[ElementSegment] {
685 &self.0
686 }
687
688 pub fn entries_mut(&mut self) -> &mut Vec<ElementSegment> {
690 &mut self.0
691 }
692}
693
694impl Deserialize for ElementSection {
695 type Error = Error;
696
697 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
698 Ok(ElementSection(read_entries(reader)?))
699 }
700}
701
702impl Serialize for ElementSection {
703 type Error = Error;
704
705 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
706 let mut counted_writer = CountedWriter::new(writer);
707 let data = self.0;
708 let counted_list =
709 CountedListWriter::<ElementSegment, _>(data.len(), data.into_iter().map(Into::into));
710 counted_list.serialize(&mut counted_writer)?;
711 counted_writer.done()?;
712 Ok(())
713 }
714}
715
716#[derive(Default, Debug, Clone, PartialEq)]
718pub struct DataSection(Vec<DataSegment>);
719
720impl DataSection {
721 pub fn with_entries(entries: Vec<DataSegment>) -> Self {
723 DataSection(entries)
724 }
725
726 pub fn entries(&self) -> &[DataSegment] {
728 &self.0
729 }
730
731 pub fn entries_mut(&mut self) -> &mut Vec<DataSegment> {
733 &mut self.0
734 }
735}
736
737impl Deserialize for DataSection {
738 type Error = Error;
739
740 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
741 Ok(DataSection(read_entries(reader)?))
742 }
743}
744
745impl Serialize for DataSection {
746 type Error = Error;
747
748 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
749 let mut counted_writer = CountedWriter::new(writer);
750 let data = self.0;
751 let counted_list =
752 CountedListWriter::<DataSegment, _>(data.len(), data.into_iter().map(Into::into));
753 counted_list.serialize(&mut counted_writer)?;
754 counted_writer.done()?;
755 Ok(())
756 }
757}
758
759#[cfg(test)]
760mod tests {
761
762 use super::{
763 super::{
764 deserialize_buffer, deserialize_file, serialize, BlockType, DataSegment,
765 ElementSegment, FuncBody, InitExpr, Instructions, Local, ValueType,
766 },
767 CodeSection, DataSection, ElementSection, Section, Type, TypeSection,
768 };
769
770 #[test]
771 fn import_section() {
772 let module = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized");
773 let mut found = false;
774 for section in module.sections() {
775 if let Section::Import(ref import_section) = *section {
776 assert_eq!(25, import_section.entries().len());
777 found = true
778 }
779 }
780 assert!(found, "There should be import section in test5.wasm");
781 }
782
783 fn functions_test_payload() -> &'static [u8] {
784 &[
785 0x03u8, 0x87, 0x80, 0x80, 0x80, 0x0, 0x04, 0x01, 0x86, 0x80, 0x00, 0x09, 0x33,
793 ]
794 }
795
796 #[test]
797 fn fn_section_detect() {
798 let section: Section =
799 deserialize_buffer(functions_test_payload()).expect("section to be deserialized");
800
801 match section {
802 Section::Function(_) => {},
803 _ => {
804 panic!("Payload should be recognized as functions section")
805 },
806 }
807 }
808
809 #[test]
810 fn fn_section_number() {
811 let section: Section =
812 deserialize_buffer(functions_test_payload()).expect("section to be deserialized");
813
814 if let Section::Function(fn_section) = section {
815 assert_eq!(4, fn_section.entries().len(), "There should be 4 functions total");
816 }
817 }
818
819 #[test]
820 fn fn_section_ref() {
821 let section: Section =
822 deserialize_buffer(functions_test_payload()).expect("section to be deserialized");
823
824 if let Section::Function(fn_section) = section {
825 assert_eq!(6, fn_section.entries()[1].type_ref());
826 }
827 }
828
829 fn types_test_payload() -> &'static [u8] {
830 &[
831 11, 2, 0x60, 1, 0x7e, 0x00, 0x60, 2, 0x7e, 0x7d, 0x01, 0x7e,
844 ]
845 }
846
847 #[test]
848 fn type_section_len() {
849 let type_section: TypeSection =
850 deserialize_buffer(types_test_payload()).expect("type_section be deserialized");
851
852 assert_eq!(type_section.types().len(), 2);
853 }
854
855 #[test]
856 fn type_section_infer() {
857 let type_section: TypeSection =
858 deserialize_buffer(types_test_payload()).expect("type_section be deserialized");
859
860 let Type::Function(ref t1) = type_section.types()[1];
861 assert_eq!(vec![ValueType::I64], t1.results());
862 assert_eq!(2, t1.params().len());
863 }
864
865 fn export_payload() -> &'static [u8] {
866 &[
867 0x07, 28, 6,
871 0x01, 0x41, 0x01, 0x86, 0x80, 0x00, 0x01, 0x42, 0x01, 0x86, 0x00, 0x01, 0x43, 0x01, 0x07, 0x01, 0x44, 0x02, 0x00, 0x01, 0x45, 0x01, 0x01, 0x01, 0x46, 0x01, 0x02,
879 ]
880 }
881
882 #[test]
883 fn export_detect() {
884 let section: Section =
885 deserialize_buffer(export_payload()).expect("section to be deserialized");
886
887 match section {
888 Section::Export(_) => {},
889 _ => {
890 panic!("Payload should be recognized as export section")
891 },
892 }
893 }
894
895 fn code_payload() -> &'static [u8] {
896 &[
897 0x0Au8, 0x20, 0x01, 0x1E, 0x01, 0x01, 0x7F, 0x02, 0x7F, 0x23, 0x00, 0x21, 0x01, 0x23, 0x00, 0x20, 0x00, 0x6A, 0x24, 0x00, 0x23, 0x00, 0x41, 0x0F, 0x6A, 0x41, 0x70, 0x71, 0x24, 0x00, 0x20, 0x01, 0x0B, 0x0B,
917 ]
918 }
919
920 #[test]
921 fn code_detect() {
922 let section: Section =
923 deserialize_buffer(code_payload()).expect("section to be deserialized");
924
925 match section {
926 Section::Code(_) => {},
927 _ => {
928 panic!("Payload should be recognized as a code section")
929 },
930 }
931 }
932
933 fn data_payload() -> &'static [u8] {
934 &[
935 0x0bu8, 20, 0x01, 0x00, 0x0b, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
942 0x00, 0x00,
943 ]
944 }
945
946 #[test]
947 fn data_section_ser() {
948 let data_section = DataSection::with_entries(vec![DataSegment::new(
949 0u32,
950 Some(InitExpr::empty()),
951 vec![0u8; 16],
952 )]);
953
954 let buf = serialize(data_section).expect("Data section to be serialized");
955
956 assert_eq!(
957 buf,
958 vec![
959 20u8, 0x01, 0x00, 0x0b, 16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
966 ]
967 );
968 }
969
970 #[test]
971 fn data_section_detect() {
972 let section: Section =
973 deserialize_buffer(data_payload()).expect("section to be deserialized");
974
975 match section {
976 Section::Data(_) => {},
977 _ => {
978 panic!("Payload should be recognized as a data section")
979 },
980 }
981 }
982
983 #[test]
984 fn element_section_ser() {
985 let element_section = ElementSection::with_entries(vec![ElementSegment::new(
986 0u32,
987 Some(InitExpr::empty()),
988 vec![0u32; 4],
989 )]);
990
991 let buf = serialize(element_section).expect("Element section to be serialized");
992
993 assert_eq!(
994 buf,
995 vec![
996 8u8, 0x01, 0x00, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00 ]
1003 );
1004 }
1005
1006 #[test]
1007 fn code_section_ser() {
1008 use super::super::Instruction::*;
1009
1010 let code_section = CodeSection::with_bodies(vec![FuncBody::new(
1011 vec![Local::new(1, ValueType::I32)],
1012 Instructions::new(vec![
1013 Block(BlockType::Value(ValueType::I32)),
1014 GetGlobal(0),
1015 End,
1016 End,
1017 ]),
1018 )]);
1019
1020 let buf = serialize(code_section).expect("Code section to be serialized");
1021
1022 assert_eq!(
1023 buf,
1024 vec![
1025 11u8, 0x01, 9, 1, 1, 0x7f, 0x02, 0x7f, 0x23, 0x00, 0x0b, 0x0b, ]
1037 );
1038 }
1039
1040 #[test]
1041 fn start_section() {
1042 let section: Section =
1043 deserialize_buffer(&[8u8, 1u8, 0u8]).expect("Start section to deserialize");
1044 if let Section::Start(_) = section {
1045 } else {
1046 panic!("Payload should be a start section");
1047 }
1048
1049 let serialized = serialize(section).expect("Start section to successfully serializen");
1050
1051 assert_eq!(serialized, vec![8u8, 1u8, 0u8]);
1052 }
1053}