tetsy_wasm/elements/
module.rs

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/// WebAssembly module
18#[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)]
26/// Type of the import entry to count
27pub enum ImportCountType {
28	/// Count functions
29	Function,
30	/// Count globals
31	Global,
32	/// Count tables
33	Table,
34	/// Count memories
35	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	/// New module with sections
50	pub fn new(sections: Vec<Section>) -> Self {
51		Module {
52			sections: sections, ..Default::default()
53		}
54	}
55
56	/// Construct a module from a slice.
57	pub fn from_bytes<T: AsRef<[u8]>>(input: T) -> Result<Self, Error> {
58		Ok(deserialize_buffer::<Module>(input.as_ref())?)
59	}
60
61	/// Serialize a module to a vector.
62	pub fn to_bytes(self) -> Result<Vec<u8>, Error> {
63		Ok(serialize::<Module>(self)?)
64	}
65
66	/// Destructure the module, yielding sections
67	pub fn into_sections(self) -> Vec<Section> {
68		self.sections
69	}
70
71	/// Version of module.
72	pub fn version(&self) -> u32 { self.version }
73
74	/// Sections list.
75	///
76	/// Each known section is optional and may appear at most once.
77	pub fn sections(&self) -> &[Section] {
78		&self.sections
79	}
80
81	/// Sections list (mutable).
82	///
83	/// Each known section is optional and may appear at most once.
84	pub fn sections_mut(&mut self) -> &mut Vec<Section> {
85		&mut self.sections
86	}
87
88	/// Insert a section, in the correct section ordering. This will fail with an error,
89	/// if the section can only appear once.
90	pub fn insert_section(&mut self, section: Section) -> Result<(), Error> {
91		let sections = self.sections_mut();
92
93		// Custom sections can be inserted anywhere. Lets always insert them last here.
94		if section.order() == 0 {
95			sections.push(section);
96			return Ok(());
97		}
98
99		// Check if the section already exists.
100		if sections.iter().position(|s| s.order() == section.order()).is_some() {
101			return Err(Error::DuplicatedSections(section.order()));
102		}
103
104		// Assume that the module is already well-ordered.
105		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	/// Code section reference, if any.
115	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	/// Code section mutable reference, if any.
123	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	/// Types section reference, if any.
131	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	/// Types section mutable reference, if any.
139	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	/// Imports section reference, if any.
147	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	/// Imports section mutable reference, if any.
155	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	/// Globals section reference, if any.
163	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		/// Globals section mutable reference, if any.
171	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	/// Exports section reference, if any.
180	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	/// Exports section mutable reference, if any.
188	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	/// Table section reference, if any.
196	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	/// Table section mutable reference, if any.
204	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	/// Data section reference, if any.
212	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	/// Data section mutable reference, if any.
220	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	/// Element section reference, if any.
228	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	/// Element section mutable reference, if any.
236	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	/// Memory section reference, if any.
244	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	/// Memory section mutable reference, if any.
252	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	/// Functions signatures section reference, if any.
260	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	/// Functions signatures section mutable reference, if any.
268	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	/// Start section, if any.
276	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	/// Changes the module's start section.
284	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		// This should not fail, because we update the existing section above.
292		self.insert_section(Section::Start(new_start)).expect("insert_section should not fail");
293	}
294
295	/// Removes the module's start section.
296	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	/// Returns an iterator over the module's custom sections
311	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	/// Sets the payload associated with the given custom section, or adds a new custom section,
322	/// as appropriate.
323	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	/// Removes the given custom section, if it exists.
337	/// Returns the removed section if it existed, or None otherwise.
338	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!(), // This is the section we just matched on, so...
356				}
357			}
358		}
359		None
360	}
361
362	/// True if a name section is present.
363	///
364	/// NOTE: this can return true even if the section was not parsed, hence `names_section()` may return `None`
365	///       even if this returns `true`
366	pub fn has_names_section(&self) -> bool {
367		self.sections().iter().any(|e| {
368			match e {
369				// The default case, when the section was not parsed
370				Section::Custom(custom) => custom.name() == "name",
371				// This is the case, when the section was parsed
372				Section::Name(_) => true,
373				_ => false,
374			}
375		})
376	}
377
378	/// Functions signatures section reference, if any.
379	///
380	/// NOTE: name section is not parsed by default so `names_section` could return None even if name section exists.
381	/// Call `parse_names` to parse name section
382	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	/// Functions signatures section mutable reference, if any.
390	///
391	/// NOTE: name section is not parsed by default so `names_section` could return None even if name section exists.
392	/// Call `parse_names` to parse name section
393	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	/// Try to parse name section in place.
401	///
402	/// Corresponding custom section with proper header will convert to name sections
403	/// If some of them will fail to be decoded, Err variant is returned with the list of
404	/// (index, Error) tuples of failed sections.
405	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				// todo: according to the spec a Wasm binary can contain only one name section
425				*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	/// Try to parse reloc section in place.
437	///
438	/// Corresponding custom section with proper header will convert to reloc sections
439	/// If some of them will fail to be decoded, Err variant is returned with the list of
440	/// (index, Error) tuples of failed sections.
441	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	/// Count imports by provided type.
479	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	/// Query functions space.
493	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	/// Query globals space.
499	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	/// Query table space.
505	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	/// Query memory space.
511	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			// todo: according to the spec the name section should appear after the data section
579			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
606/// Returns size of the module in the provided stream.
607pub 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	// This test fixture has FLAG_SHARED so it depends on atomics feature.
840	#[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        // Before parsing
912        assert!(module.names_section().is_none());
913        assert!(module.names_section_mut().is_none());
914        assert!(module.has_names_section());
915
916        // After parsing
917        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        // Before parsing
928        assert!(module.names_section().is_none());
929        assert!(module.names_section_mut().is_none());
930        assert!(!module.has_names_section());
931
932        // After parsing
933        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        // Duplicate.
945        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        // Duplicate.
949        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        // Duplicate.
953        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        // Duplicate.
957        assert!(module.insert_section(Section::Code(CodeSection::with_bodies(vec![]))).is_err());
958
959        // Try serialisation roundtrip to check well-orderedness.
960        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}