casper_wasm/elements/
module.rs

1use crate::io;
2use alloc::{borrow::ToOwned, string::String, vec::Vec};
3
4use super::{
5	deserialize_buffer,
6	name_section::NameSection,
7	reloc_section::RelocSection,
8	section::{
9		CodeSection, CustomSection, DataSection, ElementSection, ExportSection, FunctionSection,
10		GlobalSection, ImportSection, MemorySection, Section, TableSection, TypeSection,
11	},
12	serialize, Deserialize, Error, External, Serialize, Uint32,
13};
14
15use core::cmp;
16
17const WASM_MAGIC_NUMBER: [u8; 4] = [0x00, 0x61, 0x73, 0x6d];
18
19/// WebAssembly module
20#[derive(Debug, Clone, PartialEq)]
21pub struct Module {
22	magic: u32,
23	version: u32,
24	sections: Vec<Section>,
25}
26
27#[derive(Debug, Clone, Copy, PartialEq)]
28/// Type of the import entry to count
29pub enum ImportCountType {
30	/// Count functions
31	Function,
32	/// Count globals
33	Global,
34	/// Count tables
35	Table,
36	/// Count memories
37	Memory,
38}
39
40impl Default for Module {
41	fn default() -> Self {
42		Module {
43			magic: u32::from_le_bytes(WASM_MAGIC_NUMBER),
44			version: 1,
45			sections: Vec::with_capacity(16),
46		}
47	}
48}
49
50impl Module {
51	/// New module with sections
52	pub fn new(sections: Vec<Section>) -> Self {
53		Module { sections, ..Default::default() }
54	}
55
56	/// Construct a module from a slice.
57	pub fn from_bytes<T: AsRef<[u8]>>(input: T) -> Result<Self, Error> {
58		deserialize_buffer::<Module>(input.as_ref())
59	}
60
61	/// Serialize a module to a vector.
62	pub fn into_bytes(self) -> Result<Vec<u8>, Error> {
63		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 {
73		self.version
74	}
75
76	/// Sections list.
77	///
78	/// Each known section is optional and may appear at most once.
79	pub fn sections(&self) -> &[Section] {
80		&self.sections
81	}
82
83	/// Sections list (mutable).
84	///
85	/// Each known section is optional and may appear at most once.
86	pub fn sections_mut(&mut self) -> &mut Vec<Section> {
87		&mut self.sections
88	}
89
90	/// Insert a section, in the correct section ordering. This will fail with an error,
91	/// if the section can only appear once.
92	pub fn insert_section(&mut self, section: Section) -> Result<(), Error> {
93		let sections = self.sections_mut();
94
95		// Custom sections can be inserted anywhere. Lets always insert them last here.
96		if section.order() == 0 {
97			sections.push(section);
98			return Ok(());
99		}
100
101		// Check if the section already exists.
102		if sections.iter().any(|s| s.order() == section.order()) {
103			return Err(Error::DuplicatedSections(section.order()));
104		}
105
106		// Assume that the module is already well-ordered.
107		if let Some(pos) = sections.iter().position(|s| section.order() < s.order()) {
108			sections.insert(pos, section);
109		} else {
110			sections.push(section);
111		}
112
113		Ok(())
114	}
115
116	/// Code section reference, if any.
117	pub fn code_section(&self) -> Option<&CodeSection> {
118		for section in self.sections() {
119			if let Section::Code(ref code_section) = *section {
120				return Some(code_section);
121			}
122		}
123		None
124	}
125
126	/// Code section mutable reference, if any.
127	pub fn code_section_mut(&mut self) -> Option<&mut CodeSection> {
128		for section in self.sections_mut() {
129			if let Section::Code(ref mut code_section) = *section {
130				return Some(code_section);
131			}
132		}
133		None
134	}
135
136	/// Types section reference, if any.
137	pub fn type_section(&self) -> Option<&TypeSection> {
138		for section in self.sections() {
139			if let Section::Type(ref type_section) = *section {
140				return Some(type_section);
141			}
142		}
143		None
144	}
145
146	/// Types section mutable reference, if any.
147	pub fn type_section_mut(&mut self) -> Option<&mut TypeSection> {
148		for section in self.sections_mut() {
149			if let Section::Type(ref mut type_section) = *section {
150				return Some(type_section);
151			}
152		}
153		None
154	}
155
156	/// Imports section reference, if any.
157	pub fn import_section(&self) -> Option<&ImportSection> {
158		for section in self.sections() {
159			if let Section::Import(ref import_section) = *section {
160				return Some(import_section);
161			}
162		}
163		None
164	}
165
166	/// Imports section mutable reference, if any.
167	pub fn import_section_mut(&mut self) -> Option<&mut ImportSection> {
168		for section in self.sections_mut() {
169			if let Section::Import(ref mut import_section) = *section {
170				return Some(import_section);
171			}
172		}
173		None
174	}
175
176	/// Globals section reference, if any.
177	pub fn global_section(&self) -> Option<&GlobalSection> {
178		for section in self.sections() {
179			if let Section::Global(ref section) = *section {
180				return Some(section);
181			}
182		}
183		None
184	}
185
186	/// Globals section mutable reference, if any.
187	pub fn global_section_mut(&mut self) -> Option<&mut GlobalSection> {
188		for section in self.sections_mut() {
189			if let Section::Global(ref mut section) = *section {
190				return Some(section);
191			}
192		}
193		None
194	}
195
196	/// Exports section reference, if any.
197	pub fn export_section(&self) -> Option<&ExportSection> {
198		for section in self.sections() {
199			if let Section::Export(ref export_section) = *section {
200				return Some(export_section);
201			}
202		}
203		None
204	}
205
206	/// Exports section mutable reference, if any.
207	pub fn export_section_mut(&mut self) -> Option<&mut ExportSection> {
208		for section in self.sections_mut() {
209			if let Section::Export(ref mut export_section) = *section {
210				return Some(export_section);
211			}
212		}
213		None
214	}
215
216	/// Table section reference, if any.
217	pub fn table_section(&self) -> Option<&TableSection> {
218		for section in self.sections() {
219			if let Section::Table(ref section) = *section {
220				return Some(section);
221			}
222		}
223		None
224	}
225
226	/// Table section mutable reference, if any.
227	pub fn table_section_mut(&mut self) -> Option<&mut TableSection> {
228		for section in self.sections_mut() {
229			if let Section::Table(ref mut section) = *section {
230				return Some(section);
231			}
232		}
233		None
234	}
235
236	/// Data section reference, if any.
237	pub fn data_section(&self) -> Option<&DataSection> {
238		for section in self.sections() {
239			if let Section::Data(ref section) = *section {
240				return Some(section);
241			}
242		}
243		None
244	}
245
246	/// Data section mutable reference, if any.
247	pub fn data_section_mut(&mut self) -> Option<&mut DataSection> {
248		for section in self.sections_mut() {
249			if let Section::Data(ref mut section) = *section {
250				return Some(section);
251			}
252		}
253		None
254	}
255
256	/// Element section reference, if any.
257	pub fn elements_section(&self) -> Option<&ElementSection> {
258		for section in self.sections() {
259			if let Section::Element(ref section) = *section {
260				return Some(section);
261			}
262		}
263		None
264	}
265
266	/// Element section mutable reference, if any.
267	pub fn elements_section_mut(&mut self) -> Option<&mut ElementSection> {
268		for section in self.sections_mut() {
269			if let Section::Element(ref mut section) = *section {
270				return Some(section);
271			}
272		}
273		None
274	}
275
276	/// Memory section reference, if any.
277	pub fn memory_section(&self) -> Option<&MemorySection> {
278		for section in self.sections() {
279			if let Section::Memory(ref section) = *section {
280				return Some(section);
281			}
282		}
283		None
284	}
285
286	/// Memory section mutable reference, if any.
287	pub fn memory_section_mut(&mut self) -> Option<&mut MemorySection> {
288		for section in self.sections_mut() {
289			if let Section::Memory(ref mut section) = *section {
290				return Some(section);
291			}
292		}
293		None
294	}
295
296	/// Functions signatures section reference, if any.
297	pub fn function_section(&self) -> Option<&FunctionSection> {
298		for section in self.sections() {
299			if let Section::Function(ref sect) = *section {
300				return Some(sect);
301			}
302		}
303		None
304	}
305
306	/// Functions signatures section mutable reference, if any.
307	pub fn function_section_mut(&mut self) -> Option<&mut FunctionSection> {
308		for section in self.sections_mut() {
309			if let Section::Function(ref mut sect) = *section {
310				return Some(sect);
311			}
312		}
313		None
314	}
315
316	/// Start section, if any.
317	pub fn start_section(&self) -> Option<u32> {
318		for section in self.sections() {
319			if let Section::Start(sect) = *section {
320				return Some(sect);
321			}
322		}
323		None
324	}
325
326	/// Changes the module's start section.
327	pub fn set_start_section(&mut self, new_start: u32) {
328		for section in self.sections_mut().iter_mut() {
329			if let Section::Start(_sect) = *section {
330				*section = Section::Start(new_start);
331				return;
332			}
333		}
334		// This should not fail, because we update the existing section above.
335		self.insert_section(Section::Start(new_start))
336			.expect("insert_section should not fail");
337	}
338
339	/// Removes the module's start section.
340	pub fn clear_start_section(&mut self) {
341		let sections = self.sections_mut();
342		let mut rmidx = sections.len();
343		for (index, section) in sections.iter_mut().enumerate() {
344			if let Section::Start(_sect) = section {
345				rmidx = index;
346				break;
347			}
348		}
349		if rmidx < sections.len() {
350			sections.remove(rmidx);
351		}
352	}
353
354	/// Returns an iterator over the module's custom sections
355	pub fn custom_sections(&self) -> impl Iterator<Item = &CustomSection> {
356		self.sections()
357			.iter()
358			.filter_map(|s| if let Section::Custom(s) = s { Some(s) } else { None })
359	}
360
361	/// Sets the payload associated with the given custom section, or adds a new custom section,
362	/// as appropriate.
363	pub fn set_custom_section(&mut self, name: impl Into<String>, payload: Vec<u8>) {
364		let name: String = name.into();
365		for section in self.sections_mut() {
366			if let Section::Custom(ref mut sect) = *section {
367				if sect.name() == name {
368					*sect = CustomSection::new(name, payload);
369					return;
370				}
371			}
372		}
373		self.sections_mut().push(Section::Custom(CustomSection::new(name, payload)));
374	}
375
376	/// Removes the given custom section, if it exists.
377	/// Returns the removed section if it existed, or None otherwise.
378	pub fn clear_custom_section(&mut self, name: impl AsRef<str>) -> Option<CustomSection> {
379		let name: &str = name.as_ref();
380
381		let sections = self.sections_mut();
382
383		for i in 0..sections.len() {
384			let mut remove = false;
385			if let Section::Custom(ref sect) = sections[i] {
386				if sect.name() == name {
387					remove = true;
388				}
389			}
390
391			if remove {
392				let removed = sections.remove(i);
393				match removed {
394					Section::Custom(sect) => return Some(sect),
395					_ => unreachable!(), // This is the section we just matched on, so...
396				}
397			}
398		}
399		None
400	}
401
402	/// True if a name section is present.
403	///
404	/// NOTE: this can return true even if the section was not parsed, hence `names_section()` may return `None`
405	///       even if this returns `true`
406	pub fn has_names_section(&self) -> bool {
407		self.sections().iter().any(|e| {
408			match e {
409				// The default case, when the section was not parsed
410				Section::Custom(custom) => custom.name() == "name",
411				// This is the case, when the section was parsed
412				Section::Name(_) => true,
413				_ => false,
414			}
415		})
416	}
417
418	/// Functions signatures section reference, if any.
419	///
420	/// NOTE: name section is not parsed by default so `names_section` could return None even if name section exists.
421	/// Call `parse_names` to parse name section
422	pub fn names_section(&self) -> Option<&NameSection> {
423		for section in self.sections() {
424			if let Section::Name(ref sect) = *section {
425				return Some(sect);
426			}
427		}
428		None
429	}
430
431	/// Functions signatures section mutable reference, if any.
432	///
433	/// NOTE: name section is not parsed by default so `names_section` could return None even if name section exists.
434	/// Call `parse_names` to parse name section
435	pub fn names_section_mut(&mut self) -> Option<&mut NameSection> {
436		for section in self.sections_mut() {
437			if let Section::Name(ref mut sect) = *section {
438				return Some(sect);
439			}
440		}
441		None
442	}
443
444	/// Try to parse name section in place.
445	///
446	/// Corresponding custom section with proper header will convert to name sections
447	/// If some of them will fail to be decoded, Err variant is returned with the list of
448	/// (index, Error) tuples of failed sections.
449	pub fn parse_names(mut self) -> Result<Self, (Vec<(usize, Error)>, Self)> {
450		let mut parse_errors = Vec::new();
451
452		for i in 0..self.sections.len() {
453			if let Some(name_section) = {
454				let section =
455					self.sections.get(i).expect("cannot fail because i in range 0..len; qed");
456				if let Section::Custom(ref custom) = *section {
457					if custom.name() == "name" {
458						let mut rdr = io::Cursor::new(custom.payload());
459						let name_section = match NameSection::deserialize(&self, &mut rdr) {
460							Ok(ns) => ns,
461							Err(e) => {
462								parse_errors.push((i, e));
463								continue;
464							},
465						};
466						Some(name_section)
467					} else {
468						None
469					}
470				} else {
471					None
472				}
473			} {
474				// todo: according to the spec a Wasm binary can contain only one name section
475				*self.sections.get_mut(i).expect("cannot fail because i in range 0..len; qed") =
476					Section::Name(name_section);
477			}
478		}
479
480		if !parse_errors.is_empty() {
481			Err((parse_errors, self))
482		} else {
483			Ok(self)
484		}
485	}
486
487	/// Try to parse reloc section in place.
488	///
489	/// Corresponding custom section with proper header will convert to reloc sections
490	/// If some of them will fail to be decoded, Err variant is returned with the list of
491	/// (index, Error) tuples of failed sections.
492	pub fn parse_reloc(mut self) -> Result<Self, (Vec<(usize, Error)>, Self)> {
493		let mut parse_errors = Vec::new();
494
495		for (i, section) in self.sections.iter_mut().enumerate() {
496			if let Some(relocation_section) = {
497				if let Section::Custom(ref custom) = *section {
498					if custom.name().starts_with("reloc.") {
499						let mut rdr = io::Cursor::new(custom.payload());
500						let reloc_section =
501							match RelocSection::deserialize(custom.name().to_owned(), &mut rdr) {
502								Ok(reloc_section) => reloc_section,
503								Err(e) => {
504									parse_errors.push((i, e));
505									continue;
506								},
507							};
508						if rdr.position() != custom.payload().len() {
509							parse_errors.push((i, io::Error::InvalidData.into()));
510							continue;
511						}
512						Some(Section::Reloc(reloc_section))
513					} else {
514						None
515					}
516				} else {
517					None
518				}
519			} {
520				*section = relocation_section;
521			}
522		}
523
524		if !parse_errors.is_empty() {
525			Err((parse_errors, self))
526		} else {
527			Ok(self)
528		}
529	}
530
531	/// Count imports by provided type.
532	pub fn import_count(&self, count_type: ImportCountType) -> usize {
533		self.import_section()
534			.map(|is| {
535				is.entries()
536					.iter()
537					.filter(|import| {
538						matches!(
539							(count_type, *import.external()),
540							(ImportCountType::Function, External::Function(_)) |
541								(ImportCountType::Global, External::Global(_)) |
542								(ImportCountType::Table, External::Table(_)) |
543								(ImportCountType::Memory, External::Memory(_))
544						)
545					})
546					.count()
547			})
548			.unwrap_or(0)
549	}
550
551	/// Query functions space.
552	pub fn functions_space(&self) -> usize {
553		self.import_count(ImportCountType::Function) +
554			self.function_section().map(|fs| fs.entries().len()).unwrap_or(0)
555	}
556
557	/// Query globals space.
558	pub fn globals_space(&self) -> usize {
559		self.import_count(ImportCountType::Global) +
560			self.global_section().map(|gs| gs.entries().len()).unwrap_or(0)
561	}
562
563	/// Query table space.
564	pub fn table_space(&self) -> usize {
565		self.import_count(ImportCountType::Table) +
566			self.table_section().map(|ts| ts.entries().len()).unwrap_or(0)
567	}
568
569	/// Query memory space.
570	pub fn memory_space(&self) -> usize {
571		self.import_count(ImportCountType::Memory) +
572			self.memory_section().map(|ms| ms.entries().len()).unwrap_or(0)
573	}
574}
575
576impl Deserialize for Module {
577	type Error = super::Error;
578
579	fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
580		let mut sections = Vec::new();
581
582		let mut magic = [0u8; 4];
583		reader.read(&mut magic)?;
584		if magic != WASM_MAGIC_NUMBER {
585			return Err(Error::InvalidMagic);
586		}
587
588		let version: u32 = Uint32::deserialize(reader)?.into();
589
590		if version != 1 {
591			return Err(Error::UnsupportedVersion(version));
592		}
593
594		let mut last_section_order = 0;
595
596		loop {
597			match Section::deserialize(reader) {
598				Err(Error::UnexpectedEof) => break,
599				Err(e) => return Err(e),
600				Ok(section) => {
601					if section.order() != 0 {
602						match last_section_order {
603							x if x > section.order() => return Err(Error::SectionsOutOfOrder),
604							x if x == section.order() =>
605								return Err(Error::DuplicatedSections(last_section_order)),
606							_ => {},
607						};
608
609						last_section_order = section.order();
610					}
611					sections.push(section);
612				},
613			}
614		}
615
616		let module = Module { magic: u32::from_le_bytes(magic), version, sections };
617
618		if module.code_section().map(|cs| cs.bodies().len()).unwrap_or(0) !=
619			module.function_section().map(|fs| fs.entries().len()).unwrap_or(0)
620		{
621			return Err(Error::InconsistentCode);
622		}
623
624		Ok(module)
625	}
626}
627
628impl Serialize for Module {
629	type Error = Error;
630
631	fn serialize<W: io::Write>(self, w: &mut W) -> Result<(), Self::Error> {
632		Uint32::from(self.magic).serialize(w)?;
633		Uint32::from(self.version).serialize(w)?;
634		for section in self.sections.into_iter() {
635			// todo: according to the spec the name section should appear after the data section
636			section.serialize(w)?;
637		}
638		Ok(())
639	}
640}
641
642#[derive(Debug, Copy, Clone, PartialEq)]
643struct PeekSection<'a> {
644	cursor: usize,
645	region: &'a [u8],
646}
647
648impl io::Read for PeekSection<'_> {
649	fn read(&mut self, buf: &mut [u8]) -> io::Result<()> {
650		let available = cmp::min(buf.len(), self.region.len() - self.cursor);
651		if available < buf.len() {
652			return Err(io::Error::UnexpectedEof);
653		}
654
655		let range = self.cursor..self.cursor + buf.len();
656		buf.copy_from_slice(&self.region[range]);
657
658		self.cursor += available;
659		Ok(())
660	}
661}
662
663/// Returns size of the module in the provided stream.
664pub fn peek_size(source: &[u8]) -> usize {
665	if source.len() < 9 {
666		return 0;
667	}
668
669	let mut cursor = 8;
670	loop {
671		let (new_cursor, section_id, section_len) = {
672			let mut peek_section = PeekSection { cursor: 0, region: &source[cursor..] };
673			let section_id: u8 = match super::VarUint7::deserialize(&mut peek_section) {
674				Ok(res) => res.into(),
675				Err(_) => break,
676			};
677			let section_len: u32 = match super::VarUint32::deserialize(&mut peek_section) {
678				Ok(res) => res.into(),
679				Err(_) => break,
680			};
681
682			(peek_section.cursor, section_id, section_len)
683		};
684
685		if section_id <= 11 && section_len > 0 {
686			let next_cursor = cursor + new_cursor + section_len as usize;
687
688			match next_cursor {
689				x if x > source.len() => break,
690				x if x == source.len() => {
691					cursor = next_cursor;
692					break;
693				},
694				_ => {},
695			}
696			cursor = next_cursor;
697		} else {
698			break;
699		}
700	}
701
702	cursor
703}
704
705#[cfg(test)]
706mod integration_tests {
707	#[cfg(feature = "std")]
708	use super::super::deserialize_file;
709	use super::{
710		super::{
711			deserialize_buffer, serialize, CodeSection, ExportSection, FunctionSection, Section,
712			TypeSection,
713		},
714		Module,
715	};
716	use crate::alloc::{string::ToString, vec::Vec};
717
718	#[cfg(feature = "std")]
719	#[test]
720	fn hello() {
721		let module = deserialize_file("./res/cases/v1/hello.wasm").expect("Should be deserialized");
722
723		assert_eq!(module.version(), 1);
724		assert_eq!(module.sections().len(), 8);
725	}
726
727	#[cfg(feature = "std")]
728	#[test]
729	fn serde() {
730		let module = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized");
731		let buf = serialize(module).expect("serialization to succeed");
732
733		let module_new: Module = deserialize_buffer(&buf).expect("deserialization to succeed");
734		let module_old =
735			deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized");
736
737		assert_eq!(module_old.sections().len(), module_new.sections().len());
738	}
739
740	#[cfg(feature = "std")]
741	#[test]
742	fn serde_type() {
743		let mut module =
744			deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized");
745		module.sections_mut().retain(|x| matches!(x, &Section::Type(_)));
746
747		let buf = serialize(module).expect("serialization to succeed");
748
749		let module_new: Module = deserialize_buffer(&buf).expect("deserialization to succeed");
750		let module_old =
751			deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized");
752		assert_eq!(
753			module_old.type_section().expect("type section exists").types().len(),
754			module_new.type_section().expect("type section exists").types().len(),
755			"There should be equal amount of types before and after serialization"
756		);
757	}
758
759	#[cfg(feature = "std")]
760	#[test]
761	fn serde_import() {
762		let mut module =
763			deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized");
764		module.sections_mut().retain(|x| matches!(x, &Section::Import(_)));
765
766		let buf = serialize(module).expect("serialization to succeed");
767
768		let module_new: Module = deserialize_buffer(&buf).expect("deserialization to succeed");
769		let module_old =
770			deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized");
771		assert_eq!(
772			module_old.import_section().expect("import section exists").entries().len(),
773			module_new.import_section().expect("import section exists").entries().len(),
774			"There should be equal amount of import entries before and after serialization"
775		);
776	}
777
778	#[cfg(feature = "std")]
779	#[test]
780	fn serde_code() {
781		let mut module =
782			deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized");
783		module.sections_mut().retain(|x| {
784			if let Section::Code(_) = *x {
785				return true;
786			}
787			matches!(*x, Section::Function(_))
788		});
789
790		let buf = serialize(module).expect("serialization to succeed");
791
792		let module_new: Module = deserialize_buffer(&buf).expect("deserialization to succeed");
793		let module_old =
794			deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized");
795		assert_eq!(
796			module_old.code_section().expect("code section exists").bodies().len(),
797			module_new.code_section().expect("code section exists").bodies().len(),
798			"There should be equal amount of function bodies before and after serialization"
799		);
800	}
801
802	#[cfg(feature = "std")]
803	#[test]
804	fn const_() {
805		use super::super::Instruction::*;
806
807		let module = deserialize_file("./res/cases/v1/const.wasm").expect("Should be deserialized");
808		let func = &module.code_section().expect("Code section to exist").bodies()[0];
809		assert_eq!(func.code().elements().len(), 20);
810
811		assert_eq!(I64Const(9223372036854775807), func.code().elements()[0]);
812		assert_eq!(I64Const(-9223372036854775808), func.code().elements()[1]);
813		assert_eq!(I64Const(-1152894205662152753), func.code().elements()[2]);
814		assert_eq!(I64Const(-8192), func.code().elements()[3]);
815		assert_eq!(I32Const(1024), func.code().elements()[4]);
816		assert_eq!(I32Const(2048), func.code().elements()[5]);
817		assert_eq!(I32Const(4096), func.code().elements()[6]);
818		assert_eq!(I32Const(8192), func.code().elements()[7]);
819		assert_eq!(I32Const(16384), func.code().elements()[8]);
820		assert_eq!(I32Const(32767), func.code().elements()[9]);
821		assert_eq!(I32Const(-1024), func.code().elements()[10]);
822		assert_eq!(I32Const(-2048), func.code().elements()[11]);
823		assert_eq!(I32Const(-4096), func.code().elements()[12]);
824		assert_eq!(I32Const(-8192), func.code().elements()[13]);
825		assert_eq!(I32Const(-16384), func.code().elements()[14]);
826		assert_eq!(I32Const(-32768), func.code().elements()[15]);
827		assert_eq!(I32Const(-2147483648), func.code().elements()[16]);
828		assert_eq!(I32Const(2147483647), func.code().elements()[17]);
829	}
830
831	#[cfg(feature = "std")]
832	#[test]
833	fn store() {
834		use super::super::Instruction::*;
835
836		let module =
837			deserialize_file("./res/cases/v1/offset.wasm").expect("Should be deserialized");
838		let func = &module.code_section().expect("Code section to exist").bodies()[0];
839
840		assert_eq!(func.code().elements().len(), 5);
841		assert_eq!(I64Store(0, 32), func.code().elements()[2]);
842	}
843
844	#[cfg(feature = "std")]
845	#[test]
846	fn peek() {
847		use super::peek_size;
848
849		let module = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized");
850		let mut buf = serialize(module).expect("serialization to succeed");
851
852		buf.extend_from_slice(&[1, 5, 12, 17]);
853
854		assert_eq!(peek_size(&buf), buf.len() - 4);
855	}
856
857	#[cfg(feature = "std")]
858	#[test]
859	fn peek_2() {
860		use super::peek_size;
861
862		let module =
863			deserialize_file("./res/cases/v1/offset.wasm").expect("Should be deserialized");
864		let mut buf = serialize(module).expect("serialization to succeed");
865
866		buf.extend_from_slice(&[0, 0, 0, 0, 0, 1, 5, 12, 17]);
867
868		assert_eq!(peek_size(&buf), buf.len() - 9);
869	}
870
871	#[cfg(feature = "std")]
872	#[test]
873	fn peek_3() {
874		use super::peek_size;
875
876		let module =
877			deserialize_file("./res/cases/v1/peek_sample.wasm").expect("Should be deserialized");
878		let buf = serialize(module).expect("serialization to succeed");
879
880		assert_eq!(peek_size(&buf), buf.len());
881	}
882
883	#[test]
884	fn module_default_round_trip() {
885		let module1 = Module::default();
886		let buf = serialize(module1).expect("Serialization should succeed");
887
888		let module2: Module = deserialize_buffer(&buf).expect("Deserialization should succeed");
889		assert_eq!(Module::default().magic, module2.magic);
890	}
891
892	#[cfg(feature = "std")]
893	#[test]
894	fn names() {
895		let module = deserialize_file("./res/cases/v1/with_names.wasm")
896			.expect("Should be deserialized")
897			.parse_names()
898			.expect("Names to be parsed");
899
900		let mut found_section = false;
901		for section in module.sections() {
902			if let Section::Name(ref name_section) = *section {
903				let function_name_subsection =
904					name_section.functions().expect("function_name_subsection should be present");
905				assert_eq!(
906					function_name_subsection.names().get(0).expect("Should be entry #0"),
907					"elog"
908				);
909				assert_eq!(
910					function_name_subsection.names().get(11).expect("Should be entry #0"),
911					"_ZN48_$LT$pwasm_token_contract..Endpoint$LT$T$GT$$GT$3new17hc3ace6dea0978cd9E"
912				);
913
914				found_section = true;
915			}
916		}
917
918		assert!(found_section, "Name section should be present in dedicated example");
919	}
920
921	#[cfg(feature = "std")]
922	#[test]
923	fn names_with_global_section() {
924		let module = deserialize_file("./res/cases/v1/global_section.wasm")
925			.expect("Should be deserialized")
926			.parse_names()
927			.expect("Names to be parsed");
928
929		let mut found_section = false;
930		for section in module.sections() {
931			if let Section::Name(ref name_section) = *section {
932				let function_name_subsection =
933					name_section.functions().expect("function_name_subsection should be present");
934				assert_eq!(
935					function_name_subsection.names().get(0).expect("Should be entry #0"),
936					"~lib/builtins/abort"
937				);
938				assert_eq!(
939					function_name_subsection.names().get(11).expect("Should be entry #0"),
940					"~lib/typedarray/Uint8Array#__set"
941				);
942
943				found_section = true;
944			}
945		}
946
947		assert!(found_section, "Name section should be present in dedicated example");
948	}
949
950	// This test fixture has FLAG_SHARED so it depends on atomics feature.
951	#[cfg(feature = "std")]
952	#[test]
953	fn shared_memory_flag() {
954		let module = deserialize_file("./res/cases/v1/varuint1_1.wasm");
955		assert_eq!(module.is_ok(), cfg!(feature = "atomics"));
956	}
957
958	#[cfg(feature = "std")]
959	#[test]
960	fn memory_space() {
961		let module =
962			deserialize_file("./res/cases/v1/two-mems.wasm").expect("failed to deserialize");
963		assert_eq!(module.memory_space(), 2);
964	}
965
966	#[cfg(feature = "std")]
967	#[test]
968	fn add_custom_section() {
969		let mut module =
970			deserialize_file("./res/cases/v1/start_mut.wasm").expect("failed to deserialize");
971		assert!(module.custom_sections().next().is_none());
972		module.set_custom_section("mycustomsection".to_string(), vec![1, 2, 3, 4]);
973		{
974			let sections = module.custom_sections().collect::<Vec<_>>();
975			assert_eq!(sections.len(), 1);
976			assert_eq!(sections[0].name(), "mycustomsection");
977			assert_eq!(sections[0].payload(), &[1, 2, 3, 4]);
978		}
979
980		let old_section = module.clear_custom_section("mycustomsection");
981		assert_eq!(old_section.expect("Did not find custom section").payload(), &[1, 2, 3, 4]);
982
983		assert!(module.custom_sections().next().is_none());
984	}
985
986	#[cfg(feature = "std")]
987	#[test]
988	fn mut_start() {
989		let mut module =
990			deserialize_file("./res/cases/v1/start_mut.wasm").expect("failed to deserialize");
991		assert_eq!(module.start_section().expect("Did not find any start section"), 1);
992		module.set_start_section(0);
993		assert_eq!(module.start_section().expect("Did not find any start section"), 0);
994		module.clear_start_section();
995		assert_eq!(None, module.start_section());
996	}
997
998	#[cfg(feature = "std")]
999	#[test]
1000	fn add_start() {
1001		let mut module =
1002			deserialize_file("./res/cases/v1/start_add.wasm").expect("failed to deserialize");
1003		assert!(module.start_section().is_none());
1004		module.set_start_section(0);
1005		assert_eq!(module.start_section().expect("Did not find any start section"), 0);
1006
1007		let sections = module.sections().iter().map(|s| s.order()).collect::<Vec<_>>();
1008		assert_eq!(sections, vec![1, 2, 3, 6, 7, 8, 9, 11, 12]);
1009	}
1010
1011	#[cfg(feature = "std")]
1012	#[test]
1013	fn add_start_custom() {
1014		let mut module = deserialize_file("./res/cases/v1/start_add_custom.wasm")
1015			.expect("failed to deserialize");
1016
1017		let sections = module.sections().iter().map(|s| s.order()).collect::<Vec<_>>();
1018		assert_eq!(sections, vec![1, 2, 3, 6, 7, 9, 11, 12, 0]);
1019
1020		assert!(module.start_section().is_none());
1021		module.set_start_section(0);
1022		assert_eq!(module.start_section().expect("Dorder not find any start section"), 0);
1023
1024		let sections = module.sections().iter().map(|s| s.order()).collect::<Vec<_>>();
1025		assert_eq!(sections, vec![1, 2, 3, 6, 7, 8, 9, 11, 12, 0]);
1026	}
1027
1028	#[cfg(feature = "std")]
1029	#[test]
1030	fn names_section_present() {
1031		let mut module =
1032			deserialize_file("./res/cases/v1/names.wasm").expect("failed to deserialize");
1033
1034		// Before parsing
1035		assert!(module.names_section().is_none());
1036		assert!(module.names_section_mut().is_none());
1037		assert!(module.has_names_section());
1038
1039		// After parsing
1040		let mut module = module.parse_names().expect("failed to parse names section");
1041		assert!(module.names_section().is_some());
1042		assert!(module.names_section_mut().is_some());
1043		assert!(module.has_names_section());
1044	}
1045
1046	#[cfg(feature = "std")]
1047	#[test]
1048	fn names_section_not_present() {
1049		let mut module =
1050			deserialize_file("./res/cases/v1/test.wasm").expect("failed to deserialize");
1051
1052		// Before parsing
1053		assert!(module.names_section().is_none());
1054		assert!(module.names_section_mut().is_none());
1055		assert!(!module.has_names_section());
1056
1057		// After parsing
1058		let mut module = module.parse_names().expect("failed to parse names section");
1059		assert!(module.names_section().is_none());
1060		assert!(module.names_section_mut().is_none());
1061		assert!(!module.has_names_section());
1062	}
1063
1064	#[test]
1065	fn insert_sections() {
1066		let mut module = Module::default();
1067
1068		assert!(module
1069			.insert_section(Section::Function(FunctionSection::with_entries(vec![])))
1070			.is_ok());
1071		// Duplicate.
1072		assert!(module
1073			.insert_section(Section::Function(FunctionSection::with_entries(vec![])))
1074			.is_err());
1075
1076		assert!(module.insert_section(Section::Type(TypeSection::with_types(vec![]))).is_ok());
1077		// Duplicate.
1078		assert!(module.insert_section(Section::Type(TypeSection::with_types(vec![]))).is_err());
1079
1080		assert!(module
1081			.insert_section(Section::Export(ExportSection::with_entries(vec![])))
1082			.is_ok());
1083		// Duplicate.
1084		assert!(module
1085			.insert_section(Section::Export(ExportSection::with_entries(vec![])))
1086			.is_err());
1087
1088		assert!(module.insert_section(Section::Code(CodeSection::with_bodies(vec![]))).is_ok());
1089		// Duplicate.
1090		assert!(module.insert_section(Section::Code(CodeSection::with_bodies(vec![]))).is_err());
1091
1092		// Try serialisation roundtrip to check well-orderedness.
1093		let serialized = serialize(module).expect("serialization to succeed");
1094		assert!(deserialize_buffer::<Module>(&serialized).is_ok());
1095	}
1096
1097	#[cfg(feature = "std")]
1098	#[test]
1099	fn serialization_roundtrip() {
1100		let module = deserialize_file("./res/cases/v1/test.wasm").expect("failed to deserialize");
1101		let module_copy = module.clone().into_bytes().expect("failed to serialize");
1102		let module_copy = Module::from_bytes(&module_copy).expect("failed to deserialize");
1103		assert_eq!(module, module_copy);
1104	}
1105}