1use alloc::{borrow::ToOwned, vec::Vec, string::String};
2use crate::io;
3
4use super::{deserialize_buffer, serialize, Deserialize, Serialize, Error, Uint32, External};
5use super::section::{
6 Section, CodeSection, TypeSection, ImportSection, ExportSection, FunctionSection,
7 GlobalSection, TableSection, ElementSection, DataSection, MemorySection,
8 CustomSection,
9};
10use super::name_section::NameSection;
11use super::reloc_section::RelocSection;
12
13use core::cmp;
14
15const WASM_MAGIC_NUMBER: [u8; 4] = [0x00, 0x61, 0x73, 0x6d];
16
17#[derive(Debug, Clone, PartialEq)]
19pub struct Module {
20 magic: u32,
21 version: u32,
22 sections: Vec<Section>,
23}
24
25#[derive(Debug, Clone, Copy, PartialEq)]
26pub enum ImportCountType {
28 Function,
30 Global,
32 Table,
34 Memory,
36}
37
38impl Default for Module {
39 fn default() -> Self {
40 Module {
41 magic: u32::from_le_bytes(WASM_MAGIC_NUMBER),
42 version: 1,
43 sections: Vec::with_capacity(16),
44 }
45 }
46}
47
48impl Module {
49 pub fn new(sections: Vec<Section>) -> Self {
51 Module {
52 sections: sections, ..Default::default()
53 }
54 }
55
56 pub fn from_bytes<T: AsRef<[u8]>>(input: T) -> Result<Self, Error> {
58 Ok(deserialize_buffer::<Module>(input.as_ref())?)
59 }
60
61 pub fn to_bytes(self) -> Result<Vec<u8>, Error> {
63 Ok(serialize::<Module>(self)?)
64 }
65
66 pub fn into_sections(self) -> Vec<Section> {
68 self.sections
69 }
70
71 pub fn version(&self) -> u32 { self.version }
73
74 pub fn sections(&self) -> &[Section] {
78 &self.sections
79 }
80
81 pub fn sections_mut(&mut self) -> &mut Vec<Section> {
85 &mut self.sections
86 }
87
88 pub fn insert_section(&mut self, section: Section) -> Result<(), Error> {
91 let sections = self.sections_mut();
92
93 if section.order() == 0 {
95 sections.push(section);
96 return Ok(());
97 }
98
99 if sections.iter().position(|s| s.order() == section.order()).is_some() {
101 return Err(Error::DuplicatedSections(section.order()));
102 }
103
104 if let Some(pos) = sections.iter().position(|s| section.order() < s.order()) {
106 sections.insert(pos, section);
107 } else {
108 sections.push(section);
109 }
110
111 Ok(())
112 }
113
114 pub fn code_section(&self) -> Option<&CodeSection> {
116 for section in self.sections() {
117 if let &Section::Code(ref code_section) = section { return Some(code_section); }
118 }
119 None
120 }
121
122 pub fn code_section_mut(&mut self) -> Option<&mut CodeSection> {
124 for section in self.sections_mut() {
125 if let Section::Code(ref mut code_section) = *section { return Some(code_section); }
126 }
127 None
128 }
129
130 pub fn type_section(&self) -> Option<&TypeSection> {
132 for section in self.sections() {
133 if let &Section::Type(ref type_section) = section { return Some(type_section); }
134 }
135 None
136 }
137
138 pub fn type_section_mut(&mut self) -> Option<&mut TypeSection> {
140 for section in self.sections_mut() {
141 if let Section::Type(ref mut type_section) = *section { return Some(type_section); }
142 }
143 None
144 }
145
146 pub fn import_section(&self) -> Option<&ImportSection> {
148 for section in self.sections() {
149 if let &Section::Import(ref import_section) = section { return Some(import_section); }
150 }
151 None
152 }
153
154 pub fn import_section_mut(&mut self) -> Option<&mut ImportSection> {
156 for section in self.sections_mut() {
157 if let Section::Import(ref mut import_section) = *section { return Some(import_section); }
158 }
159 None
160 }
161
162 pub fn global_section(&self) -> Option<&GlobalSection> {
164 for section in self.sections() {
165 if let &Section::Global(ref section) = section { return Some(section); }
166 }
167 None
168 }
169
170 pub fn global_section_mut(&mut self) -> Option<&mut GlobalSection> {
172 for section in self.sections_mut() {
173 if let Section::Global(ref mut section) = *section { return Some(section); }
174 }
175 None
176 }
177
178
179 pub fn export_section(&self) -> Option<&ExportSection> {
181 for section in self.sections() {
182 if let &Section::Export(ref export_section) = section { return Some(export_section); }
183 }
184 None
185 }
186
187 pub fn export_section_mut(&mut self) -> Option<&mut ExportSection> {
189 for section in self.sections_mut() {
190 if let Section::Export(ref mut export_section) = *section { return Some(export_section); }
191 }
192 None
193 }
194
195 pub fn table_section(&self) -> Option<&TableSection> {
197 for section in self.sections() {
198 if let &Section::Table(ref section) = section { return Some(section); }
199 }
200 None
201 }
202
203 pub fn table_section_mut(&mut self) -> Option<&mut TableSection> {
205 for section in self.sections_mut() {
206 if let Section::Table(ref mut section) = *section { return Some(section); }
207 }
208 None
209 }
210
211 pub fn data_section(&self) -> Option<&DataSection> {
213 for section in self.sections() {
214 if let &Section::Data(ref section) = section { return Some(section); }
215 }
216 None
217 }
218
219 pub fn data_section_mut(&mut self) -> Option<&mut DataSection> {
221 for section in self.sections_mut() {
222 if let Section::Data(ref mut section) = *section { return Some(section); }
223 }
224 None
225 }
226
227 pub fn elements_section(&self) -> Option<&ElementSection> {
229 for section in self.sections() {
230 if let &Section::Element(ref section) = section { return Some(section); }
231 }
232 None
233 }
234
235 pub fn elements_section_mut(&mut self) -> Option<&mut ElementSection> {
237 for section in self.sections_mut() {
238 if let Section::Element(ref mut section) = *section { return Some(section); }
239 }
240 None
241 }
242
243 pub fn memory_section(&self) -> Option<&MemorySection> {
245 for section in self.sections() {
246 if let &Section::Memory(ref section) = section { return Some(section); }
247 }
248 None
249 }
250
251 pub fn memory_section_mut(&mut self) -> Option<&mut MemorySection> {
253 for section in self.sections_mut() {
254 if let Section::Memory(ref mut section) = *section { return Some(section); }
255 }
256 None
257 }
258
259 pub fn function_section(&self) -> Option<&FunctionSection> {
261 for section in self.sections() {
262 if let &Section::Function(ref sect) = section { return Some(sect); }
263 }
264 None
265 }
266
267 pub fn function_section_mut(&mut self) -> Option<&mut FunctionSection> {
269 for section in self.sections_mut() {
270 if let Section::Function(ref mut sect) = *section { return Some(sect); }
271 }
272 None
273 }
274
275 pub fn start_section(&self) -> Option<u32> {
277 for section in self.sections() {
278 if let &Section::Start(sect) = section { return Some(sect); }
279 }
280 None
281 }
282
283 pub fn set_start_section(&mut self, new_start: u32) {
285 for section in self.sections_mut().iter_mut() {
286 if let &mut Section::Start(_sect) = section {
287 *section = Section::Start(new_start);
288 return
289 }
290 }
291 self.insert_section(Section::Start(new_start)).expect("insert_section should not fail");
293 }
294
295 pub fn clear_start_section(&mut self) {
297 let sections = self.sections_mut();
298 let mut rmidx = sections.len();
299 for (index, section) in sections.iter_mut().enumerate() {
300 if let Section::Start(_sect) = section {
301 rmidx = index;
302 break;
303 }
304 }
305 if rmidx < sections.len() {
306 sections.remove(rmidx);
307 }
308 }
309
310 pub fn custom_sections(&self) -> impl Iterator<Item=&CustomSection> {
312 self.sections().iter().filter_map(|s| {
313 if let Section::Custom(s) = s {
314 Some(s)
315 } else {
316 None
317 }
318 })
319 }
320
321 pub fn set_custom_section(&mut self, name: impl Into<String>, payload: Vec<u8>) {
324 let name: String = name.into();
325 for section in self.sections_mut() {
326 if let &mut Section::Custom(ref mut sect) = section {
327 if sect.name() == name {
328 *sect = CustomSection::new(name, payload);
329 return
330 }
331 }
332 }
333 self.sections_mut().push(Section::Custom(CustomSection::new(name, payload)));
334 }
335
336 pub fn clear_custom_section(&mut self, name: impl AsRef<str>) -> Option<CustomSection> {
339 let name: &str = name.as_ref();
340
341 let sections = self.sections_mut();
342
343 for i in 0..sections.len() {
344 let mut remove = false;
345 if let Section::Custom(ref sect) = sections[i] {
346 if sect.name() == name {
347 remove = true;
348 }
349 }
350
351 if remove {
352 let removed = sections.remove(i);
353 match removed {
354 Section::Custom(sect) => return Some(sect),
355 _ => unreachable!(), }
357 }
358 }
359 None
360 }
361
362 pub fn has_names_section(&self) -> bool {
367 self.sections().iter().any(|e| {
368 match e {
369 Section::Custom(custom) => custom.name() == "name",
371 Section::Name(_) => true,
373 _ => false,
374 }
375 })
376 }
377
378 pub fn names_section(&self) -> Option<&NameSection> {
383 for section in self.sections() {
384 if let Section::Name(ref sect) = *section { return Some(sect); }
385 }
386 None
387 }
388
389 pub fn names_section_mut(&mut self) -> Option<&mut NameSection> {
394 for section in self.sections_mut() {
395 if let Section::Name(ref mut sect) = *section { return Some(sect); }
396 }
397 None
398 }
399
400 pub fn parse_names(mut self) -> Result<Self, (Vec<(usize, Error)>, Self)> {
406 let mut parse_errors = Vec::new();
407
408 for i in 0..self.sections.len() {
409 if let Some(name_section) = {
410 let section = self.sections.get(i).expect("cannot fail because i in range 0..len; qed");
411 if let Section::Custom(ref custom) = *section {
412 if custom.name() == "name" {
413 let mut rdr = io::Cursor::new(custom.payload());
414 let name_section = match NameSection::deserialize(&self, &mut rdr) {
415 Ok(ns) => ns,
416 Err(e) => { parse_errors.push((i, e)); continue; }
417 };
418 Some(name_section)
419 } else {
420 None
421 }
422 } else { None }
423 } {
424 *self.sections.get_mut(i).expect("cannot fail because i in range 0..len; qed") = Section::Name(name_section);
426 }
427 }
428
429 if parse_errors.len() > 0 {
430 Err((parse_errors, self))
431 } else {
432 Ok(self)
433 }
434 }
435
436 pub fn parse_reloc(mut self) -> Result<Self, (Vec<(usize, Error)>, Self)> {
442 let mut parse_errors = Vec::new();
443
444 for (i, section) in self.sections.iter_mut().enumerate() {
445 if let Some(relocation_section) = {
446 if let Section::Custom(ref custom) = *section {
447 if custom.name().starts_with("reloc.") {
448 let mut rdr = io::Cursor::new(custom.payload());
449 let reloc_section = match RelocSection::deserialize(custom.name().to_owned(), &mut rdr) {
450 Ok(reloc_section) => reloc_section,
451 Err(e) => { parse_errors.push((i, e)); continue; }
452 };
453 if rdr.position() != custom.payload().len() {
454 parse_errors.push((i, io::Error::InvalidData.into()));
455 continue;
456 }
457 Some(Section::Reloc(reloc_section))
458 }
459 else {
460 None
461 }
462 }
463 else {
464 None
465 }
466 } {
467 *section = relocation_section;
468 }
469 }
470
471 if parse_errors.len() > 0 {
472 Err((parse_errors, self))
473 } else {
474 Ok(self)
475 }
476 }
477
478 pub fn import_count(&self, count_type: ImportCountType) -> usize {
480 self.import_section()
481 .map(|is|
482 is.entries().iter().filter(|import| match (count_type, *import.external()) {
483 (ImportCountType::Function, External::Function(_)) => true,
484 (ImportCountType::Global, External::Global(_)) => true,
485 (ImportCountType::Table, External::Table(_)) => true,
486 (ImportCountType::Memory, External::Memory(_)) => true,
487 _ => false
488 }).count())
489 .unwrap_or(0)
490 }
491
492 pub fn functions_space(&self) -> usize {
494 self.import_count(ImportCountType::Function) +
495 self.function_section().map(|fs| fs.entries().len()).unwrap_or(0)
496 }
497
498 pub fn globals_space(&self) -> usize {
500 self.import_count(ImportCountType::Global) +
501 self.global_section().map(|gs| gs.entries().len()).unwrap_or(0)
502 }
503
504 pub fn table_space(&self) -> usize {
506 self.import_count(ImportCountType::Table) +
507 self.table_section().map(|ts| ts.entries().len()).unwrap_or(0)
508 }
509
510 pub fn memory_space(&self) -> usize {
512 self.import_count(ImportCountType::Memory) +
513 self.memory_section().map(|ms| ms.entries().len()).unwrap_or(0)
514 }
515}
516
517impl Deserialize for Module {
518 type Error = super::Error;
519
520 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
521 let mut sections = Vec::new();
522
523 let mut magic = [0u8; 4];
524 reader.read(&mut magic)?;
525 if magic != WASM_MAGIC_NUMBER {
526 return Err(Error::InvalidMagic);
527 }
528
529 let version: u32 = Uint32::deserialize(reader)?.into();
530
531 if version != 1 {
532 return Err(Error::UnsupportedVersion(version));
533 }
534
535 let mut last_section_order = 0;
536
537 loop {
538 match Section::deserialize(reader) {
539 Err(Error::UnexpectedEof) => { break; },
540 Err(e) => { return Err(e) },
541 Ok(section) => {
542 if section.order() != 0 {
543 if last_section_order > section.order() {
544 return Err(Error::SectionsOutOfOrder);
545 } else if last_section_order == section.order() {
546 return Err(Error::DuplicatedSections(last_section_order));
547 }
548 last_section_order = section.order();
549 }
550 sections.push(section);
551 }
552 }
553 }
554
555 let module = Module {
556 magic: u32::from_le_bytes(magic),
557 version: version,
558 sections: sections,
559 };
560
561 if module.code_section().map(|cs| cs.bodies().len()).unwrap_or(0) !=
562 module.function_section().map(|fs| fs.entries().len()).unwrap_or(0)
563 {
564 return Err(Error::InconsistentCode);
565 }
566
567 Ok(module)
568 }
569}
570
571impl Serialize for Module {
572 type Error = Error;
573
574 fn serialize<W: io::Write>(self, w: &mut W) -> Result<(), Self::Error> {
575 Uint32::from(self.magic).serialize(w)?;
576 Uint32::from(self.version).serialize(w)?;
577 for section in self.sections.into_iter() {
578 section.serialize(w)?;
580 }
581 Ok(())
582 }
583}
584
585#[derive(Debug, Copy, Clone, PartialEq)]
586struct PeekSection<'a> {
587 cursor: usize,
588 region: &'a [u8],
589}
590
591impl<'a> io::Read for PeekSection<'a> {
592 fn read(&mut self, buf: &mut [u8]) -> io::Result<()> {
593 let available = cmp::min(buf.len(), self.region.len() - self.cursor);
594 if available < buf.len() {
595 return Err(io::Error::UnexpectedEof);
596 }
597
598 let range = self.cursor..self.cursor + buf.len();
599 buf.copy_from_slice(&self.region[range]);
600
601 self.cursor += available;
602 Ok(())
603 }
604}
605
606pub fn peek_size(source: &[u8]) -> usize {
608 if source.len() < 9 {
609 return 0;
610 }
611
612 let mut cursor = 8;
613 loop {
614 let (new_cursor, section_id, section_len) = {
615 let mut peek_section = PeekSection { cursor: 0, region: &source[cursor..] };
616 let section_id: u8 = match super::VarUint7::deserialize(&mut peek_section) {
617 Ok(res) => res.into(),
618 Err(_) => { break; },
619 };
620 let section_len: u32 = match super::VarUint32::deserialize(&mut peek_section) {
621 Ok(res) => res.into(),
622 Err(_) => { break; },
623 };
624
625 (peek_section.cursor, section_id, section_len)
626 };
627
628 if section_id <= 11 && section_len > 0 {
629 let next_cursor = cursor + new_cursor + section_len as usize;
630 if next_cursor > source.len() {
631 break;
632 } else if next_cursor == source.len() {
633 cursor = next_cursor;
634 break;
635 }
636 cursor = next_cursor;
637 } else {
638 break;
639 }
640 }
641
642 cursor
643}
644
645#[cfg(test)]
646mod integration_tests {
647 use super::super::{deserialize_file, serialize, deserialize_buffer, Section, TypeSection, FunctionSection, ExportSection, CodeSection};
648 use super::Module;
649
650 #[test]
651 fn hello() {
652 let module = deserialize_file("./res/cases/v1/hello.wasm").expect("Should be deserialized");
653
654 assert_eq!(module.version(), 1);
655 assert_eq!(module.sections().len(), 8);
656 }
657
658 #[test]
659 fn serde() {
660 let module = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized");
661 let buf = serialize(module).expect("serialization to succeed");
662
663 let module_new: Module = deserialize_buffer(&buf).expect("deserialization to succeed");
664 let module_old = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized");
665
666 assert_eq!(module_old.sections().len(), module_new.sections().len());
667 }
668
669 #[test]
670 fn serde_type() {
671 let mut module = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized");
672 module.sections_mut().retain(|x| {
673 if let &Section::Type(_) = x { true } else { false }
674 });
675
676 let buf = serialize(module).expect("serialization to succeed");
677
678 let module_new: Module = deserialize_buffer(&buf).expect("deserialization to succeed");
679 let module_old = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized");
680 assert_eq!(
681 module_old.type_section().expect("type section exists").types().len(),
682 module_new.type_section().expect("type section exists").types().len(),
683 "There should be equal amount of types before and after serialization"
684 );
685 }
686
687 #[test]
688 fn serde_import() {
689 let mut module = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized");
690 module.sections_mut().retain(|x| {
691 if let &Section::Import(_) = x { true } else { false }
692 });
693
694 let buf = serialize(module).expect("serialization to succeed");
695
696 let module_new: Module = deserialize_buffer(&buf).expect("deserialization to succeed");
697 let module_old = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized");
698 assert_eq!(
699 module_old.import_section().expect("import section exists").entries().len(),
700 module_new.import_section().expect("import section exists").entries().len(),
701 "There should be equal amount of import entries before and after serialization"
702 );
703 }
704
705 #[test]
706 fn serde_code() {
707 let mut module = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized");
708 module.sections_mut().retain(|x| {
709 if let &Section::Code(_) = x { return true }
710 if let &Section::Function(_) = x { true } else { false }
711 });
712
713 let buf = serialize(module).expect("serialization to succeed");
714
715 let module_new: Module = deserialize_buffer(&buf).expect("deserialization to succeed");
716 let module_old = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized");
717 assert_eq!(
718 module_old.code_section().expect("code section exists").bodies().len(),
719 module_new.code_section().expect("code section exists").bodies().len(),
720 "There should be equal amount of function bodies before and after serialization"
721 );
722 }
723
724 #[test]
725 fn const_() {
726 use super::super::Instruction::*;
727
728 let module = deserialize_file("./res/cases/v1/const.wasm").expect("Should be deserialized");
729 let func = &module.code_section().expect("Code section to exist").bodies()[0];
730 assert_eq!(func.code().elements().len(), 20);
731
732 assert_eq!(I64Const(9223372036854775807), func.code().elements()[0]);
733 assert_eq!(I64Const(-9223372036854775808), func.code().elements()[1]);
734 assert_eq!(I64Const(-1152894205662152753), func.code().elements()[2]);
735 assert_eq!(I64Const(-8192), func.code().elements()[3]);
736 assert_eq!(I32Const(1024), func.code().elements()[4]);
737 assert_eq!(I32Const(2048), func.code().elements()[5]);
738 assert_eq!(I32Const(4096), func.code().elements()[6]);
739 assert_eq!(I32Const(8192), func.code().elements()[7]);
740 assert_eq!(I32Const(16384), func.code().elements()[8]);
741 assert_eq!(I32Const(32767), func.code().elements()[9]);
742 assert_eq!(I32Const(-1024), func.code().elements()[10]);
743 assert_eq!(I32Const(-2048), func.code().elements()[11]);
744 assert_eq!(I32Const(-4096), func.code().elements()[12]);
745 assert_eq!(I32Const(-8192), func.code().elements()[13]);
746 assert_eq!(I32Const(-16384), func.code().elements()[14]);
747 assert_eq!(I32Const(-32768), func.code().elements()[15]);
748 assert_eq!(I32Const(-2147483648), func.code().elements()[16]);
749 assert_eq!(I32Const(2147483647), func.code().elements()[17]);
750 }
751
752 #[test]
753 fn store() {
754 use super::super::Instruction::*;
755
756 let module = deserialize_file("./res/cases/v1/offset.wasm").expect("Should be deserialized");
757 let func = &module.code_section().expect("Code section to exist").bodies()[0];
758
759 assert_eq!(func.code().elements().len(), 5);
760 assert_eq!(I64Store(0, 32), func.code().elements()[2]);
761 }
762
763 #[test]
764 fn peek() {
765 use super::peek_size;
766
767 let module = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized");
768 let mut buf = serialize(module).expect("serialization to succeed");
769
770 buf.extend_from_slice(&[1, 5, 12, 17]);
771
772 assert_eq!(peek_size(&buf), buf.len() - 4);
773 }
774
775
776 #[test]
777 fn peek_2() {
778 use super::peek_size;
779
780 let module = deserialize_file("./res/cases/v1/offset.wasm").expect("Should be deserialized");
781 let mut buf = serialize(module).expect("serialization to succeed");
782
783 buf.extend_from_slice(&[0, 0, 0, 0, 0, 1, 5, 12, 17]);
784
785 assert_eq!(peek_size(&buf), buf.len() - 9);
786 }
787
788 #[test]
789 fn peek_3() {
790 use super::peek_size;
791
792 let module = deserialize_file("./res/cases/v1/peek_sample.wasm").expect("Should be deserialized");
793 let buf = serialize(module).expect("serialization to succeed");
794
795 assert_eq!(peek_size(&buf), buf.len());
796 }
797
798 #[test]
799 fn module_default_round_trip() {
800 let module1 = Module::default();
801 let buf = serialize(module1).expect("Serialization should succeed");
802
803 let module2: Module = deserialize_buffer(&buf).expect("Deserialization should succeed");
804 assert_eq!(Module::default().magic, module2.magic);
805 }
806
807 #[test]
808 fn names() {
809 let module = deserialize_file("./res/cases/v1/with_names.wasm")
810 .expect("Should be deserialized")
811 .parse_names()
812 .expect("Names to be parsed");
813
814 let mut found_section = false;
815 for section in module.sections() {
816 match *section {
817 Section::Name(ref name_section) => {
818 let function_name_subsection = name_section
819 .functions()
820 .expect("function_name_subsection should be present");
821 assert_eq!(
822 function_name_subsection.names().get(0).expect("Should be entry #0"),
823 "elog"
824 );
825 assert_eq!(
826 function_name_subsection.names().get(11).expect("Should be entry #0"),
827 "_ZN48_$LT$pwasm_token_contract..Endpoint$LT$T$GT$$GT$3new17hc3ace6dea0978cd9E"
828 );
829
830 found_section = true;
831 },
832 _ => {},
833 }
834 }
835
836 assert!(found_section, "Name section should be present in dedicated example");
837 }
838
839 #[test]
841 fn shared_memory_flag() {
842 let module = deserialize_file("./res/cases/v1/varuint1_1.wasm");
843 assert_eq!(module.is_ok(), cfg!(feature="atomics"));
844 }
845
846
847 #[test]
848 fn memory_space() {
849 let module = deserialize_file("./res/cases/v1/two-mems.wasm").expect("failed to deserialize");
850 assert_eq!(module.memory_space(), 2);
851 }
852
853 #[test]
854 fn add_custom_section() {
855 let mut module = deserialize_file("./res/cases/v1/start_mut.wasm").expect("failed to deserialize");
856 assert!(module.custom_sections().next().is_none());
857 module.set_custom_section("mycustomsection".to_string(), vec![1, 2, 3, 4]);
858 {
859 let sections = module.custom_sections().collect::<Vec<_>>();
860 assert_eq!(sections.len(), 1);
861 assert_eq!(sections[0].name(), "mycustomsection");
862 assert_eq!(sections[0].payload(), &[1, 2, 3, 4]);
863 }
864
865 let old_section = module.clear_custom_section("mycustomsection");
866 assert_eq!(old_section.expect("Did not find custom section").payload(), &[1, 2, 3, 4]);
867
868 assert!(module.custom_sections().next().is_none());
869 }
870
871 #[test]
872 fn mut_start() {
873 let mut module = deserialize_file("./res/cases/v1/start_mut.wasm").expect("failed to deserialize");
874 assert_eq!(module.start_section().expect("Did not find any start section"), 1);
875 module.set_start_section(0);
876 assert_eq!(module.start_section().expect("Did not find any start section"), 0);
877 module.clear_start_section();
878 assert_eq!(None, module.start_section());
879 }
880
881 #[test]
882 fn add_start() {
883 let mut module = deserialize_file("./res/cases/v1/start_add.wasm").expect("failed to deserialize");
884 assert!(module.start_section().is_none());
885 module.set_start_section(0);
886 assert_eq!(module.start_section().expect("Did not find any start section"), 0);
887
888 let sections = module.sections().iter().map(|s| s.order()).collect::<Vec<_>>();
889 assert_eq!(sections, vec![1, 2, 3, 6, 7, 8, 9, 11, 12]);
890 }
891
892 #[test]
893 fn add_start_custom() {
894 let mut module = deserialize_file("./res/cases/v1/start_add_custom.wasm").expect("failed to deserialize");
895
896 let sections = module.sections().iter().map(|s| s.order()).collect::<Vec<_>>();
897 assert_eq!(sections, vec![1, 2, 3, 6, 7, 9, 11, 12, 0]);
898
899 assert!(module.start_section().is_none());
900 module.set_start_section(0);
901 assert_eq!(module.start_section().expect("Dorder not find any start section"), 0);
902
903 let sections = module.sections().iter().map(|s| s.order()).collect::<Vec<_>>();
904 assert_eq!(sections, vec![1, 2, 3, 6, 7, 8, 9, 11, 12, 0]);
905 }
906
907 #[test]
908 fn names_section_present() {
909 let mut module = deserialize_file("./res/cases/v1/names.wasm").expect("failed to deserialize");
910
911 assert!(module.names_section().is_none());
913 assert!(module.names_section_mut().is_none());
914 assert!(module.has_names_section());
915
916 let mut module = module.parse_names().expect("failed to parse names section");
918 assert!(module.names_section().is_some());
919 assert!(module.names_section_mut().is_some());
920 assert!(module.has_names_section());
921 }
922
923 #[test]
924 fn names_section_not_present() {
925 let mut module = deserialize_file("./res/cases/v1/test.wasm").expect("failed to deserialize");
926
927 assert!(module.names_section().is_none());
929 assert!(module.names_section_mut().is_none());
930 assert!(!module.has_names_section());
931
932 let mut module = module.parse_names().expect("failed to parse names section");
934 assert!(module.names_section().is_none());
935 assert!(module.names_section_mut().is_none());
936 assert!(!module.has_names_section());
937 }
938
939 #[test]
940 fn insert_sections() {
941 let mut module = Module::default();
942
943 assert!(module.insert_section(Section::Function(FunctionSection::with_entries(vec![]))).is_ok());
944 assert!(module.insert_section(Section::Function(FunctionSection::with_entries(vec![]))).is_err());
946
947 assert!(module.insert_section(Section::Type(TypeSection::with_types(vec![]))).is_ok());
948 assert!(module.insert_section(Section::Type(TypeSection::with_types(vec![]))).is_err());
950
951 assert!(module.insert_section(Section::Export(ExportSection::with_entries(vec![]))).is_ok());
952 assert!(module.insert_section(Section::Export(ExportSection::with_entries(vec![]))).is_err());
954
955 assert!(module.insert_section(Section::Code(CodeSection::with_bodies(vec![]))).is_ok());
956 assert!(module.insert_section(Section::Code(CodeSection::with_bodies(vec![]))).is_err());
958
959 let serialized = serialize(module).expect("serialization to succeed");
961 assert!(deserialize_buffer::<Module>(&serialized).is_ok());
962 }
963
964 #[test]
965 fn serialization_roundtrip() {
966 let module = deserialize_file("./res/cases/v1/test.wasm").expect("failed to deserialize");
967 let module_copy = module.clone().to_bytes().expect("failed to serialize");
968 let module_copy = Module::from_bytes(&module_copy).expect("failed to deserialize");
969 assert_eq!(module, module_copy);
970 }
971}