1use alloc::{vec::Vec, borrow::ToOwned, string::String};
2use crate::{io, elements};
3use super::{
4 Serialize,
5 Deserialize,
6 Error,
7 VarUint7,
8 VarUint32,
9 CountedList,
10 ImportEntry,
11 MemoryType,
12 TableType,
13 ExportEntry,
14 GlobalEntry,
15 Func,
16 FuncBody,
17 ElementSegment,
18 DataSegment,
19 CountedWriter,
20 CountedListWriter,
21 External,
22 serialize,
23};
24
25use super::types::Type;
26use super::name_section::NameSection;
27use super::reloc_section::RelocSection;
28
29const ENTRIES_BUFFER_LENGTH: usize = 16384;
30
31#[derive(Debug, Clone, PartialEq)]
33pub enum Section {
34 Unparsed {
36 id: u8,
38 payload: Vec<u8>,
40 },
41 Custom(CustomSection),
43 Type(TypeSection),
45 Import(ImportSection),
47 Function(FunctionSection),
49 Table(TableSection),
51 Memory(MemorySection),
53 Global(GlobalSection),
55 Export(ExportSection),
57 Start(u32),
59 Element(ElementSection),
61 DataCount(u32),
63 Code(CodeSection),
65 Data(DataSection),
67 Name(NameSection),
71 Reloc(RelocSection),
77}
78
79impl Deserialize for Section {
80 type Error = Error;
81
82 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
83 let id = match VarUint7::deserialize(reader) {
84 Err(_) => { return Err(Error::UnexpectedEof); },
86 Ok(id) => id,
87 };
88
89 Ok(
90 match id.into() {
91 0 => {
92 Section::Custom(CustomSection::deserialize(reader)?.into())
93 },
94 1 => {
95 Section::Type(TypeSection::deserialize(reader)?)
96 },
97 2 => {
98 Section::Import(ImportSection::deserialize(reader)?)
99 },
100 3 => {
101 Section::Function(FunctionSection::deserialize(reader)?)
102 },
103 4 => {
104 Section::Table(TableSection::deserialize(reader)?)
105 },
106 5 => {
107 Section::Memory(MemorySection::deserialize(reader)?)
108 },
109 6 => {
110 Section::Global(GlobalSection::deserialize(reader)?)
111 },
112 7 => {
113 Section::Export(ExportSection::deserialize(reader)?)
114 },
115 8 => {
116 let mut section_reader = SectionReader::new(reader)?;
117 let start_idx = VarUint32::deserialize(&mut section_reader)?;
118 section_reader.close()?;
119 Section::Start(start_idx.into())
120 },
121 9 => {
122 Section::Element(ElementSection::deserialize(reader)?)
123 },
124 10 => {
125 Section::Code(CodeSection::deserialize(reader)?)
126 },
127 11 => {
128 Section::Data(DataSection::deserialize(reader)?)
129 },
130 12 => {
131 let mut section_reader = SectionReader::new(reader)?;
132 let count = VarUint32::deserialize(&mut section_reader)?;
133 section_reader.close()?;
134 Section::DataCount(count.into())
135 },
136 invalid_id => {
137 return Err(Error::InvalidSectionId(invalid_id))
138 },
139 }
140 )
141 }
142}
143
144impl Serialize for Section {
145 type Error = Error;
146
147 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
148 match self {
149 Section::Custom(custom_section) => {
150 VarUint7::from(0x00).serialize(writer)?;
151 custom_section.serialize(writer)?;
152 },
153 Section::Unparsed { id, payload } => {
154 VarUint7::from(id).serialize(writer)?;
155 writer.write(&payload[..])?;
156 },
157 Section::Type(type_section) => {
158 VarUint7::from(0x01).serialize(writer)?;
159 type_section.serialize(writer)?;
160 },
161 Section::Import(import_section) => {
162 VarUint7::from(0x02).serialize(writer)?;
163 import_section.serialize(writer)?;
164 },
165 Section::Function(function_section) => {
166 VarUint7::from(0x03).serialize(writer)?;
167 function_section.serialize(writer)?;
168 },
169 Section::Table(table_section) => {
170 VarUint7::from(0x04).serialize(writer)?;
171 table_section.serialize(writer)?;
172 },
173 Section::Memory(memory_section) => {
174 VarUint7::from(0x05).serialize(writer)?;
175 memory_section.serialize(writer)?;
176 },
177 Section::Global(global_section) => {
178 VarUint7::from(0x06).serialize(writer)?;
179 global_section.serialize(writer)?;
180 },
181 Section::Export(export_section) => {
182 VarUint7::from(0x07).serialize(writer)?;
183 export_section.serialize(writer)?;
184 },
185 Section::Start(index) => {
186 VarUint7::from(0x08).serialize(writer)?;
187 let mut counted_writer = CountedWriter::new(writer);
188 VarUint32::from(index).serialize(&mut counted_writer)?;
189 counted_writer.done()?;
190 },
191 Section::DataCount(count) => {
192 VarUint7::from(0x0c).serialize(writer)?;
193 let mut counted_writer = CountedWriter::new(writer);
194 VarUint32::from(count).serialize(&mut counted_writer)?;
195 counted_writer.done()?;
196 },
197 Section::Element(element_section) => {
198 VarUint7::from(0x09).serialize(writer)?;
199 element_section.serialize(writer)?;
200 },
201 Section::Code(code_section) => {
202 VarUint7::from(0x0a).serialize(writer)?;
203 code_section.serialize(writer)?;
204 },
205 Section::Data(data_section) => {
206 VarUint7::from(0x0b).serialize(writer)?;
207 data_section.serialize(writer)?;
208 },
209 Section::Name(name_section) => {
210 VarUint7::from(0x00).serialize(writer)?;
211 let custom = CustomSection {
212 name: "name".to_owned(),
213 payload: serialize(name_section)?,
214 };
215 custom.serialize(writer)?;
216 },
217 Section::Reloc(reloc_section) => {
218 VarUint7::from(0x00).serialize(writer)?;
219 reloc_section.serialize(writer)?;
220 },
221 }
222 Ok(())
223 }
224}
225
226impl Section {
227 pub(crate) fn order(&self) -> u8 {
228 match *self {
229 Section::Custom(_) => 0x00,
230 Section::Unparsed { .. } => 0x00,
231 Section::Type(_) => 0x1,
232 Section::Import(_) => 0x2,
233 Section::Function(_) => 0x3,
234 Section::Table(_) => 0x4,
235 Section::Memory(_) => 0x5,
236 Section::Global(_) => 0x6,
237 Section::Export(_) => 0x7,
238 Section::Start(_) => 0x8,
239 Section::Element(_) => 0x9,
240 Section::DataCount(_) => 0x0a,
241 Section::Code(_) => 0x0b,
242 Section::Data(_) => 0x0c,
243 Section::Name(_) => 0x00,
244 Section::Reloc(_) => 0x00,
245 }
246 }
247}
248
249pub(crate) struct SectionReader {
250 cursor: io::Cursor<Vec<u8>>,
251 declared_length: usize,
252}
253
254impl SectionReader {
255 pub fn new<R: io::Read>(reader: &mut R) -> Result<Self, elements::Error> {
256 let length = u32::from(VarUint32::deserialize(reader)?) as usize;
257 let inner_buffer = buffered_read!(ENTRIES_BUFFER_LENGTH, length, reader);
258 let buf_length = inner_buffer.len();
259 let cursor = io::Cursor::new(inner_buffer);
260
261 Ok(SectionReader {
262 cursor: cursor,
263 declared_length: buf_length,
264 })
265 }
266
267 pub fn close(self) -> Result<(), io::Error> {
268 let cursor = self.cursor;
269 let buf_length = self.declared_length;
270
271 if cursor.position() != buf_length {
272 Err(io::Error::InvalidData)
273 } else {
274 Ok(())
275 }
276 }
277}
278
279impl io::Read for SectionReader {
280 fn read(&mut self, buf: &mut [u8]) -> io::Result<()> {
281 self.cursor.read(buf)?;
282 Ok(())
283 }
284}
285
286fn read_entries<R: io::Read, T: Deserialize<Error=elements::Error>>(reader: &mut R)
287 -> Result<Vec<T>, elements::Error>
288{
289 let mut section_reader = SectionReader::new(reader)?;
290 let result = CountedList::<T>::deserialize(&mut section_reader)?.into_inner();
291 section_reader.close()?;
292 Ok(result)
293}
294
295#[derive(Debug, Default, Clone, PartialEq)]
297pub struct CustomSection {
298 name: String,
299 payload: Vec<u8>,
300}
301
302impl CustomSection {
303 pub fn new(name: String, payload: Vec<u8>) -> CustomSection {
305 CustomSection { name, payload }
306 }
307
308 pub fn name(&self) -> &str {
310 &self.name
311 }
312
313 pub fn payload(&self) -> &[u8] {
315 &self.payload
316 }
317
318 pub fn name_mut(&mut self) -> &mut String {
320 &mut self.name
321 }
322
323 pub fn payload_mut(&mut self) -> &mut Vec<u8> {
325 &mut self.payload
326 }
327}
328
329impl Deserialize for CustomSection {
330 type Error = Error;
331
332 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
333 let section_length: usize = u32::from(VarUint32::deserialize(reader)?) as usize;
334 let buf = buffered_read!(16384, section_length, reader);
335 let mut cursor = io::Cursor::new(&buf[..]);
336 let name = String::deserialize(&mut cursor)?;
337 let payload = buf[cursor.position() as usize..].to_vec();
338 Ok(CustomSection { name: name, payload: payload })
339 }
340}
341
342impl Serialize for CustomSection {
343 type Error = Error;
344
345 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
346 use io::Write;
347
348 let mut counted_writer = CountedWriter::new(writer);
349 self.name.serialize(&mut counted_writer)?;
350 counted_writer.write(&self.payload[..])?;
351 counted_writer.done()?;
352 Ok(())
353 }
354}
355
356#[derive(Debug, Default, Clone, PartialEq)]
358pub struct TypeSection(Vec<Type>);
359
360impl TypeSection {
361 pub fn with_types(types: Vec<Type>) -> Self {
363 TypeSection(types)
364 }
365
366 pub fn types(&self) -> &[Type] {
368 &self.0
369 }
370
371 pub fn types_mut(&mut self) -> &mut Vec<Type> {
373 &mut self.0
374 }
375}
376
377impl Deserialize for TypeSection {
378 type Error = Error;
379
380 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
381 Ok(TypeSection(read_entries(reader)?))
382 }
383}
384
385impl Serialize for TypeSection {
386 type Error = Error;
387
388 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
389 let mut counted_writer = CountedWriter::new(writer);
390 let data = self.0;
391 let counted_list = CountedListWriter::<Type, _>(
392 data.len(),
393 data.into_iter().map(Into::into),
394 );
395 counted_list.serialize(&mut counted_writer)?;
396 counted_writer.done()?;
397 Ok(())
398 }
399}
400
401#[derive(Debug, Default, Clone, PartialEq)]
403pub struct ImportSection(Vec<ImportEntry>);
404
405impl ImportSection {
406 pub fn with_entries(entries: Vec<ImportEntry>) -> Self {
408 ImportSection(entries)
409 }
410
411 pub fn entries(&self) -> &[ImportEntry] {
413 &self.0
414 }
415
416 pub fn entries_mut(&mut self) -> &mut Vec<ImportEntry> {
418 &mut self.0
419 }
420
421 pub fn functions(&self) -> usize {
423 self.0.iter()
424 .filter(|entry| match entry.external() { &External::Function(_) => true, _ => false })
425 .count()
426 }
427
428 pub fn globals(&self) -> usize {
430 self.0.iter()
431 .filter(|entry| match entry.external() { &External::Global(_) => true, _ => false })
432 .count()
433 }
434}
435
436impl Deserialize for ImportSection {
437 type Error = Error;
438
439 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
440 Ok(ImportSection(read_entries(reader)?))
441 }
442}
443
444impl Serialize for ImportSection {
445 type Error = Error;
446
447 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
448 let mut counted_writer = CountedWriter::new(writer);
449 let data = self.0;
450 let counted_list = CountedListWriter::<ImportEntry, _>(
451 data.len(),
452 data.into_iter().map(Into::into),
453 );
454 counted_list.serialize(&mut counted_writer)?;
455 counted_writer.done()?;
456 Ok(())
457 }
458}
459
460#[derive(Default, Debug, Clone, PartialEq)]
462pub struct FunctionSection(Vec<Func>);
463
464impl FunctionSection {
465 pub fn with_entries(entries: Vec<Func>) -> Self {
467 FunctionSection(entries)
468 }
469
470 pub fn entries_mut(&mut self) -> &mut Vec<Func> {
472 &mut self.0
473 }
474
475 pub fn entries(&self) -> &[Func] {
477 &self.0
478 }
479}
480
481impl Deserialize for FunctionSection {
482 type Error = Error;
483
484 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
485 Ok(FunctionSection(read_entries(reader)?))
486 }
487}
488
489impl Serialize for FunctionSection {
490 type Error = Error;
491
492 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
493 let mut counted_writer = CountedWriter::new(writer);
494 let data = self.0;
495 let counted_list = CountedListWriter::<VarUint32, _>(
496 data.len(),
497 data.into_iter().map(|func| func.type_ref().into())
498 );
499 counted_list.serialize(&mut counted_writer)?;
500 counted_writer.done()?;
501 Ok(())
502 }
503}
504
505#[derive(Default, Debug, Clone, PartialEq)]
507pub struct TableSection(Vec<TableType>);
508
509impl TableSection {
510 pub fn entries(&self) -> &[TableType] {
512 &self.0
513 }
514
515 pub fn with_entries(entries: Vec<TableType>) -> Self {
517 TableSection(entries)
518 }
519
520 pub fn entries_mut(&mut self) -> &mut Vec<TableType> {
522 &mut self.0
523 }
524}
525
526impl Deserialize for TableSection {
527 type Error = Error;
528
529 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
530 Ok(TableSection(read_entries(reader)?))
531 }
532}
533
534impl Serialize for TableSection {
535 type Error = Error;
536
537 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
538 let mut counted_writer = CountedWriter::new(writer);
539 let data = self.0;
540 let counted_list = CountedListWriter::<TableType, _>(
541 data.len(),
542 data.into_iter().map(Into::into),
543 );
544 counted_list.serialize(&mut counted_writer)?;
545 counted_writer.done()?;
546 Ok(())
547 }
548}
549
550#[derive(Default, Debug, Clone, PartialEq)]
552pub struct MemorySection(Vec<MemoryType>);
553
554impl MemorySection {
555 pub fn entries(&self) -> &[MemoryType] {
557 &self.0
558 }
559
560 pub fn with_entries(entries: Vec<MemoryType>) -> Self {
562 MemorySection(entries)
563 }
564
565 pub fn entries_mut(&mut self) -> &mut Vec<MemoryType> {
567 &mut self.0
568 }
569}
570
571impl Deserialize for MemorySection {
572 type Error = Error;
573
574 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
575 Ok(MemorySection(read_entries(reader)?))
576 }
577}
578
579impl Serialize for MemorySection {
580 type Error = Error;
581
582 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
583 let mut counted_writer = CountedWriter::new(writer);
584 let data = self.0;
585 let counted_list = CountedListWriter::<MemoryType, _>(
586 data.len(),
587 data.into_iter().map(Into::into),
588 );
589 counted_list.serialize(&mut counted_writer)?;
590 counted_writer.done()?;
591 Ok(())
592 }
593}
594
595#[derive(Default, Debug, Clone, PartialEq)]
597pub struct GlobalSection(Vec<GlobalEntry>);
598
599impl GlobalSection {
600 pub fn entries(&self) -> &[GlobalEntry] {
602 &self.0
603 }
604
605 pub fn with_entries(entries: Vec<GlobalEntry>) -> Self {
607 GlobalSection(entries)
608 }
609
610 pub fn entries_mut(&mut self) -> &mut Vec<GlobalEntry> {
612 &mut self.0
613 }
614}
615
616impl Deserialize for GlobalSection {
617 type Error = Error;
618
619 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
620 Ok(GlobalSection(read_entries(reader)?))
621 }
622}
623
624impl Serialize for GlobalSection {
625 type Error = Error;
626
627 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
628 let mut counted_writer = CountedWriter::new(writer);
629 let data = self.0;
630 let counted_list = CountedListWriter::<GlobalEntry, _>(
631 data.len(),
632 data.into_iter().map(Into::into),
633 );
634 counted_list.serialize(&mut counted_writer)?;
635 counted_writer.done()?;
636 Ok(())
637 }
638}
639
640#[derive(Debug, Default, Clone, PartialEq)]
642pub struct ExportSection(Vec<ExportEntry>);
643
644impl ExportSection {
645 pub fn entries(&self) -> &[ExportEntry] {
647 &self.0
648 }
649
650 pub fn with_entries(entries: Vec<ExportEntry>) -> Self {
652 ExportSection(entries)
653 }
654
655 pub fn entries_mut(&mut self) -> &mut Vec<ExportEntry> {
657 &mut self.0
658 }
659}
660
661impl Deserialize for ExportSection {
662 type Error = Error;
663
664 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
665 Ok(ExportSection(read_entries(reader)?))
666 }
667}
668
669impl Serialize for ExportSection {
670 type Error = Error;
671
672 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
673 let mut counted_writer = CountedWriter::new(writer);
674 let data = self.0;
675 let counted_list = CountedListWriter::<ExportEntry, _>(
676 data.len(),
677 data.into_iter().map(Into::into),
678 );
679 counted_list.serialize(&mut counted_writer)?;
680 counted_writer.done()?;
681 Ok(())
682 }
683}
684
685#[derive(Default, Debug, Clone, PartialEq)]
687pub struct CodeSection(Vec<FuncBody>);
688
689impl CodeSection {
690 pub fn with_bodies(bodies: Vec<FuncBody>) -> Self {
692 CodeSection(bodies)
693 }
694
695 pub fn bodies(&self) -> &[FuncBody] {
697 &self.0
698 }
699
700 pub fn bodies_mut(&mut self) -> &mut Vec<FuncBody> {
702 &mut self.0
703 }
704}
705
706impl Deserialize for CodeSection {
707 type Error = Error;
708
709 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
710 Ok(CodeSection(read_entries(reader)?))
711 }
712}
713
714impl Serialize for CodeSection {
715 type Error = Error;
716
717 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
718 let mut counted_writer = CountedWriter::new(writer);
719 let data = self.0;
720 let counted_list = CountedListWriter::<FuncBody, _>(
721 data.len(),
722 data.into_iter().map(Into::into),
723 );
724 counted_list.serialize(&mut counted_writer)?;
725 counted_writer.done()?;
726 Ok(())
727 }
728}
729
730#[derive(Default, Debug, Clone, PartialEq)]
732pub struct ElementSection(Vec<ElementSegment>);
733
734impl ElementSection {
735 pub fn with_entries(entries: Vec<ElementSegment>) -> Self {
737 ElementSection(entries)
738 }
739
740 pub fn entries(&self) -> &[ElementSegment] {
742 &self.0
743 }
744
745 pub fn entries_mut(&mut self) -> &mut Vec<ElementSegment> {
747 &mut self.0
748 }
749}
750
751impl Deserialize for ElementSection {
752 type Error = Error;
753
754 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
755 Ok(ElementSection(read_entries(reader)?))
756 }
757}
758
759impl Serialize for ElementSection {
760 type Error = Error;
761
762 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
763 let mut counted_writer = CountedWriter::new(writer);
764 let data = self.0;
765 let counted_list = CountedListWriter::<ElementSegment, _>(
766 data.len(),
767 data.into_iter().map(Into::into),
768 );
769 counted_list.serialize(&mut counted_writer)?;
770 counted_writer.done()?;
771 Ok(())
772 }
773}
774
775#[derive(Default, Debug, Clone, PartialEq)]
777pub struct DataSection(Vec<DataSegment>);
778
779impl DataSection {
780 pub fn with_entries(entries: Vec<DataSegment>) -> Self {
782 DataSection(entries)
783 }
784
785 pub fn entries(&self) -> &[DataSegment] {
787 &self.0
788 }
789
790 pub fn entries_mut(&mut self) -> &mut Vec<DataSegment> {
792 &mut self.0
793 }
794}
795
796impl Deserialize for DataSection {
797 type Error = Error;
798
799 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
800 Ok(DataSection(read_entries(reader)?))
801 }
802}
803
804impl Serialize for DataSection {
805 type Error = Error;
806
807 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
808 let mut counted_writer = CountedWriter::new(writer);
809 let data = self.0;
810 let counted_list = CountedListWriter::<DataSegment, _>(
811 data.len(),
812 data.into_iter().map(Into::into),
813 );
814 counted_list.serialize(&mut counted_writer)?;
815 counted_writer.done()?;
816 Ok(())
817 }
818}
819
820#[cfg(test)]
821mod tests {
822
823 use super::super::{
824 deserialize_buffer, deserialize_file, ValueType, InitExpr, DataSegment,
825 serialize, ElementSegment, Instructions, BlockType, Local, FuncBody,
826 };
827 use super::{Section, TypeSection, Type, DataSection, ElementSection, CodeSection};
828
829 #[test]
830 fn import_section() {
831 let module = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized");
832 let mut found = false;
833 for section in module.sections() {
834 match section {
835 &Section::Import(ref import_section) => {
836 assert_eq!(25, import_section.entries().len());
837 found = true
838 },
839 _ => { }
840 }
841 }
842 assert!(found, "There should be import section in test5.wasm");
843 }
844
845 fn functions_test_payload() -> &'static [u8] {
846 &[
847 0x03u8,
849 0x87, 0x80, 0x80, 0x80, 0x0,
851 0x04,
853 0x01,
855 0x86, 0x80, 0x00,
857 0x09,
859 0x33
861 ]
862 }
863
864 #[test]
865 fn fn_section_detect() {
866 let section: Section =
867 deserialize_buffer(functions_test_payload()).expect("section to be deserialized");
868
869 match section {
870 Section::Function(_) => {},
871 _ => {
872 panic!("Payload should be recognized as functions section")
873 }
874 }
875 }
876
877 #[test]
878 fn fn_section_number() {
879 let section: Section =
880 deserialize_buffer(functions_test_payload()).expect("section to be deserialized");
881
882 match section {
883 Section::Function(fn_section) => {
884 assert_eq!(4, fn_section.entries().len(), "There should be 4 functions total");
885 },
886 _ => {
887 }
889 }
890 }
891
892 #[test]
893 fn fn_section_ref() {
894 let section: Section =
895 deserialize_buffer(functions_test_payload()).expect("section to be deserialized");
896
897 match section {
898 Section::Function(fn_section) => {
899 assert_eq!(6, fn_section.entries()[1].type_ref());
900 },
901 _ => {
902 }
904 }
905 }
906
907 fn types_test_payload() -> &'static [u8] {
908 &[
909 11,
911
912 2,
914 0x60,
916 1,
918 0x7e, 0x00,
922
923 0x60,
925 2,
927 0x7e,
929 0x7d,
931 0x01, 0x7e
933 ]
934 }
935
936 #[test]
937 fn type_section_len() {
938 let type_section: TypeSection =
939 deserialize_buffer(types_test_payload()).expect("type_section be deserialized");
940
941 assert_eq!(type_section.types().len(), 2);
942 }
943
944 #[test]
945 fn type_section_infer() {
946 let type_section: TypeSection =
947 deserialize_buffer(types_test_payload()).expect("type_section be deserialized");
948
949 let t1 = match &type_section.types()[1] {
950 &Type::Function(ref func_type) => func_type
951 };
952
953 assert_eq!(vec![ValueType::I64], t1.results());
954 assert_eq!(2, t1.params().len());
955 }
956
957 fn export_payload() -> &'static [u8] {
958 &[
959 0x07,
961 28,
963 6,
965 0x01, 0x41, 0x01, 0x86, 0x80, 0x00,
968 0x01, 0x42, 0x01, 0x86, 0x00,
970 0x01, 0x43, 0x01, 0x07,
972 0x01, 0x44, 0x02, 0x00,
974 0x01, 0x45, 0x01, 0x01,
976 0x01, 0x46, 0x01, 0x02
978 ]
979 }
980
981
982 #[test]
983 fn export_detect() {
984 let section: Section =
985 deserialize_buffer(export_payload()).expect("section to be deserialized");
986
987 match section {
988 Section::Export(_) => {},
989 _ => {
990 panic!("Payload should be recognized as export section")
991 }
992 }
993 }
994
995 fn code_payload() -> &'static [u8] {
996 &[
997 0x0Au8,
999 0x20,
1001 0x01,
1003 0x1E,
1005 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,
1021 0x0B,
1022 ]
1023 }
1024
1025 #[test]
1026 fn code_detect() {
1027
1028 let section: Section =
1029 deserialize_buffer(code_payload()).expect("section to be deserialized");
1030
1031 match section {
1032 Section::Code(_) => {},
1033 _ => {
1034 panic!("Payload should be recognized as a code section")
1035 }
1036 }
1037 }
1038
1039 fn data_payload() -> &'static [u8] {
1040 &[
1041 0x0bu8, 20, 0x01, 0x00, 0x0b, 0x10,
1047 0x00, 0x00, 0x00, 0x00,
1049 0x00, 0x00, 0x00, 0x00,
1050 0x00, 0x00, 0x00, 0x00,
1051 0x00, 0x00, 0x00, 0x00
1052 ]
1053 }
1054
1055 #[test]
1056 fn data_section_ser() {
1057 let data_section = DataSection::with_entries(
1058 vec![DataSegment::new(0u32, Some(InitExpr::empty()), vec![0u8; 16])]
1059 );
1060
1061 let buf = serialize(data_section).expect("Data section to be serialized");
1062
1063 assert_eq!(buf, vec![
1064 20u8, 0x01, 0x00, 0x0b, 16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1071 0x00, 0x00, 0x00, 0x00,
1072 0x00, 0x00, 0x00, 0x00
1073 ]);
1074 }
1075
1076 #[test]
1077 fn data_section_detect() {
1078 let section: Section =
1079 deserialize_buffer(data_payload()).expect("section to be deserialized");
1080
1081 match section {
1082 Section::Data(_) => {},
1083 _ => {
1084 panic!("Payload should be recognized as a data section")
1085 }
1086 }
1087 }
1088
1089 #[test]
1090 fn element_section_ser() {
1091 let element_section = ElementSection::with_entries(
1092 vec![ElementSegment::new(0u32, Some(InitExpr::empty()), vec![0u32; 4])]
1093 );
1094
1095 let buf = serialize(element_section).expect("Element section to be serialized");
1096
1097 assert_eq!(buf, vec![
1098 08u8, 0x01, 0x00, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00 ]);
1105 }
1106
1107 #[test]
1108 fn code_section_ser() {
1109 use super::super::Instruction::*;
1110
1111 let code_section = CodeSection::with_bodies(
1112 vec![
1113 FuncBody::new(
1114 vec![Local::new(1, ValueType::I32)],
1115 Instructions::new(vec![
1116 Block(BlockType::Value(ValueType::I32)),
1117 GetGlobal(0),
1118 End,
1119 End,
1120 ])
1121 )
1122 ]);
1123
1124 let buf = serialize(code_section).expect("Code section to be serialized");
1125
1126 assert_eq!(buf, vec![
1127 11u8, 0x01, 9, 1, 1, 0x7f, 0x02, 0x7f, 0x23, 0x00, 0x0b, 0x0b, ]);
1139 }
1140
1141 #[test]
1142 fn start_section() {
1143 let section: Section = deserialize_buffer(&[08u8, 01u8, 00u8]).expect("Start section to deserialize");
1144 if let Section::Start(_) = section {
1145 } else {
1146 panic!("Payload should be a start section");
1147 }
1148
1149 let serialized = serialize(section).expect("Start section to successfully serializen");
1150
1151 assert_eq!(serialized, vec![08u8, 01u8, 00u8]);
1152 }
1153}