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()..].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 = CountedListWriter::<Type, _>(data.len(), data.into_iter());
347 counted_list.serialize(&mut counted_writer)?;
348 counted_writer.done()?;
349 Ok(())
350 }
351}
352
353#[derive(Debug, Default, Clone, PartialEq)]
355pub struct ImportSection(Vec<ImportEntry>);
356
357impl ImportSection {
358 pub fn with_entries(entries: Vec<ImportEntry>) -> Self {
360 ImportSection(entries)
361 }
362
363 pub fn entries(&self) -> &[ImportEntry] {
365 &self.0
366 }
367
368 pub fn entries_mut(&mut self) -> &mut Vec<ImportEntry> {
370 &mut self.0
371 }
372
373 pub fn functions(&self) -> usize {
375 self.0
376 .iter()
377 .filter(|entry| matches!(*entry.external(), External::Function(_)))
378 .count()
379 }
380
381 pub fn globals(&self) -> usize {
383 self.0
384 .iter()
385 .filter(|entry| matches!(entry.external(), &External::Global(_)))
386 .count()
387 }
388}
389
390impl Deserialize for ImportSection {
391 type Error = Error;
392
393 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
394 Ok(ImportSection(read_entries(reader)?))
395 }
396}
397
398impl Serialize for ImportSection {
399 type Error = Error;
400
401 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
402 let mut counted_writer = CountedWriter::new(writer);
403 let data = self.0;
404 let counted_list = CountedListWriter::<ImportEntry, _>(data.len(), data.into_iter());
405 counted_list.serialize(&mut counted_writer)?;
406 counted_writer.done()?;
407 Ok(())
408 }
409}
410
411#[derive(Default, Debug, Clone, PartialEq)]
413pub struct FunctionSection(Vec<Func>);
414
415impl FunctionSection {
416 pub fn with_entries(entries: Vec<Func>) -> Self {
418 FunctionSection(entries)
419 }
420
421 pub fn entries_mut(&mut self) -> &mut Vec<Func> {
423 &mut self.0
424 }
425
426 pub fn entries(&self) -> &[Func] {
428 &self.0
429 }
430}
431
432impl Deserialize for FunctionSection {
433 type Error = Error;
434
435 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
436 Ok(FunctionSection(read_entries(reader)?))
437 }
438}
439
440impl Serialize for FunctionSection {
441 type Error = Error;
442
443 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
444 let mut counted_writer = CountedWriter::new(writer);
445 let data = self.0;
446 let counted_list = CountedListWriter::<VarUint32, _>(
447 data.len(),
448 data.into_iter().map(|func| func.type_ref().into()),
449 );
450 counted_list.serialize(&mut counted_writer)?;
451 counted_writer.done()?;
452 Ok(())
453 }
454}
455
456#[derive(Default, Debug, Clone, PartialEq)]
458pub struct TableSection(Vec<TableType>);
459
460impl TableSection {
461 pub fn entries(&self) -> &[TableType] {
463 &self.0
464 }
465
466 pub fn with_entries(entries: Vec<TableType>) -> Self {
468 TableSection(entries)
469 }
470
471 pub fn entries_mut(&mut self) -> &mut Vec<TableType> {
473 &mut self.0
474 }
475}
476
477impl Deserialize for TableSection {
478 type Error = Error;
479
480 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
481 Ok(TableSection(read_entries(reader)?))
482 }
483}
484
485impl Serialize for TableSection {
486 type Error = Error;
487
488 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
489 let mut counted_writer = CountedWriter::new(writer);
490 let data = self.0;
491 let counted_list = CountedListWriter::<TableType, _>(data.len(), data.into_iter());
492 counted_list.serialize(&mut counted_writer)?;
493 counted_writer.done()?;
494 Ok(())
495 }
496}
497
498#[derive(Default, Debug, Clone, PartialEq)]
500pub struct MemorySection(Vec<MemoryType>);
501
502impl MemorySection {
503 pub fn entries(&self) -> &[MemoryType] {
505 &self.0
506 }
507
508 pub fn with_entries(entries: Vec<MemoryType>) -> Self {
510 MemorySection(entries)
511 }
512
513 pub fn entries_mut(&mut self) -> &mut Vec<MemoryType> {
515 &mut self.0
516 }
517}
518
519impl Deserialize for MemorySection {
520 type Error = Error;
521
522 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
523 Ok(MemorySection(read_entries(reader)?))
524 }
525}
526
527impl Serialize for MemorySection {
528 type Error = Error;
529
530 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
531 let mut counted_writer = CountedWriter::new(writer);
532 let data = self.0;
533 let counted_list = CountedListWriter::<MemoryType, _>(data.len(), data.into_iter());
534 counted_list.serialize(&mut counted_writer)?;
535 counted_writer.done()?;
536 Ok(())
537 }
538}
539
540#[derive(Default, Debug, Clone, PartialEq)]
542pub struct GlobalSection(Vec<GlobalEntry>);
543
544impl GlobalSection {
545 pub fn entries(&self) -> &[GlobalEntry] {
547 &self.0
548 }
549
550 pub fn with_entries(entries: Vec<GlobalEntry>) -> Self {
552 GlobalSection(entries)
553 }
554
555 pub fn entries_mut(&mut self) -> &mut Vec<GlobalEntry> {
557 &mut self.0
558 }
559}
560
561impl Deserialize for GlobalSection {
562 type Error = Error;
563
564 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
565 Ok(GlobalSection(read_entries(reader)?))
566 }
567}
568
569impl Serialize for GlobalSection {
570 type Error = Error;
571
572 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
573 let mut counted_writer = CountedWriter::new(writer);
574 let data = self.0;
575 let counted_list = CountedListWriter::<GlobalEntry, _>(data.len(), data.into_iter());
576 counted_list.serialize(&mut counted_writer)?;
577 counted_writer.done()?;
578 Ok(())
579 }
580}
581
582#[derive(Debug, Default, Clone, PartialEq)]
584pub struct ExportSection(Vec<ExportEntry>);
585
586impl ExportSection {
587 pub fn entries(&self) -> &[ExportEntry] {
589 &self.0
590 }
591
592 pub fn with_entries(entries: Vec<ExportEntry>) -> Self {
594 ExportSection(entries)
595 }
596
597 pub fn entries_mut(&mut self) -> &mut Vec<ExportEntry> {
599 &mut self.0
600 }
601}
602
603impl Deserialize for ExportSection {
604 type Error = Error;
605
606 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
607 Ok(ExportSection(read_entries(reader)?))
608 }
609}
610
611impl Serialize for ExportSection {
612 type Error = Error;
613
614 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
615 let mut counted_writer = CountedWriter::new(writer);
616 let data = self.0;
617 let counted_list = CountedListWriter::<ExportEntry, _>(data.len(), data.into_iter());
618 counted_list.serialize(&mut counted_writer)?;
619 counted_writer.done()?;
620 Ok(())
621 }
622}
623
624#[derive(Default, Debug, Clone, PartialEq)]
626pub struct CodeSection(Vec<FuncBody>);
627
628impl CodeSection {
629 pub fn with_bodies(bodies: Vec<FuncBody>) -> Self {
631 CodeSection(bodies)
632 }
633
634 pub fn bodies(&self) -> &[FuncBody] {
636 &self.0
637 }
638
639 pub fn bodies_mut(&mut self) -> &mut Vec<FuncBody> {
641 &mut self.0
642 }
643}
644
645impl Deserialize for CodeSection {
646 type Error = Error;
647
648 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
649 Ok(CodeSection(read_entries(reader)?))
650 }
651}
652
653impl Serialize for CodeSection {
654 type Error = Error;
655
656 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
657 let mut counted_writer = CountedWriter::new(writer);
658 let data = self.0;
659 let counted_list = CountedListWriter::<FuncBody, _>(data.len(), data.into_iter());
660 counted_list.serialize(&mut counted_writer)?;
661 counted_writer.done()?;
662 Ok(())
663 }
664}
665
666#[derive(Default, Debug, Clone, PartialEq)]
668pub struct ElementSection(Vec<ElementSegment>);
669
670impl ElementSection {
671 pub fn with_entries(entries: Vec<ElementSegment>) -> Self {
673 ElementSection(entries)
674 }
675
676 pub fn entries(&self) -> &[ElementSegment] {
678 &self.0
679 }
680
681 pub fn entries_mut(&mut self) -> &mut Vec<ElementSegment> {
683 &mut self.0
684 }
685}
686
687impl Deserialize for ElementSection {
688 type Error = Error;
689
690 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
691 Ok(ElementSection(read_entries(reader)?))
692 }
693}
694
695impl Serialize for ElementSection {
696 type Error = Error;
697
698 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
699 let mut counted_writer = CountedWriter::new(writer);
700 let data = self.0;
701 let counted_list = CountedListWriter::<ElementSegment, _>(data.len(), data.into_iter());
702 counted_list.serialize(&mut counted_writer)?;
703 counted_writer.done()?;
704 Ok(())
705 }
706}
707
708#[derive(Default, Debug, Clone, PartialEq)]
710pub struct DataSection(Vec<DataSegment>);
711
712impl DataSection {
713 pub fn with_entries(entries: Vec<DataSegment>) -> Self {
715 DataSection(entries)
716 }
717
718 pub fn entries(&self) -> &[DataSegment] {
720 &self.0
721 }
722
723 pub fn entries_mut(&mut self) -> &mut Vec<DataSegment> {
725 &mut self.0
726 }
727}
728
729impl Deserialize for DataSection {
730 type Error = Error;
731
732 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
733 Ok(DataSection(read_entries(reader)?))
734 }
735}
736
737impl Serialize for DataSection {
738 type Error = Error;
739
740 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
741 let mut counted_writer = CountedWriter::new(writer);
742 let data = self.0;
743 let counted_list = CountedListWriter::<DataSegment, _>(data.len(), data.into_iter());
744 counted_list.serialize(&mut counted_writer)?;
745 counted_writer.done()?;
746 Ok(())
747 }
748}
749
750#[cfg(test)]
751mod tests {
752
753 #[cfg(feature = "std")]
754 use super::super::deserialize_file;
755 use super::{
756 super::{
757 deserialize_buffer, serialize, BlockType, DataSegment, ElementSegment, FuncBody,
758 InitExpr, Instructions, Local, ValueType,
759 },
760 CodeSection, DataSection, ElementSection, Section, Type, TypeSection,
761 };
762
763 #[cfg(feature = "std")]
764 #[test]
765 fn import_section() {
766 let module = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized");
767 let mut found = false;
768 for section in module.sections() {
769 if let Section::Import(ref import_section) = *section {
770 assert_eq!(25, import_section.entries().len());
771 found = true
772 }
773 }
774 assert!(found, "There should be import section in test5.wasm");
775 }
776
777 fn functions_test_payload() -> &'static [u8] {
778 &[
779 0x03u8, 0x87, 0x80, 0x80, 0x80, 0x0, 0x04, 0x01, 0x86, 0x80, 0x00, 0x09, 0x33,
787 ]
788 }
789
790 #[test]
791 fn fn_section_detect() {
792 let section: Section =
793 deserialize_buffer(functions_test_payload()).expect("section to be deserialized");
794
795 match section {
796 Section::Function(_) => {},
797 _ => {
798 panic!("Payload should be recognized as functions section")
799 },
800 }
801 }
802
803 #[test]
804 fn fn_section_number() {
805 let section: Section =
806 deserialize_buffer(functions_test_payload()).expect("section to be deserialized");
807
808 if let Section::Function(fn_section) = section {
809 assert_eq!(4, fn_section.entries().len(), "There should be 4 functions total");
810 }
811 }
812
813 #[test]
814 fn fn_section_ref() {
815 let section: Section =
816 deserialize_buffer(functions_test_payload()).expect("section to be deserialized");
817
818 if let Section::Function(fn_section) = section {
819 assert_eq!(6, fn_section.entries()[1].type_ref());
820 }
821 }
822
823 fn types_test_payload() -> &'static [u8] {
824 &[
825 11, 2, 0x60, 1, 0x7e, 0x00, 0x60, 2, 0x7e, 0x7d, 0x01, 0x7e,
838 ]
839 }
840
841 #[test]
842 fn type_section_len() {
843 let type_section: TypeSection =
844 deserialize_buffer(types_test_payload()).expect("type_section be deserialized");
845
846 assert_eq!(type_section.types().len(), 2);
847 }
848
849 #[test]
850 fn type_section_infer() {
851 let type_section: TypeSection =
852 deserialize_buffer(types_test_payload()).expect("type_section be deserialized");
853
854 let Type::Function(ref t1) = type_section.types()[1];
855 assert_eq!(vec![ValueType::I64], t1.results());
856 assert_eq!(2, t1.params().len());
857 }
858
859 fn export_payload() -> &'static [u8] {
860 &[
861 0x07, 28, 6,
865 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,
873 ]
874 }
875
876 #[test]
877 fn export_detect() {
878 let section: Section =
879 deserialize_buffer(export_payload()).expect("section to be deserialized");
880
881 match section {
882 Section::Export(_) => {},
883 _ => {
884 panic!("Payload should be recognized as export section")
885 },
886 }
887 }
888
889 fn code_payload() -> &'static [u8] {
890 &[
891 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,
911 ]
912 }
913
914 #[test]
915 fn code_detect() {
916 let section: Section =
917 deserialize_buffer(code_payload()).expect("section to be deserialized");
918
919 match section {
920 Section::Code(_) => {},
921 _ => {
922 panic!("Payload should be recognized as a code section")
923 },
924 }
925 }
926
927 fn data_payload() -> &'static [u8] {
928 &[
929 0x0bu8, 20, 0x01, 0x00, 0x0b, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
936 0x00, 0x00,
937 ]
938 }
939
940 #[test]
941 fn data_section_ser() {
942 let data_section = DataSection::with_entries(vec![DataSegment::new(
943 0u32,
944 Some(InitExpr::empty()),
945 vec![0u8; 16],
946 )]);
947
948 let buf = serialize(data_section).expect("Data section to be serialized");
949
950 assert_eq!(
951 buf,
952 vec![
953 20u8, 0x01, 0x00, 0x0b, 16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
960 ]
961 );
962 }
963
964 #[test]
965 fn data_section_detect() {
966 let section: Section =
967 deserialize_buffer(data_payload()).expect("section to be deserialized");
968
969 match section {
970 Section::Data(_) => {},
971 _ => {
972 panic!("Payload should be recognized as a data section")
973 },
974 }
975 }
976
977 #[test]
978 fn element_section_ser() {
979 let element_section = ElementSection::with_entries(vec![ElementSegment::new(
980 0u32,
981 Some(InitExpr::empty()),
982 vec![0u32; 4],
983 )]);
984
985 let buf = serialize(element_section).expect("Element section to be serialized");
986
987 assert_eq!(
988 buf,
989 vec![
990 8u8, 0x01, 0x00, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00 ]
997 );
998 }
999
1000 #[test]
1001 fn code_section_ser() {
1002 use super::super::Instruction::*;
1003
1004 let code_section = CodeSection::with_bodies(vec![FuncBody::new(
1005 vec![Local::new(1, ValueType::I32)],
1006 Instructions::new(vec![
1007 Block(BlockType::Value(ValueType::I32)),
1008 GetGlobal(0),
1009 End,
1010 End,
1011 ]),
1012 )]);
1013
1014 let buf = serialize(code_section).expect("Code section to be serialized");
1015
1016 assert_eq!(
1017 buf,
1018 vec![
1019 11u8, 0x01, 9, 1, 1, 0x7f, 0x02, 0x7f, 0x23, 0x00, 0x0b, 0x0b, ]
1031 );
1032 }
1033
1034 #[test]
1035 fn start_section() {
1036 let section: Section =
1037 deserialize_buffer(&[8u8, 1u8, 0u8]).expect("Start section to deserialize");
1038 if let Section::Start(_) = section {
1039 } else {
1040 panic!("Payload should be a start section");
1041 }
1042
1043 let serialized = serialize(section).expect("Start section to successfully serializen");
1044
1045 assert_eq!(serialized, vec![8u8, 1u8, 0u8]);
1046 }
1047}