1use io;
2use std::vec::Vec;
3use std::string::String;
4use std::borrow::ToOwned;
5use super::{
6 Serialize,
7 Deserialize,
8 Error,
9 VarUint7,
10 VarUint32,
11 CountedList,
12 ImportEntry,
13 MemoryType,
14 TableType,
15 ExportEntry,
16 GlobalEntry,
17 Func,
18 FuncBody,
19 ElementSegment,
20 DataSegment,
21 CountedWriter,
22 CountedListWriter,
23 External,
24 serialize,
25};
26
27use super::types::Type;
28use super::name_section::NameSection;
29use super::reloc_section::RelocSection;
30
31const ENTRIES_BUFFER_LENGTH: usize = 16384;
32
33#[derive(Debug, Clone, PartialEq)]
35pub enum Section {
36 Unparsed {
38 id: u8,
40 payload: Vec<u8>,
42 },
43 Custom(CustomSection),
45 Type(TypeSection),
47 Import(ImportSection),
49 Function(FunctionSection),
51 Table(TableSection),
53 Memory(MemorySection),
55 Global(GlobalSection),
57 Export(ExportSection),
59 Start(u32),
61 Element(ElementSection),
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 invalid_id => {
131 return Err(Error::InvalidSectionId(invalid_id))
132 },
133 }
134 )
135 }
136}
137
138impl Serialize for Section {
139 type Error = Error;
140
141 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
142 match self {
143 Section::Custom(custom_section) => {
144 VarUint7::from(0x00).serialize(writer)?;
145 custom_section.serialize(writer)?;
146 },
147 Section::Unparsed { id, payload } => {
148 VarUint7::from(id).serialize(writer)?;
149 writer.write(&payload[..])?;
150 },
151 Section::Type(type_section) => {
152 VarUint7::from(0x01).serialize(writer)?;
153 type_section.serialize(writer)?;
154 },
155 Section::Import(import_section) => {
156 VarUint7::from(0x02).serialize(writer)?;
157 import_section.serialize(writer)?;
158 },
159 Section::Function(function_section) => {
160 VarUint7::from(0x03).serialize(writer)?;
161 function_section.serialize(writer)?;
162 },
163 Section::Table(table_section) => {
164 VarUint7::from(0x04).serialize(writer)?;
165 table_section.serialize(writer)?;
166 },
167 Section::Memory(memory_section) => {
168 VarUint7::from(0x05).serialize(writer)?;
169 memory_section.serialize(writer)?;
170 },
171 Section::Global(global_section) => {
172 VarUint7::from(0x06).serialize(writer)?;
173 global_section.serialize(writer)?;
174 },
175 Section::Export(export_section) => {
176 VarUint7::from(0x07).serialize(writer)?;
177 export_section.serialize(writer)?;
178 },
179 Section::Start(index) => {
180 VarUint7::from(0x08).serialize(writer)?;
181 let mut counted_writer = CountedWriter::new(writer);
182 VarUint32::from(index).serialize(&mut counted_writer)?;
183 counted_writer.done()?;
184 },
185 Section::Element(element_section) => {
186 VarUint7::from(0x09).serialize(writer)?;
187 element_section.serialize(writer)?;
188 },
189 Section::Code(code_section) => {
190 VarUint7::from(0x0a).serialize(writer)?;
191 code_section.serialize(writer)?;
192 },
193 Section::Data(data_section) => {
194 VarUint7::from(0x0b).serialize(writer)?;
195 data_section.serialize(writer)?;
196 },
197 Section::Name(name_section) => {
198 VarUint7::from(0x00).serialize(writer)?;
199 let custom = CustomSection {
200 name: "name".to_owned(),
201 payload: serialize(name_section)?,
202 };
203 custom.serialize(writer)?;
204 },
205 Section::Reloc(reloc_section) => {
206 VarUint7::from(0x00).serialize(writer)?;
207 reloc_section.serialize(writer)?;
208 },
209 }
210 Ok(())
211 }
212}
213
214impl Section {
215 pub(crate) fn id(&self) -> u8 {
216 match *self {
217 Section::Custom(_) => 0x00,
218 Section::Unparsed { .. } => 0x00,
219 Section::Type(_) => 0x1,
220 Section::Import(_) => 0x2,
221 Section::Function(_) => 0x3,
222 Section::Table(_) => 0x4,
223 Section::Memory(_) => 0x5,
224 Section::Global(_) => 0x6,
225 Section::Export(_) => 0x7,
226 Section::Start(_) => 0x8,
227 Section::Element(_) => 0x9,
228 Section::Code(_) => 0x0a,
229 Section::Data(_) => 0x0b,
230 Section::Name(_) => 0x00,
231 Section::Reloc(_) => 0x00,
232 }
233 }
234}
235
236pub(crate) struct SectionReader {
237 cursor: io::Cursor<Vec<u8>>,
238 declared_length: usize,
239}
240
241impl SectionReader {
242 pub fn new<R: io::Read>(reader: &mut R) -> Result<Self, ::elements::Error> {
243 let length = u32::from(VarUint32::deserialize(reader)?) as usize;
244 let inner_buffer = buffered_read!(ENTRIES_BUFFER_LENGTH, length, reader);
245 let buf_length = inner_buffer.len();
246 let cursor = io::Cursor::new(inner_buffer);
247
248 Ok(SectionReader {
249 cursor: cursor,
250 declared_length: buf_length,
251 })
252 }
253
254 pub fn close(self) -> Result<(), io::Error> {
255 let cursor = self.cursor;
256 let buf_length = self.declared_length;
257
258 if cursor.position() != buf_length {
259 Err(io::Error::InvalidData)
260 } else {
261 Ok(())
262 }
263 }
264}
265
266impl io::Read for SectionReader {
267 fn read(&mut self, buf: &mut [u8]) -> io::Result<()> {
268 self.cursor.read(buf)?;
269 Ok(())
270 }
271}
272
273fn read_entries<R: io::Read, T: Deserialize<Error=::elements::Error>>(reader: &mut R)
274 -> Result<Vec<T>, ::elements::Error>
275{
276 let mut section_reader = SectionReader::new(reader)?;
277 let result = CountedList::<T>::deserialize(&mut section_reader)?.into_inner();
278 section_reader.close()?;
279 Ok(result)
280}
281
282#[derive(Debug, Default, Clone, PartialEq)]
284pub struct CustomSection {
285 name: String,
286 payload: Vec<u8>,
287}
288
289impl CustomSection {
290
291 pub fn name(&self) -> &str {
293 &self.name
294 }
295
296 pub fn payload(&self) -> &[u8] {
298 &self.payload
299 }
300
301 pub fn name_mut(&mut self) -> &mut String {
303 &mut self.name
304 }
305
306 pub fn payload_mut(&mut self) -> &mut Vec<u8> {
308 &mut self.payload
309 }
310}
311
312impl Deserialize for CustomSection {
313 type Error = Error;
314
315 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
316 let section_length: usize = u32::from(VarUint32::deserialize(reader)?) as usize;
317 let buf = buffered_read!(16384, section_length, reader);
318 let mut cursor = io::Cursor::new(&buf[..]);
319 let name = String::deserialize(&mut cursor)?;
320 let payload = buf[cursor.position() as usize..].to_vec();
321 Ok(CustomSection { name: name, payload: payload })
322 }
323}
324
325impl Serialize for CustomSection {
326 type Error = Error;
327
328 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
329 use io::Write;
330
331 let mut counted_writer = CountedWriter::new(writer);
332 self.name.serialize(&mut counted_writer)?;
333 counted_writer.write(&self.payload[..])?;
334 counted_writer.done()?;
335 Ok(())
336 }
337}
338
339#[derive(Debug, Default, Clone, PartialEq)]
341pub struct TypeSection(Vec<Type>);
342
343impl TypeSection {
344 pub fn with_types(types: Vec<Type>) -> Self {
346 TypeSection(types)
347 }
348
349 pub fn types(&self) -> &[Type] {
351 &self.0
352 }
353
354 pub fn types_mut(&mut self) -> &mut Vec<Type> {
356 &mut self.0
357 }
358}
359
360impl Deserialize for TypeSection {
361 type Error = Error;
362
363 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
364 Ok(TypeSection(read_entries(reader)?))
365 }
366}
367
368impl Serialize for TypeSection {
369 type Error = Error;
370
371 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
372 let mut counted_writer = CountedWriter::new(writer);
373 let data = self.0;
374 let counted_list = CountedListWriter::<Type, _>(
375 data.len(),
376 data.into_iter().map(Into::into),
377 );
378 counted_list.serialize(&mut counted_writer)?;
379 counted_writer.done()?;
380 Ok(())
381 }
382}
383
384#[derive(Debug, Default, Clone, PartialEq)]
386pub struct ImportSection(Vec<ImportEntry>);
387
388impl ImportSection {
389 pub fn with_entries(entries: Vec<ImportEntry>) -> Self {
391 ImportSection(entries)
392 }
393
394 pub fn entries(&self) -> &[ImportEntry] {
396 &self.0
397 }
398
399 pub fn entries_mut(&mut self) -> &mut Vec<ImportEntry> {
401 &mut self.0
402 }
403
404 pub fn functions(&self) -> usize {
406 self.0.iter()
407 .filter(|entry| match entry.external() { &External::Function(_) => true, _ => false })
408 .count()
409 }
410
411 pub fn globals(&self) -> usize {
413 self.0.iter()
414 .filter(|entry| match entry.external() { &External::Global(_) => true, _ => false })
415 .count()
416 }
417}
418
419impl Deserialize for ImportSection {
420 type Error = Error;
421
422 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
423 Ok(ImportSection(read_entries(reader)?))
424 }
425}
426
427impl Serialize for ImportSection {
428 type Error = Error;
429
430 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
431 let mut counted_writer = CountedWriter::new(writer);
432 let data = self.0;
433 let counted_list = CountedListWriter::<ImportEntry, _>(
434 data.len(),
435 data.into_iter().map(Into::into),
436 );
437 counted_list.serialize(&mut counted_writer)?;
438 counted_writer.done()?;
439 Ok(())
440 }
441}
442
443#[derive(Default, Debug, Clone, PartialEq)]
445pub struct FunctionSection(Vec<Func>);
446
447impl FunctionSection {
448 pub fn with_entries(entries: Vec<Func>) -> Self {
450 FunctionSection(entries)
451 }
452
453 pub fn entries_mut(&mut self) -> &mut Vec<Func> {
455 &mut self.0
456 }
457
458 pub fn entries(&self) -> &[Func] {
460 &self.0
461 }
462}
463
464impl Deserialize for FunctionSection {
465 type Error = Error;
466
467 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
468 Ok(FunctionSection(read_entries(reader)?))
469 }
470}
471
472impl Serialize for FunctionSection {
473 type Error = Error;
474
475 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
476 let mut counted_writer = CountedWriter::new(writer);
477 let data = self.0;
478 let counted_list = CountedListWriter::<VarUint32, _>(
479 data.len(),
480 data.into_iter().map(|func| func.type_ref().into())
481 );
482 counted_list.serialize(&mut counted_writer)?;
483 counted_writer.done()?;
484 Ok(())
485 }
486}
487
488#[derive(Default, Debug, Clone, PartialEq)]
490pub struct TableSection(Vec<TableType>);
491
492impl TableSection {
493 pub fn entries(&self) -> &[TableType] {
495 &self.0
496 }
497
498 pub fn with_entries(entries: Vec<TableType>) -> Self {
500 TableSection(entries)
501 }
502
503 pub fn entries_mut(&mut self) -> &mut Vec<TableType> {
505 &mut self.0
506 }
507}
508
509impl Deserialize for TableSection {
510 type Error = Error;
511
512 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
513 Ok(TableSection(read_entries(reader)?))
514 }
515}
516
517impl Serialize for TableSection {
518 type Error = Error;
519
520 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
521 let mut counted_writer = CountedWriter::new(writer);
522 let data = self.0;
523 let counted_list = CountedListWriter::<TableType, _>(
524 data.len(),
525 data.into_iter().map(Into::into),
526 );
527 counted_list.serialize(&mut counted_writer)?;
528 counted_writer.done()?;
529 Ok(())
530 }
531}
532
533#[derive(Default, Debug, Clone, PartialEq)]
535pub struct MemorySection(Vec<MemoryType>);
536
537impl MemorySection {
538 pub fn entries(&self) -> &[MemoryType] {
540 &self.0
541 }
542
543 pub fn with_entries(entries: Vec<MemoryType>) -> Self {
545 MemorySection(entries)
546 }
547
548 pub fn entries_mut(&mut self) -> &mut Vec<MemoryType> {
550 &mut self.0
551 }
552}
553
554impl Deserialize for MemorySection {
555 type Error = Error;
556
557 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
558 Ok(MemorySection(read_entries(reader)?))
559 }
560}
561
562impl Serialize for MemorySection {
563 type Error = Error;
564
565 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
566 let mut counted_writer = CountedWriter::new(writer);
567 let data = self.0;
568 let counted_list = CountedListWriter::<MemoryType, _>(
569 data.len(),
570 data.into_iter().map(Into::into),
571 );
572 counted_list.serialize(&mut counted_writer)?;
573 counted_writer.done()?;
574 Ok(())
575 }
576}
577
578#[derive(Default, Debug, Clone, PartialEq)]
580pub struct GlobalSection(Vec<GlobalEntry>);
581
582impl GlobalSection {
583 pub fn entries(&self) -> &[GlobalEntry] {
585 &self.0
586 }
587
588 pub fn with_entries(entries: Vec<GlobalEntry>) -> Self {
590 GlobalSection(entries)
591 }
592
593 pub fn entries_mut(&mut self) -> &mut Vec<GlobalEntry> {
595 &mut self.0
596 }
597}
598
599impl Deserialize for GlobalSection {
600 type Error = Error;
601
602 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
603 Ok(GlobalSection(read_entries(reader)?))
604 }
605}
606
607impl Serialize for GlobalSection {
608 type Error = Error;
609
610 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
611 let mut counted_writer = CountedWriter::new(writer);
612 let data = self.0;
613 let counted_list = CountedListWriter::<GlobalEntry, _>(
614 data.len(),
615 data.into_iter().map(Into::into),
616 );
617 counted_list.serialize(&mut counted_writer)?;
618 counted_writer.done()?;
619 Ok(())
620 }
621}
622
623#[derive(Debug, Default, Clone, PartialEq)]
625pub struct ExportSection(Vec<ExportEntry>);
626
627impl ExportSection {
628 pub fn entries(&self) -> &[ExportEntry] {
630 &self.0
631 }
632
633 pub fn with_entries(entries: Vec<ExportEntry>) -> Self {
635 ExportSection(entries)
636 }
637
638 pub fn entries_mut(&mut self) -> &mut Vec<ExportEntry> {
640 &mut self.0
641 }
642}
643
644impl Deserialize for ExportSection {
645 type Error = Error;
646
647 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
648 Ok(ExportSection(read_entries(reader)?))
649 }
650}
651
652impl Serialize for ExportSection {
653 type Error = Error;
654
655 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
656 let mut counted_writer = CountedWriter::new(writer);
657 let data = self.0;
658 let counted_list = CountedListWriter::<ExportEntry, _>(
659 data.len(),
660 data.into_iter().map(Into::into),
661 );
662 counted_list.serialize(&mut counted_writer)?;
663 counted_writer.done()?;
664 Ok(())
665 }
666}
667
668#[derive(Default, Debug, Clone, PartialEq)]
670pub struct CodeSection(Vec<FuncBody>);
671
672impl CodeSection {
673 pub fn with_bodies(bodies: Vec<FuncBody>) -> Self {
675 CodeSection(bodies)
676 }
677
678 pub fn bodies(&self) -> &[FuncBody] {
680 &self.0
681 }
682
683 pub fn bodies_mut(&mut self) -> &mut Vec<FuncBody> {
685 &mut self.0
686 }
687}
688
689impl Deserialize for CodeSection {
690 type Error = Error;
691
692 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
693 Ok(CodeSection(read_entries(reader)?))
694 }
695}
696
697impl Serialize for CodeSection {
698 type Error = Error;
699
700 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
701 let mut counted_writer = CountedWriter::new(writer);
702 let data = self.0;
703 let counted_list = CountedListWriter::<FuncBody, _>(
704 data.len(),
705 data.into_iter().map(Into::into),
706 );
707 counted_list.serialize(&mut counted_writer)?;
708 counted_writer.done()?;
709 Ok(())
710 }
711}
712
713#[derive(Default, Debug, Clone, PartialEq)]
715pub struct ElementSection(Vec<ElementSegment>);
716
717impl ElementSection {
718 pub fn with_entries(entries: Vec<ElementSegment>) -> Self {
720 ElementSection(entries)
721 }
722
723 pub fn entries(&self) -> &[ElementSegment] {
725 &self.0
726 }
727
728 pub fn entries_mut(&mut self) -> &mut Vec<ElementSegment> {
730 &mut self.0
731 }
732}
733
734impl Deserialize for ElementSection {
735 type Error = Error;
736
737 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
738 Ok(ElementSection(read_entries(reader)?))
739 }
740}
741
742impl Serialize for ElementSection {
743 type Error = Error;
744
745 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
746 let mut counted_writer = CountedWriter::new(writer);
747 let data = self.0;
748 let counted_list = CountedListWriter::<ElementSegment, _>(
749 data.len(),
750 data.into_iter().map(Into::into),
751 );
752 counted_list.serialize(&mut counted_writer)?;
753 counted_writer.done()?;
754 Ok(())
755 }
756}
757
758#[derive(Default, Debug, Clone, PartialEq)]
760pub struct DataSection(Vec<DataSegment>);
761
762impl DataSection {
763 pub fn with_entries(entries: Vec<DataSegment>) -> Self {
765 DataSection(entries)
766 }
767
768 pub fn entries(&self) -> &[DataSegment] {
770 &self.0
771 }
772
773 pub fn entries_mut(&mut self) -> &mut Vec<DataSegment> {
775 &mut self.0
776 }
777}
778
779impl Deserialize for DataSection {
780 type Error = Error;
781
782 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
783 Ok(DataSection(read_entries(reader)?))
784 }
785}
786
787impl Serialize for DataSection {
788 type Error = Error;
789
790 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
791 let mut counted_writer = CountedWriter::new(writer);
792 let data = self.0;
793 let counted_list = CountedListWriter::<DataSegment, _>(
794 data.len(),
795 data.into_iter().map(Into::into),
796 );
797 counted_list.serialize(&mut counted_writer)?;
798 counted_writer.done()?;
799 Ok(())
800 }
801}
802
803#[cfg(test)]
804mod tests {
805
806 use super::super::{
807 deserialize_buffer, deserialize_file, ValueType, InitExpr, DataSegment,
808 serialize, ElementSegment, Instructions, BlockType, Local, FuncBody,
809 };
810 use super::{Section, TypeSection, Type, DataSection, ElementSection, CodeSection};
811
812 #[test]
813 fn import_section() {
814 let module = deserialize_file("./res/cases/v1/test5.swasm").expect("Should be deserialized");
815 let mut found = false;
816 for section in module.sections() {
817 match section {
818 &Section::Import(ref import_section) => {
819 assert_eq!(25, import_section.entries().len());
820 found = true
821 },
822 _ => { }
823 }
824 }
825 assert!(found, "There should be import section in test5.swasm");
826 }
827
828 fn functions_test_payload() -> &'static [u8] {
829 &[
830 0x03u8,
832 0x87, 0x80, 0x80, 0x80, 0x0,
834 0x04,
836 0x01,
838 0x86, 0x80, 0x00,
840 0x09,
842 0x33
844 ]
845 }
846
847 #[test]
848 fn fn_section_detect() {
849 let section: Section =
850 deserialize_buffer(functions_test_payload()).expect("section to be deserialized");
851
852 match section {
853 Section::Function(_) => {},
854 _ => {
855 panic!("Payload should be recognized as functions section")
856 }
857 }
858 }
859
860 #[test]
861 fn fn_section_number() {
862 let section: Section =
863 deserialize_buffer(functions_test_payload()).expect("section to be deserialized");
864
865 match section {
866 Section::Function(fn_section) => {
867 assert_eq!(4, fn_section.entries().len(), "There should be 4 functions total");
868 },
869 _ => {
870 }
872 }
873 }
874
875 #[test]
876 fn fn_section_ref() {
877 let section: Section =
878 deserialize_buffer(functions_test_payload()).expect("section to be deserialized");
879
880 match section {
881 Section::Function(fn_section) => {
882 assert_eq!(6, fn_section.entries()[1].type_ref());
883 },
884 _ => {
885 }
887 }
888 }
889
890 fn types_test_payload() -> &'static [u8] {
891 &[
892 11,
894
895 2,
897 0x60,
899 1,
901 0x7e, 0x00,
905
906 0x60,
908 2,
910 0x7e,
912 0x7d,
914 0x01, 0x7e
916 ]
917 }
918
919 #[test]
920 fn type_section_len() {
921 let type_section: TypeSection =
922 deserialize_buffer(types_test_payload()).expect("type_section be deserialized");
923
924 assert_eq!(type_section.types().len(), 2);
925 }
926
927 #[test]
928 fn type_section_infer() {
929 let type_section: TypeSection =
930 deserialize_buffer(types_test_payload()).expect("type_section be deserialized");
931
932 let t1 = match &type_section.types()[1] {
933 &Type::Function(ref func_type) => func_type
934 };
935
936 assert_eq!(Some(ValueType::I64), t1.return_type());
937 assert_eq!(2, t1.params().len());
938 }
939
940 fn export_payload() -> &'static [u8] {
941 &[
942 0x07,
944 28,
946 6,
948 0x01, 0x41, 0x01, 0x86, 0x80, 0x00,
951 0x01, 0x42, 0x01, 0x86, 0x00,
953 0x01, 0x43, 0x01, 0x07,
955 0x01, 0x44, 0x02, 0x00,
957 0x01, 0x45, 0x01, 0x01,
959 0x01, 0x46, 0x01, 0x02
961 ]
962 }
963
964
965 #[test]
966 fn export_detect() {
967 let section: Section =
968 deserialize_buffer(export_payload()).expect("section to be deserialized");
969
970 match section {
971 Section::Export(_) => {},
972 _ => {
973 panic!("Payload should be recognized as export section")
974 }
975 }
976 }
977
978 fn code_payload() -> &'static [u8] {
979 &[
980 0x0Au8,
982 0x20,
984 0x01,
986 0x1E,
988 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,
1004 0x0B,
1005 ]
1006 }
1007
1008 #[test]
1009 fn code_detect() {
1010
1011 let section: Section =
1012 deserialize_buffer(code_payload()).expect("section to be deserialized");
1013
1014 match section {
1015 Section::Code(_) => {},
1016 _ => {
1017 panic!("Payload should be recognized as a code section")
1018 }
1019 }
1020 }
1021
1022 fn data_payload() -> &'static [u8] {
1023 &[
1024 0x0bu8, 20, 0x01, 0x00, 0x0b, 0x10,
1030 0x00, 0x00, 0x00, 0x00,
1032 0x00, 0x00, 0x00, 0x00,
1033 0x00, 0x00, 0x00, 0x00,
1034 0x00, 0x00, 0x00, 0x00
1035 ]
1036 }
1037
1038 #[test]
1039 fn data_section_ser() {
1040 let data_section = DataSection::with_entries(
1041 vec![DataSegment::new(0u32, InitExpr::empty(), vec![0u8; 16])]
1042 );
1043
1044 let buf = serialize(data_section).expect("Data section to be serialized");
1045
1046 assert_eq!(buf, vec![
1047 20u8, 0x01, 0x00, 0x0b, 16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1054 0x00, 0x00, 0x00, 0x00,
1055 0x00, 0x00, 0x00, 0x00
1056 ]);
1057 }
1058
1059 #[test]
1060 fn data_section_detect() {
1061 let section: Section =
1062 deserialize_buffer(data_payload()).expect("section to be deserialized");
1063
1064 match section {
1065 Section::Data(_) => {},
1066 _ => {
1067 panic!("Payload should be recognized as a data section")
1068 }
1069 }
1070 }
1071
1072 #[test]
1073 fn element_section_ser() {
1074 let element_section = ElementSection::with_entries(
1075 vec![ElementSegment::new(0u32, InitExpr::empty(), vec![0u32; 4])]
1076 );
1077
1078 let buf = serialize(element_section).expect("Element section to be serialized");
1079
1080 assert_eq!(buf, vec![
1081 08u8, 0x01, 0x00, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00 ]);
1088 }
1089
1090 #[test]
1091 fn code_section_ser() {
1092 use super::super::Instruction::*;
1093
1094 let code_section = CodeSection::with_bodies(
1095 vec![
1096 FuncBody::new(
1097 vec![Local::new(1, ValueType::I32)],
1098 Instructions::new(vec![
1099 Block(BlockType::Value(ValueType::I32)),
1100 GetGlobal(0),
1101 End,
1102 End,
1103 ])
1104 )
1105 ]);
1106
1107 let buf = serialize(code_section).expect("Code section to be serialized");
1108
1109 assert_eq!(buf, vec![
1110 11u8, 0x01, 9, 1, 1, 0x7f, 0x02, 0x7f, 0x23, 0x00, 0x0b, 0x0b, ]);
1122 }
1123
1124 #[test]
1125 fn start_section() {
1126 let section: Section = deserialize_buffer(&[08u8, 01u8, 00u8]).expect("Start section to deserialize");
1127 if let Section::Start(_) = section {
1128 } else {
1129 panic!("Payload should be a start section");
1130 }
1131
1132 let serialized = serialize(section).expect("Start section to successfully serializen");
1133
1134 assert_eq!(serialized, vec![08u8, 01u8, 00u8]);
1135 }
1136}