1use std::io;
2use super::{
3 Serialize,
4 Deserialize,
5 Unparsed,
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};
23
24use super::types::Type;
25
26#[derive(Clone)]
28pub enum Section {
29 Unparsed {
31 id: u8,
33 payload: Vec<u8>,
35 },
36 Custom(CustomSection),
38 Type(TypeSection),
40 Import(ImportSection),
42 Function(FunctionSection),
44 Table(TableSection),
46 Memory(MemorySection),
48 Global(GlobalSection),
50 Export(ExportSection),
52 Start(u32),
54 Element(ElementSection),
56 Code(CodeSection),
58 Data(DataSection),
60}
61
62impl Deserialize for Section {
63 type Error = Error;
64
65 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
66 let id = match VarUint7::deserialize(reader) {
67 Err(_) => { return Err(Error::UnexpectedEof); },
69 Ok(id) => id,
70 };
71
72 Ok(
73 match id.into() {
74 0 => {
75 Section::Custom(CustomSection::deserialize(reader)?.into())
76 },
77 1 => {
78 Section::Type(TypeSection::deserialize(reader)?)
79 },
80 2 => {
81 Section::Import(ImportSection::deserialize(reader)?)
82 },
83 3 => {
84 Section::Function(FunctionSection::deserialize(reader)?)
85 },
86 4 => {
87 Section::Table(TableSection::deserialize(reader)?)
88 },
89 5 => {
90 Section::Memory(MemorySection::deserialize(reader)?)
91 },
92 6 => {
93 Section::Global(GlobalSection::deserialize(reader)?)
94 },
95 7 => {
96 Section::Export(ExportSection::deserialize(reader)?)
97 },
98 8 => {
99 let _section_length = VarUint32::deserialize(reader)?;
100 Section::Start(VarUint32::deserialize(reader)?.into())
101 },
102 9 => {
103 Section::Element(ElementSection::deserialize(reader)?)
104 },
105 10 => {
106 Section::Code(CodeSection::deserialize(reader)?)
107 },
108 11 => {
109 Section::Data(DataSection::deserialize(reader)?)
110 },
111 _ => {
112 Section::Unparsed { id: id.into(), payload: Unparsed::deserialize(reader)?.into() }
113 }
114 }
115 )
116 }
117}
118
119impl Serialize for Section {
120 type Error = Error;
121
122 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
123 match self {
124 Section::Custom(custom_section) => {
125 VarUint7::from(0x00).serialize(writer)?;
126 custom_section.serialize(writer)?;
127 },
128 Section::Unparsed { id, payload } => {
129 VarUint7::from(id).serialize(writer)?;
130 writer.write_all(&payload[..])?;
131 },
132 Section::Type(type_section) => {
133 VarUint7::from(0x01).serialize(writer)?;
134 type_section.serialize(writer)?;
135 },
136 Section::Import(import_section) => {
137 VarUint7::from(0x02).serialize(writer)?;
138 import_section.serialize(writer)?;
139 },
140 Section::Function(function_section) => {
141 VarUint7::from(0x03).serialize(writer)?;
142 function_section.serialize(writer)?;
143 },
144 Section::Table(table_section) => {
145 VarUint7::from(0x04).serialize(writer)?;
146 table_section.serialize(writer)?;
147 },
148 Section::Memory(memory_section) => {
149 VarUint7::from(0x05).serialize(writer)?;
150 memory_section.serialize(writer)?;
151 },
152 Section::Global(global_section) => {
153 VarUint7::from(0x06).serialize(writer)?;
154 global_section.serialize(writer)?;
155 },
156 Section::Export(export_section) => {
157 VarUint7::from(0x07).serialize(writer)?;
158 export_section.serialize(writer)?;
159 },
160 Section::Start(index) => {
161 VarUint7::from(0x08).serialize(writer)?;
162 let mut counted_writer = CountedWriter::new(writer);
163 VarUint32::from(index).serialize(&mut counted_writer)?;
164 counted_writer.done()?;
165 },
166 Section::Element(element_section) => {
167 VarUint7::from(0x09).serialize(writer)?;
168 element_section.serialize(writer)?;
169 },
170 Section::Code(code_section) => {
171 VarUint7::from(0x0a).serialize(writer)?;
172 code_section.serialize(writer)?;
173 },
174 Section::Data(data_section) => {
175 VarUint7::from(0x0b).serialize(writer)?;
176 data_section.serialize(writer)?;
177 },
178 }
179 Ok(())
180 }
181}
182
183#[derive(Clone)]
185pub struct CustomSection {
186 name: String,
187 payload: Vec<u8>,
188}
189
190impl CustomSection {
191
192 pub fn name(&self) -> &str {
194 &self.name
195 }
196
197 pub fn payload(&self) -> &[u8] {
199 &self.payload
200 }
201
202 pub fn name_mut(&mut self) -> &mut String {
204 &mut self.name
205 }
206
207 pub fn payload_mut(&mut self) -> &mut Vec<u8> {
209 &mut self.payload
210 }
211}
212
213impl Deserialize for CustomSection {
214 type Error = Error;
215
216 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
217 let section_length: u32 = VarUint32::deserialize(reader)?.into();
219
220 let name = String::deserialize(reader)?;
221 let payload_left = section_length - (name.len() as u32 + name.len() as u32 / 128 + 1);
222 let mut payload = vec![0u8; payload_left as usize];
223 reader.read_exact(&mut payload[..])?;
224
225 Ok(CustomSection { name: name, payload: payload })
226 }
227}
228
229impl Serialize for CustomSection {
230 type Error = Error;
231
232 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
233 use std::io::Write;
234
235 let mut counted_writer = CountedWriter::new(writer);
236 self.name.serialize(&mut counted_writer)?;
237 counted_writer.write_all(&self.payload[..])?;
238 counted_writer.done()?;
239 Ok(())
240 }
241}
242
243#[derive(Default, Clone)]
245pub struct TypeSection(Vec<Type>);
246
247impl TypeSection {
248 pub fn with_types(types: Vec<Type>) -> Self {
250 TypeSection(types)
251 }
252
253 pub fn types(&self) -> &[Type] {
255 &self.0
256 }
257
258 pub fn types_mut(&mut self) -> &mut Vec<Type> {
260 &mut self.0
261 }
262}
263
264impl Deserialize for TypeSection {
265 type Error = Error;
266
267 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
268 let _section_length = VarUint32::deserialize(reader)?;
270 let types: Vec<Type> = CountedList::deserialize(reader)?.into_inner();
271 Ok(TypeSection(types))
272 }
273}
274
275impl Serialize for TypeSection {
276 type Error = Error;
277
278 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
279 let mut counted_writer = CountedWriter::new(writer);
280 let data = self.0;
281 let counted_list = CountedListWriter::<Type, _>(
282 data.len(),
283 data.into_iter().map(Into::into),
284 );
285 counted_list.serialize(&mut counted_writer)?;
286 counted_writer.done()?;
287 Ok(())
288 }
289}
290
291#[derive(Debug, Default, Clone)]
293pub struct ImportSection(Vec<ImportEntry>);
294
295impl ImportSection {
296 pub fn with_entries(entries: Vec<ImportEntry>) -> Self {
298 ImportSection(entries)
299 }
300
301 pub fn entries(&self) -> &[ImportEntry] {
303 &self.0
304 }
305
306 pub fn entries_mut(&mut self) -> &mut Vec<ImportEntry> {
308 &mut self.0
309 }
310
311 pub fn functions(&self) -> usize {
313 self.0.iter()
314 .filter(|entry| match entry.external() { &External::Function(_) => true, _ => false })
315 .count()
316 }
317
318 pub fn globals(&self) -> usize {
320 self.0.iter()
321 .filter(|entry| match entry.external() { &External::Global(_) => true, _ => false })
322 .count()
323 }
324}
325
326impl Deserialize for ImportSection {
327 type Error = Error;
328
329 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
330 let _section_length = VarUint32::deserialize(reader)?;
332 let entries: Vec<ImportEntry> = CountedList::deserialize(reader)?.into_inner();
333 Ok(ImportSection(entries))
334 }
335}
336
337impl Serialize for ImportSection {
338 type Error = Error;
339
340 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
341 let mut counted_writer = CountedWriter::new(writer);
342 let data = self.0;
343 let counted_list = CountedListWriter::<ImportEntry, _>(
344 data.len(),
345 data.into_iter().map(Into::into),
346 );
347 counted_list.serialize(&mut counted_writer)?;
348 counted_writer.done()?;
349 Ok(())
350 }
351}
352
353#[derive(Default, Clone)]
355pub struct FunctionSection(Vec<Func>);
356
357impl FunctionSection {
358 pub fn with_entries(entries: Vec<Func>) -> Self {
360 FunctionSection(entries)
361 }
362
363 pub fn entries_mut(&mut self) -> &mut Vec<Func> {
365 &mut self.0
366 }
367
368 pub fn entries(&self) -> &[Func] {
370 &self.0
371 }
372}
373
374impl Deserialize for FunctionSection {
375 type Error = Error;
376
377 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
378 let _section_length = VarUint32::deserialize(reader)?;
380 let funcs: Vec<Func> = CountedList::<VarUint32>::deserialize(reader)?
381 .into_inner()
382 .into_iter()
383 .map(|f| Func::new(f.into()))
384 .collect();
385 Ok(FunctionSection(funcs))
386 }
387}
388
389impl Serialize for FunctionSection {
390 type Error = Error;
391
392 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
393 let mut counted_writer = CountedWriter::new(writer);
394 let data = self.0;
395 let counted_list = CountedListWriter::<VarUint32, _>(
396 data.len(),
397 data.into_iter().map(|func| func.type_ref().into())
398 );
399 counted_list.serialize(&mut counted_writer)?;
400 counted_writer.done()?;
401 Ok(())
402 }
403}
404
405#[derive(Default, Clone)]
407pub struct TableSection(Vec<TableType>);
408
409impl TableSection {
410 pub fn entries(&self) -> &[TableType] {
412 &self.0
413 }
414
415 pub fn with_entries(entries: Vec<TableType>) -> Self {
417 TableSection(entries)
418 }
419
420 pub fn entries_mut(&mut self) -> &mut Vec<TableType> {
422 &mut self.0
423 }
424}
425
426impl Deserialize for TableSection {
427 type Error = Error;
428
429 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
430 let _section_length = VarUint32::deserialize(reader)?;
432 let entries: Vec<TableType> = CountedList::deserialize(reader)?.into_inner();
433 Ok(TableSection(entries))
434 }
435}
436
437impl Serialize for TableSection {
438 type Error = Error;
439
440 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
441 let mut counted_writer = CountedWriter::new(writer);
442 let data = self.0;
443 let counted_list = CountedListWriter::<TableType, _>(
444 data.len(),
445 data.into_iter().map(Into::into),
446 );
447 counted_list.serialize(&mut counted_writer)?;
448 counted_writer.done()?;
449 Ok(())
450 }
451}
452
453#[derive(Default, Clone)]
455pub struct MemorySection(Vec<MemoryType>);
456
457impl MemorySection {
458 pub fn entries(&self) -> &[MemoryType] {
460 &self.0
461 }
462
463 pub fn with_entries(entries: Vec<MemoryType>) -> Self {
465 MemorySection(entries)
466 }
467
468 pub fn entries_mut(&mut self) -> &mut Vec<MemoryType> {
470 &mut self.0
471 }
472}
473
474impl Deserialize for MemorySection {
475 type Error = Error;
476
477 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
478 let _section_length = VarUint32::deserialize(reader)?;
480 let entries: Vec<MemoryType> = CountedList::deserialize(reader)?.into_inner();
481 Ok(MemorySection(entries))
482 }
483}
484
485impl Serialize for MemorySection {
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::<MemoryType, _>(
492 data.len(),
493 data.into_iter().map(Into::into),
494 );
495 counted_list.serialize(&mut counted_writer)?;
496 counted_writer.done()?;
497 Ok(())
498 }
499}
500
501#[derive(Default, Clone)]
503pub struct GlobalSection(Vec<GlobalEntry>);
504
505impl GlobalSection {
506 pub fn entries(&self) -> &[GlobalEntry] {
508 &self.0
509 }
510
511 pub fn with_entries(entries: Vec<GlobalEntry>) -> Self {
513 GlobalSection(entries)
514 }
515
516 pub fn entries_mut(&mut self) -> &mut Vec<GlobalEntry> {
518 &mut self.0
519 }
520}
521
522impl Deserialize for GlobalSection {
523 type Error = Error;
524
525 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
526 let _section_length = VarUint32::deserialize(reader)?;
528 let entries: Vec<GlobalEntry> = CountedList::deserialize(reader)?.into_inner();
529 Ok(GlobalSection(entries))
530 }
531}
532
533impl Serialize for GlobalSection {
534 type Error = Error;
535
536 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
537 let mut counted_writer = CountedWriter::new(writer);
538 let data = self.0;
539 let counted_list = CountedListWriter::<GlobalEntry, _>(
540 data.len(),
541 data.into_iter().map(Into::into),
542 );
543 counted_list.serialize(&mut counted_writer)?;
544 counted_writer.done()?;
545 Ok(())
546 }
547}
548
549#[derive(Debug, Default, Clone)]
551pub struct ExportSection(Vec<ExportEntry>);
552
553impl ExportSection {
554 pub fn entries(&self) -> &[ExportEntry] {
556 &self.0
557 }
558
559 pub fn with_entries(entries: Vec<ExportEntry>) -> Self {
561 ExportSection(entries)
562 }
563
564 pub fn entries_mut(&mut self) -> &mut Vec<ExportEntry> {
566 &mut self.0
567 }
568}
569
570impl Deserialize for ExportSection {
571 type Error = Error;
572
573 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
574 let _section_length = VarUint32::deserialize(reader)?;
576 let entries: Vec<ExportEntry> = CountedList::deserialize(reader)?.into_inner();
577 Ok(ExportSection(entries))
578 }
579}
580
581impl Serialize for ExportSection {
582 type Error = Error;
583
584 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
585 let mut counted_writer = CountedWriter::new(writer);
586 let data = self.0;
587 let counted_list = CountedListWriter::<ExportEntry, _>(
588 data.len(),
589 data.into_iter().map(Into::into),
590 );
591 counted_list.serialize(&mut counted_writer)?;
592 counted_writer.done()?;
593 Ok(())
594 }
595}
596
597#[derive(Default, Clone)]
599pub struct CodeSection(Vec<FuncBody>);
600
601impl CodeSection {
602 pub fn with_bodies(bodies: Vec<FuncBody>) -> Self {
604 CodeSection(bodies)
605 }
606
607 pub fn bodies(&self) -> &[FuncBody] {
609 &self.0
610 }
611
612 pub fn bodies_mut(&mut self) -> &mut Vec<FuncBody> {
614 &mut self.0
615 }
616}
617
618impl Deserialize for CodeSection {
619 type Error = Error;
620
621 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
622 let _section_length = VarUint32::deserialize(reader)?;
624 let entries: Vec<FuncBody> = CountedList::deserialize(reader)?.into_inner();
625 Ok(CodeSection(entries))
626 }
627}
628
629impl Serialize for CodeSection {
630 type Error = Error;
631
632 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
633 let mut counted_writer = CountedWriter::new(writer);
634 let data = self.0;
635 let counted_list = CountedListWriter::<FuncBody, _>(
636 data.len(),
637 data.into_iter().map(Into::into),
638 );
639 counted_list.serialize(&mut counted_writer)?;
640 counted_writer.done()?;
641 Ok(())
642 }
643}
644
645#[derive(Default, Clone)]
647pub struct ElementSection(Vec<ElementSegment>);
648
649impl ElementSection {
650 pub fn with_entries(entries: Vec<ElementSegment>) -> Self {
652 ElementSection(entries)
653 }
654
655 pub fn entries(&self) -> &[ElementSegment] {
657 &self.0
658 }
659
660 pub fn entries_mut(&mut self) -> &mut Vec<ElementSegment> {
662 &mut self.0
663 }
664}
665
666impl Deserialize for ElementSection {
667 type Error = Error;
668
669 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
670 let _section_length = VarUint32::deserialize(reader)?;
672 let entries: Vec<ElementSegment> = CountedList::deserialize(reader)?.into_inner();
673 Ok(ElementSection(entries))
674 }
675}
676
677impl Serialize for ElementSection {
678 type Error = Error;
679
680 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
681 let mut counted_writer = CountedWriter::new(writer);
682 let data = self.0;
683 let counted_list = CountedListWriter::<ElementSegment, _>(
684 data.len(),
685 data.into_iter().map(Into::into),
686 );
687 counted_list.serialize(&mut counted_writer)?;
688 counted_writer.done()?;
689 Ok(())
690 }
691}
692
693#[derive(Default, Clone)]
695pub struct DataSection(Vec<DataSegment>);
696
697impl DataSection {
698 pub fn with_entries(entries: Vec<DataSegment>) -> Self {
700 DataSection(entries)
701 }
702
703 pub fn entries(&self) -> &[DataSegment] {
705 &self.0
706 }
707
708 pub fn entries_mut(&mut self) -> &mut Vec<DataSegment> {
710 &mut self.0
711 }
712}
713
714impl Deserialize for DataSection {
715 type Error = Error;
716
717 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
718 let _section_length = VarUint32::deserialize(reader)?;
720 let entries: Vec<DataSegment> = CountedList::deserialize(reader)?.into_inner();
721 Ok(DataSection(entries))
722 }
723}
724
725impl Serialize for DataSection {
726 type Error = Error;
727
728 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
729 let mut counted_writer = CountedWriter::new(writer);
730 let data = self.0;
731 let counted_list = CountedListWriter::<DataSegment, _>(
732 data.len(),
733 data.into_iter().map(Into::into),
734 );
735 counted_list.serialize(&mut counted_writer)?;
736 counted_writer.done()?;
737 Ok(())
738 }
739}
740
741#[cfg(test)]
742mod tests {
743
744 use super::super::{
745 deserialize_buffer, deserialize_file, ValueType, InitExpr, DataSegment,
746 serialize, ElementSegment, Opcodes, BlockType, Local, FuncBody,
747 };
748 use super::{Section, TypeSection, Type, DataSection, ElementSection, CodeSection};
749
750 #[test]
751 fn import_section() {
752 let module = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized");
753 let mut found = false;
754 for section in module.sections() {
755 match section {
756 &Section::Import(ref import_section) => {
757 assert_eq!(25, import_section.entries().len());
758 found = true
759 },
760 _ => { }
761 }
762 }
763 assert!(found, "There should be import section in test5.wasm");
764 }
765
766 fn functions_test_payload() -> &'static [u8] {
767 &[
768 0x03u8,
770 0x87, 0x80, 0x80, 0x80, 0x0,
772 0x04,
774 0x01,
776 0x86, 0x80, 0x00,
778 0x09,
780 0x33
782 ]
783 }
784
785 #[test]
786 fn fn_section_detect() {
787 let section: Section =
788 deserialize_buffer(functions_test_payload()).expect("section to be deserialized");
789
790 match section {
791 Section::Function(_) => {},
792 _ => {
793 panic!("Payload should be recognized as functions section")
794 }
795 }
796 }
797
798 #[test]
799 fn fn_section_number() {
800 let section: Section =
801 deserialize_buffer(functions_test_payload()).expect("section to be deserialized");
802
803 match section {
804 Section::Function(fn_section) => {
805 assert_eq!(4, fn_section.entries().len(), "There should be 4 functions total");
806 },
807 _ => {
808 }
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 match section {
819 Section::Function(fn_section) => {
820 assert_eq!(6, fn_section.entries()[1].type_ref());
821 },
822 _ => {
823 }
825 }
826 }
827
828 fn types_test_payload() -> &'static [u8] {
829 &[
830 148u8, 0x80, 0x80, 0x80, 0x0,
832
833 130u8, 0x80, 0x80, 0x80, 0x0,
835 0x01,
837 129u8, 0x80, 0x80, 0x80, 0x0,
839 0x7e, 0x00,
843
844 0x01,
846 130u8, 0x80, 0x80, 0x80, 0x0,
848 0x7e,
850 0x7d,
852 0x01, 0x7e
854 ]
855 }
856
857 #[test]
858 fn type_section_len() {
859 let type_section: TypeSection =
860 deserialize_buffer(types_test_payload()).expect("type_section be deserialized");
861
862 assert_eq!(type_section.types().len(), 2);
863 }
864
865 #[test]
866 fn type_section_infer() {
867 let type_section: TypeSection =
868 deserialize_buffer(types_test_payload()).expect("type_section be deserialized");
869
870 let t1 = match &type_section.types()[1] {
871 &Type::Function(ref func_type) => func_type
872 };
873
874 assert_eq!(Some(ValueType::I64), t1.return_type());
875 assert_eq!(2, t1.params().len());
876 }
877
878 fn export_payload() -> &'static [u8] {
879 &[
880 0x07,
882 148u8, 0x80, 0x80, 0x80, 0x0,
884 134u8, 0x80, 0x80, 0x80, 0x0,
886 0x01, 0x41, 0x01, 0x86, 0x80, 0x00,
889 0x01, 0x42, 0x01, 0x86, 0x00,
891 0x01, 0x43, 0x01, 0x07,
893 0x01, 0x44, 0x02, 0x00,
895 0x01, 0x45, 0x01, 0x01,
897 0x01, 0x46, 0x01, 0x02
899 ]
900 }
901
902
903 #[test]
904 fn export_detect() {
905 let section: Section =
906 deserialize_buffer(export_payload()).expect("section to be deserialized");
907
908 match section {
909 Section::Export(_) => {},
910 _ => {
911 panic!("Payload should be recognized as export section")
912 }
913 }
914 }
915
916 fn code_payload() -> &'static [u8] {
917 &[
918 0x0Au8,
920 0x20,
922 0x01,
924 0x1E,
926 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,
942 0x0B,
943 ]
944 }
945
946 #[test]
947 fn code_detect() {
948
949 let section: Section =
950 deserialize_buffer(code_payload()).expect("section to be deserialized");
951
952 match section {
953 Section::Code(_) => {},
954 _ => {
955 panic!("Payload should be recognized as a code section")
956 }
957 }
958 }
959
960 fn data_payload() -> &'static [u8] {
961 &[
962 0x0bu8, 19, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00,
969 0x00, 0x00, 0x00, 0x00,
970 0x00, 0x00, 0x00, 0x00,
971 0x00, 0x00, 0x00, 0x00
972 ]
973 }
974
975 #[test]
976 fn data_section_ser() {
977 let data_section = DataSection::with_entries(
978 vec![DataSegment::new(0u32, InitExpr::empty(), vec![0u8; 16])]
979 );
980
981 let buf = serialize(data_section).expect("Data section to be serialized");
982
983 assert_eq!(buf, vec![
984 20u8, 0x01, 0x00, 0x0b, 16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
991 0x00, 0x00, 0x00, 0x00,
992 0x00, 0x00, 0x00, 0x00
993 ]);
994 }
995
996 #[test]
997 fn data_section_detect() {
998 let section: Section =
999 deserialize_buffer(data_payload()).expect("section to be deserialized");
1000
1001 match section {
1002 Section::Data(_) => {},
1003 _ => {
1004 panic!("Payload should be recognized as a data section")
1005 }
1006 }
1007 }
1008
1009 #[test]
1010 fn element_section_ser() {
1011 let element_section = ElementSection::with_entries(
1012 vec![ElementSegment::new(0u32, InitExpr::empty(), vec![0u32; 4])]
1013 );
1014
1015 let buf = serialize(element_section).expect("Element section to be serialized");
1016
1017 assert_eq!(buf, vec![
1018 08u8, 0x01, 0x00, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00 ]);
1025 }
1026
1027 #[test]
1028 fn code_section_ser() {
1029 use super::super::Opcode::*;
1030
1031 let code_section = CodeSection::with_bodies(
1032 vec![
1033 FuncBody::new(
1034 vec![Local::new(1, ValueType::I32)],
1035 Opcodes::new(vec![
1036 Block(BlockType::Value(ValueType::I32)),
1037 GetGlobal(0),
1038 End,
1039 End,
1040 ])
1041 )
1042 ]);
1043
1044 let buf = serialize(code_section).expect("Code section to be serialized");
1045
1046 assert_eq!(buf, vec![
1047 11u8, 0x01, 9, 1, 1, 0x7f, 0x02, 0x7f, 0x23, 0x00, 0x0b, 0x0b, ]);
1059 }
1060
1061 #[test]
1062 fn start_section() {
1063 let section: Section = deserialize_buffer(&[08u8, 01u8, 00u8]).expect("Start section to deserialize");
1064 if let Section::Start(_) = section {
1065 } else {
1066 panic!("Payload should be a start section");
1067 }
1068
1069 let serialized = serialize(section).expect("Start section to successfully serializen");
1070
1071 assert_eq!(serialized, vec![08u8, 01u8, 00u8]);
1072 }
1073}