tetsy_wasm/elements/
section.rs

1use alloc::{vec::Vec, borrow::ToOwned, string::String};
2use crate::{io, elements};
3use super::{
4	Serialize,
5	Deserialize,
6	Error,
7	VarUint7,
8	VarUint32,
9	CountedList,
10	ImportEntry,
11	MemoryType,
12	TableType,
13	ExportEntry,
14	GlobalEntry,
15	Func,
16	FuncBody,
17	ElementSegment,
18	DataSegment,
19	CountedWriter,
20	CountedListWriter,
21	External,
22	serialize,
23};
24
25use super::types::Type;
26use super::name_section::NameSection;
27use super::reloc_section::RelocSection;
28
29const ENTRIES_BUFFER_LENGTH: usize = 16384;
30
31/// Section in the WebAssembly module.
32#[derive(Debug, Clone, PartialEq)]
33pub enum Section {
34	/// Section is unparsed.
35	Unparsed {
36		/// id of the unparsed section.
37		id: u8,
38		/// raw bytes of the unparsed section.
39		payload: Vec<u8>,
40	},
41	/// Custom section (`id=0`).
42	Custom(CustomSection),
43	/// Types section.
44	Type(TypeSection),
45	/// Import section.
46	Import(ImportSection),
47	/// Function signatures section.
48	Function(FunctionSection),
49	/// Table definition section.
50	Table(TableSection),
51	/// Memory definition section.
52	Memory(MemorySection),
53	/// Global entries section.
54	Global(GlobalSection),
55	/// Export definitions.
56	Export(ExportSection),
57	/// Entry reference of the module.
58	Start(u32),
59	/// Elements section.
60	Element(ElementSection),
61	/// Number of passive data entries in the data section
62	DataCount(u32),
63	/// Function bodies section.
64	Code(CodeSection),
65	/// Data definition section.
66	Data(DataSection),
67	/// Name section.
68	///
69	/// Note that initially it is not parsed until `parse_names` is called explicitly.
70	Name(NameSection),
71	/// Relocation section.
72	///
73	/// Note that initially it is not parsed until `parse_reloc` is called explicitly.
74	/// Also note that currently there are serialization (but not de-serialization)
75	///   issues with this section (#198).
76	Reloc(RelocSection),
77}
78
79impl Deserialize for Section {
80	type Error = Error;
81
82	fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
83		let id = match VarUint7::deserialize(reader) {
84			// todo: be more selective detecting no more section
85			Err(_) => { return Err(Error::UnexpectedEof); },
86			Ok(id) => id,
87		};
88
89		Ok(
90			match id.into() {
91				0 => {
92					Section::Custom(CustomSection::deserialize(reader)?.into())
93				},
94				1 => {
95					Section::Type(TypeSection::deserialize(reader)?)
96				},
97				2 => {
98					Section::Import(ImportSection::deserialize(reader)?)
99				},
100				3 => {
101					Section::Function(FunctionSection::deserialize(reader)?)
102				},
103				4 => {
104					Section::Table(TableSection::deserialize(reader)?)
105				},
106				5 => {
107					Section::Memory(MemorySection::deserialize(reader)?)
108				},
109				6 => {
110					Section::Global(GlobalSection::deserialize(reader)?)
111				},
112				7 => {
113					Section::Export(ExportSection::deserialize(reader)?)
114				},
115				8 => {
116					let mut section_reader = SectionReader::new(reader)?;
117					let start_idx = VarUint32::deserialize(&mut section_reader)?;
118					section_reader.close()?;
119					Section::Start(start_idx.into())
120				},
121				9 => {
122					Section::Element(ElementSection::deserialize(reader)?)
123				},
124				10 => {
125					Section::Code(CodeSection::deserialize(reader)?)
126				},
127				11 => {
128					Section::Data(DataSection::deserialize(reader)?)
129				},
130				12 => {
131					let mut section_reader = SectionReader::new(reader)?;
132					let count = VarUint32::deserialize(&mut section_reader)?;
133					section_reader.close()?;
134					Section::DataCount(count.into())
135				},
136				invalid_id => {
137					return Err(Error::InvalidSectionId(invalid_id))
138				},
139			}
140		)
141	}
142}
143
144impl Serialize for Section {
145	type Error = Error;
146
147	fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
148		match self {
149			Section::Custom(custom_section) => {
150				VarUint7::from(0x00).serialize(writer)?;
151				custom_section.serialize(writer)?;
152			},
153			Section::Unparsed { id, payload } => {
154				VarUint7::from(id).serialize(writer)?;
155				writer.write(&payload[..])?;
156			},
157			Section::Type(type_section) => {
158				VarUint7::from(0x01).serialize(writer)?;
159				type_section.serialize(writer)?;
160			},
161			Section::Import(import_section) => {
162				VarUint7::from(0x02).serialize(writer)?;
163				import_section.serialize(writer)?;
164			},
165			Section::Function(function_section) => {
166				VarUint7::from(0x03).serialize(writer)?;
167				function_section.serialize(writer)?;
168			},
169			Section::Table(table_section) => {
170				VarUint7::from(0x04).serialize(writer)?;
171				table_section.serialize(writer)?;
172			},
173			Section::Memory(memory_section) => {
174				VarUint7::from(0x05).serialize(writer)?;
175				memory_section.serialize(writer)?;
176			},
177			Section::Global(global_section) => {
178				VarUint7::from(0x06).serialize(writer)?;
179				global_section.serialize(writer)?;
180			},
181			Section::Export(export_section) => {
182				VarUint7::from(0x07).serialize(writer)?;
183				export_section.serialize(writer)?;
184			},
185			Section::Start(index) => {
186				VarUint7::from(0x08).serialize(writer)?;
187				let mut counted_writer = CountedWriter::new(writer);
188				VarUint32::from(index).serialize(&mut counted_writer)?;
189				counted_writer.done()?;
190			},
191			Section::DataCount(count) => {
192				VarUint7::from(0x0c).serialize(writer)?;
193				let mut counted_writer = CountedWriter::new(writer);
194				VarUint32::from(count).serialize(&mut counted_writer)?;
195				counted_writer.done()?;
196			},
197			Section::Element(element_section) => {
198				VarUint7::from(0x09).serialize(writer)?;
199				element_section.serialize(writer)?;
200			},
201			Section::Code(code_section) => {
202				VarUint7::from(0x0a).serialize(writer)?;
203				code_section.serialize(writer)?;
204			},
205			Section::Data(data_section) => {
206				VarUint7::from(0x0b).serialize(writer)?;
207				data_section.serialize(writer)?;
208			},
209			Section::Name(name_section) => {
210				VarUint7::from(0x00).serialize(writer)?;
211				let custom = CustomSection {
212					name: "name".to_owned(),
213					payload: serialize(name_section)?,
214				};
215				custom.serialize(writer)?;
216			},
217			Section::Reloc(reloc_section) => {
218				VarUint7::from(0x00).serialize(writer)?;
219				reloc_section.serialize(writer)?;
220			},
221		}
222		Ok(())
223	}
224}
225
226impl Section {
227	pub(crate) fn order(&self) -> u8 {
228		match *self {
229			Section::Custom(_) => 0x00,
230			Section::Unparsed { .. } => 0x00,
231			Section::Type(_) => 0x1,
232			Section::Import(_) => 0x2,
233			Section::Function(_) => 0x3,
234			Section::Table(_) => 0x4,
235			Section::Memory(_) => 0x5,
236			Section::Global(_) => 0x6,
237			Section::Export(_) => 0x7,
238			Section::Start(_) => 0x8,
239			Section::Element(_) => 0x9,
240			Section::DataCount(_) => 0x0a,
241			Section::Code(_) => 0x0b,
242			Section::Data(_) => 0x0c,
243			Section::Name(_) => 0x00,
244			Section::Reloc(_) => 0x00,
245		}
246	}
247}
248
249pub(crate) struct SectionReader {
250	cursor: io::Cursor<Vec<u8>>,
251	declared_length: usize,
252}
253
254impl SectionReader {
255	pub fn new<R: io::Read>(reader: &mut R) -> Result<Self, elements::Error> {
256		let length = u32::from(VarUint32::deserialize(reader)?) as usize;
257		let inner_buffer = buffered_read!(ENTRIES_BUFFER_LENGTH, length, reader);
258		let buf_length = inner_buffer.len();
259		let cursor = io::Cursor::new(inner_buffer);
260
261		Ok(SectionReader {
262			cursor: cursor,
263			declared_length: buf_length,
264		})
265	}
266
267	pub fn close(self) -> Result<(), io::Error> {
268		let cursor = self.cursor;
269		let buf_length = self.declared_length;
270
271		if cursor.position() != buf_length {
272			Err(io::Error::InvalidData)
273		} else {
274			Ok(())
275		}
276	}
277}
278
279impl io::Read for SectionReader {
280    fn read(&mut self, buf: &mut [u8]) -> io::Result<()> {
281		self.cursor.read(buf)?;
282		Ok(())
283	}
284}
285
286fn read_entries<R: io::Read, T: Deserialize<Error=elements::Error>>(reader: &mut R)
287	-> Result<Vec<T>, elements::Error>
288{
289	let mut section_reader = SectionReader::new(reader)?;
290	let result = CountedList::<T>::deserialize(&mut section_reader)?.into_inner();
291	section_reader.close()?;
292	Ok(result)
293}
294
295/// Custom section.
296#[derive(Debug, Default, Clone, PartialEq)]
297pub struct CustomSection {
298	name: String,
299	payload: Vec<u8>,
300}
301
302impl CustomSection {
303	/// Creates a new custom section with the given name and payload.
304	pub fn new(name: String, payload: Vec<u8>) -> CustomSection {
305		CustomSection { name, payload }
306	}
307
308	/// Name of the custom section.
309	pub fn name(&self) -> &str {
310		&self.name
311	}
312
313	/// Payload of the custom section.
314	pub fn payload(&self) -> &[u8] {
315		&self.payload
316	}
317
318	/// Name of the custom section (mutable).
319	pub fn name_mut(&mut self) -> &mut String {
320		&mut self.name
321	}
322
323	/// Payload of the custom section (mutable).
324	pub fn payload_mut(&mut self) -> &mut Vec<u8> {
325		&mut self.payload
326	}
327}
328
329impl Deserialize for CustomSection {
330	type Error = Error;
331
332	fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
333		let section_length: usize = u32::from(VarUint32::deserialize(reader)?) as usize;
334		let buf = buffered_read!(16384, section_length, reader);
335		let mut cursor = io::Cursor::new(&buf[..]);
336		let name = String::deserialize(&mut cursor)?;
337		let payload = buf[cursor.position() as usize..].to_vec();
338		Ok(CustomSection { name: name, payload: payload })
339	}
340}
341
342impl Serialize for CustomSection {
343	type Error = Error;
344
345	fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
346		use io::Write;
347
348		let mut counted_writer = CountedWriter::new(writer);
349		self.name.serialize(&mut counted_writer)?;
350		counted_writer.write(&self.payload[..])?;
351		counted_writer.done()?;
352		Ok(())
353	}
354}
355
356/// Section with type declarations.
357#[derive(Debug, Default, Clone, PartialEq)]
358pub struct TypeSection(Vec<Type>);
359
360impl TypeSection {
361	///  New type section with provided types.
362	pub fn with_types(types: Vec<Type>) -> Self {
363		TypeSection(types)
364	}
365
366	/// List of type declarations.
367	pub fn types(&self) -> &[Type] {
368		&self.0
369	}
370
371	/// List of type declarations (mutable).
372	pub fn types_mut(&mut self) -> &mut Vec<Type> {
373		&mut self.0
374	}
375}
376
377impl Deserialize for TypeSection {
378	type Error = Error;
379
380	fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
381		Ok(TypeSection(read_entries(reader)?))
382	}
383}
384
385impl Serialize for TypeSection {
386	type Error = Error;
387
388	fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
389		let mut counted_writer = CountedWriter::new(writer);
390		let data = self.0;
391		let counted_list = CountedListWriter::<Type, _>(
392			data.len(),
393			data.into_iter().map(Into::into),
394		);
395		counted_list.serialize(&mut counted_writer)?;
396		counted_writer.done()?;
397		Ok(())
398	}
399}
400
401/// Section of the imports definition.
402#[derive(Debug, Default, Clone, PartialEq)]
403pub struct ImportSection(Vec<ImportEntry>);
404
405impl ImportSection {
406	///  New import section with provided types.
407	pub fn with_entries(entries: Vec<ImportEntry>) -> Self {
408		ImportSection(entries)
409	}
410
411	/// List of import entries.
412	pub fn entries(&self) -> &[ImportEntry] {
413		&self.0
414	}
415
416	/// List of import entries (mutable).
417	pub fn entries_mut(&mut self) -> &mut Vec<ImportEntry> {
418		&mut self.0
419	}
420
421	/// Returns number of functions.
422	pub fn functions(&self) -> usize {
423		self.0.iter()
424			.filter(|entry| match entry.external() { &External::Function(_) => true, _ => false })
425			.count()
426	}
427
428	/// Returns number of globals
429	pub fn globals(&self) -> usize {
430		self.0.iter()
431			.filter(|entry| match entry.external() { &External::Global(_) => true, _ => false })
432			.count()
433	}
434}
435
436impl Deserialize for ImportSection {
437	type Error = Error;
438
439	fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
440		Ok(ImportSection(read_entries(reader)?))
441	}
442}
443
444impl Serialize for ImportSection {
445	type Error = Error;
446
447	fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
448		let mut counted_writer = CountedWriter::new(writer);
449		let data = self.0;
450		let counted_list = CountedListWriter::<ImportEntry, _>(
451			data.len(),
452			data.into_iter().map(Into::into),
453		);
454		counted_list.serialize(&mut counted_writer)?;
455		counted_writer.done()?;
456		Ok(())
457	}
458}
459
460/// Section with function signatures definition.
461#[derive(Default, Debug, Clone, PartialEq)]
462pub struct FunctionSection(Vec<Func>);
463
464impl FunctionSection {
465	///  New function signatures section with provided entries.
466	pub fn with_entries(entries: Vec<Func>) -> Self {
467		FunctionSection(entries)
468	}
469
470	/// List of all functions in the section, mutable.
471	pub fn entries_mut(&mut self) -> &mut Vec<Func> {
472		&mut self.0
473	}
474
475	/// List of all functions in the section.
476	pub fn entries(&self) -> &[Func] {
477		&self.0
478	}
479}
480
481impl Deserialize for FunctionSection {
482	type Error = Error;
483
484	fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
485		Ok(FunctionSection(read_entries(reader)?))
486	}
487}
488
489impl Serialize for FunctionSection {
490	type Error = Error;
491
492	fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
493		let mut counted_writer = CountedWriter::new(writer);
494		let data = self.0;
495		let counted_list = CountedListWriter::<VarUint32, _>(
496			data.len(),
497			data.into_iter().map(|func| func.type_ref().into())
498		);
499		counted_list.serialize(&mut counted_writer)?;
500		counted_writer.done()?;
501		Ok(())
502	}
503}
504
505/// Section with table definition (currently only one is allowed).
506#[derive(Default, Debug, Clone, PartialEq)]
507pub struct TableSection(Vec<TableType>);
508
509impl TableSection {
510	/// Table entries.
511	pub fn entries(&self) -> &[TableType] {
512		&self.0
513	}
514
515	///  New table section with provided table entries.
516	pub fn with_entries(entries: Vec<TableType>) -> Self {
517		TableSection(entries)
518	}
519
520	/// Mutable table entries.
521	pub fn entries_mut(&mut self) -> &mut Vec<TableType> {
522		&mut self.0
523	}
524}
525
526impl Deserialize for TableSection {
527	type Error = Error;
528
529	fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
530		Ok(TableSection(read_entries(reader)?))
531	}
532}
533
534impl Serialize for TableSection {
535	type Error = Error;
536
537	fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
538		let mut counted_writer = CountedWriter::new(writer);
539		let data = self.0;
540		let counted_list = CountedListWriter::<TableType, _>(
541			data.len(),
542			data.into_iter().map(Into::into),
543		);
544		counted_list.serialize(&mut counted_writer)?;
545		counted_writer.done()?;
546		Ok(())
547	}
548}
549
550/// Section with table definition (currently only one entry is allowed).
551#[derive(Default, Debug, Clone, PartialEq)]
552pub struct MemorySection(Vec<MemoryType>);
553
554impl MemorySection {
555	/// List of all memory entries in the section
556	pub fn entries(&self) -> &[MemoryType] {
557		&self.0
558	}
559
560	///  New memory section with memory types.
561	pub fn with_entries(entries: Vec<MemoryType>) -> Self {
562		MemorySection(entries)
563	}
564
565	/// Mutable list of all memory entries in the section.
566	pub fn entries_mut(&mut self) -> &mut Vec<MemoryType> {
567		&mut self.0
568	}
569}
570
571impl Deserialize for MemorySection {
572	type Error = Error;
573
574	fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
575		Ok(MemorySection(read_entries(reader)?))
576	}
577}
578
579impl Serialize for MemorySection {
580	type Error = Error;
581
582	fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
583		let mut counted_writer = CountedWriter::new(writer);
584		let data = self.0;
585		let counted_list = CountedListWriter::<MemoryType, _>(
586			data.len(),
587			data.into_iter().map(Into::into),
588		);
589		counted_list.serialize(&mut counted_writer)?;
590		counted_writer.done()?;
591		Ok(())
592	}
593}
594
595/// Globals definition section.
596#[derive(Default, Debug, Clone, PartialEq)]
597pub struct GlobalSection(Vec<GlobalEntry>);
598
599impl GlobalSection {
600	/// List of all global entries in the section.
601	pub fn entries(&self) -> &[GlobalEntry] {
602		&self.0
603	}
604
605	/// New global section from list of global entries.
606	pub fn with_entries(entries: Vec<GlobalEntry>) -> Self {
607		GlobalSection(entries)
608	}
609
610	/// List of all global entries in the section (mutable).
611	pub fn entries_mut(&mut self) -> &mut Vec<GlobalEntry> {
612		&mut self.0
613	}
614}
615
616impl Deserialize for GlobalSection {
617	type Error = Error;
618
619	fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
620		Ok(GlobalSection(read_entries(reader)?))
621	}
622}
623
624impl Serialize for GlobalSection {
625	type Error = Error;
626
627	fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
628		let mut counted_writer = CountedWriter::new(writer);
629		let data = self.0;
630		let counted_list = CountedListWriter::<GlobalEntry, _>(
631			data.len(),
632			data.into_iter().map(Into::into),
633		);
634		counted_list.serialize(&mut counted_writer)?;
635		counted_writer.done()?;
636		Ok(())
637	}
638}
639
640/// List of exports definition.
641#[derive(Debug, Default, Clone, PartialEq)]
642pub struct ExportSection(Vec<ExportEntry>);
643
644impl ExportSection {
645	/// List of all export entries in the section.
646	pub fn entries(&self) -> &[ExportEntry] {
647		&self.0
648	}
649
650	/// New export section from list of export entries.
651	pub fn with_entries(entries: Vec<ExportEntry>) -> Self {
652		ExportSection(entries)
653	}
654
655	/// List of all export entries in the section (mutable).
656	pub fn entries_mut(&mut self) -> &mut Vec<ExportEntry> {
657		&mut self.0
658	}
659}
660
661impl Deserialize for ExportSection {
662	type Error = Error;
663
664	fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
665		Ok(ExportSection(read_entries(reader)?))
666	}
667}
668
669impl Serialize for ExportSection {
670	type Error = Error;
671
672	fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
673		let mut counted_writer = CountedWriter::new(writer);
674		let data = self.0;
675		let counted_list = CountedListWriter::<ExportEntry, _>(
676			data.len(),
677			data.into_iter().map(Into::into),
678		);
679		counted_list.serialize(&mut counted_writer)?;
680		counted_writer.done()?;
681		Ok(())
682	}
683}
684
685/// Section with function bodies of the module.
686#[derive(Default, Debug, Clone, PartialEq)]
687pub struct CodeSection(Vec<FuncBody>);
688
689impl CodeSection {
690	/// New code section with specified function bodies.
691	pub fn with_bodies(bodies: Vec<FuncBody>) -> Self {
692		CodeSection(bodies)
693	}
694
695	/// All function bodies in the section.
696	pub fn bodies(&self) -> &[FuncBody] {
697		&self.0
698	}
699
700	/// All function bodies in the section, mutable.
701	pub fn bodies_mut(&mut self) -> &mut Vec<FuncBody> {
702		&mut self.0
703	}
704}
705
706impl Deserialize for CodeSection {
707	type Error = Error;
708
709	fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
710		Ok(CodeSection(read_entries(reader)?))
711	}
712}
713
714impl Serialize for CodeSection {
715	type Error = Error;
716
717	fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
718		let mut counted_writer = CountedWriter::new(writer);
719		let data = self.0;
720		let counted_list = CountedListWriter::<FuncBody, _>(
721			data.len(),
722			data.into_iter().map(Into::into),
723		);
724		counted_list.serialize(&mut counted_writer)?;
725		counted_writer.done()?;
726		Ok(())
727	}
728}
729
730/// Element entries section.
731#[derive(Default, Debug, Clone, PartialEq)]
732pub struct ElementSection(Vec<ElementSegment>);
733
734impl ElementSection {
735	/// New elements section.
736	pub fn with_entries(entries: Vec<ElementSegment>) -> Self {
737		ElementSection(entries)
738	}
739
740	/// New elements entries in the section.
741	pub fn entries(&self) -> &[ElementSegment] {
742		&self.0
743	}
744
745	/// List of all data entries in the section (mutable).
746	pub fn entries_mut(&mut self) -> &mut Vec<ElementSegment> {
747		&mut self.0
748	}
749}
750
751impl Deserialize for ElementSection {
752	type Error = Error;
753
754	fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
755		Ok(ElementSection(read_entries(reader)?))
756	}
757}
758
759impl Serialize for ElementSection {
760	type Error = Error;
761
762	fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
763		let mut counted_writer = CountedWriter::new(writer);
764		let data = self.0;
765		let counted_list = CountedListWriter::<ElementSegment, _>(
766			data.len(),
767			data.into_iter().map(Into::into),
768		);
769		counted_list.serialize(&mut counted_writer)?;
770		counted_writer.done()?;
771		Ok(())
772	}
773}
774
775/// Data entries definitions.
776#[derive(Default, Debug, Clone, PartialEq)]
777pub struct DataSection(Vec<DataSegment>);
778
779impl DataSection {
780	/// New data section.
781	pub fn with_entries(entries: Vec<DataSegment>) -> Self {
782		DataSection(entries)
783	}
784
785	/// List of all data entries in the section.
786	pub fn entries(&self) -> &[DataSegment] {
787		&self.0
788	}
789
790	/// List of all data entries in the section (mutable).
791	pub fn entries_mut(&mut self) -> &mut Vec<DataSegment> {
792		&mut self.0
793	}
794}
795
796impl Deserialize for DataSection {
797	type Error = Error;
798
799	fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
800		Ok(DataSection(read_entries(reader)?))
801	}
802}
803
804impl Serialize for DataSection {
805	type Error = Error;
806
807	fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
808		let mut counted_writer = CountedWriter::new(writer);
809		let data = self.0;
810		let counted_list = CountedListWriter::<DataSegment, _>(
811			data.len(),
812			data.into_iter().map(Into::into),
813		);
814		counted_list.serialize(&mut counted_writer)?;
815		counted_writer.done()?;
816		Ok(())
817	}
818}
819
820#[cfg(test)]
821mod tests {
822
823	use super::super::{
824		deserialize_buffer, deserialize_file, ValueType, InitExpr, DataSegment,
825		serialize, ElementSegment, Instructions, BlockType, Local, FuncBody,
826	};
827	use super::{Section, TypeSection, Type, DataSection, ElementSection, CodeSection};
828
829	#[test]
830	fn import_section() {
831		let module = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized");
832		let mut found = false;
833		for section in module.sections() {
834			match section {
835				&Section::Import(ref import_section) => {
836					assert_eq!(25, import_section.entries().len());
837					found = true
838				},
839				_ => { }
840			}
841		}
842		assert!(found, "There should be import section in test5.wasm");
843	}
844
845	fn functions_test_payload() -> &'static [u8] {
846		&[
847			// functions section id
848			0x03u8,
849			// functions section length
850			0x87, 0x80, 0x80, 0x80, 0x0,
851			// number of functions
852			0x04,
853			// type reference 1
854			0x01,
855			// type reference 2
856			0x86, 0x80, 0x00,
857			// type reference 3
858			0x09,
859			// type reference 4
860			0x33
861		]
862	}
863
864	#[test]
865	fn fn_section_detect() {
866		let section: Section =
867			deserialize_buffer(functions_test_payload()).expect("section to be deserialized");
868
869		match section {
870			Section::Function(_) => {},
871			_ => {
872				panic!("Payload should be recognized as functions section")
873			}
874		}
875	}
876
877	#[test]
878	fn fn_section_number() {
879		let section: Section =
880			deserialize_buffer(functions_test_payload()).expect("section to be deserialized");
881
882		match section {
883			Section::Function(fn_section) => {
884				assert_eq!(4, fn_section.entries().len(), "There should be 4 functions total");
885			},
886			_ => {
887				// will be catched by dedicated test
888			}
889		}
890	}
891
892	#[test]
893	fn fn_section_ref() {
894		let section: Section =
895			deserialize_buffer(functions_test_payload()).expect("section to be deserialized");
896
897		match section {
898			Section::Function(fn_section) => {
899				assert_eq!(6, fn_section.entries()[1].type_ref());
900			},
901			_ => {
902				// will be catched by dedicated test
903			}
904		}
905	}
906
907	fn types_test_payload() -> &'static [u8] {
908		&[
909			// section length
910			11,
911
912			// 2 functions
913			2,
914			// func 1, form =1
915			0x60,
916			// param_count=1
917			1,
918				// first param
919				0x7e, // i64
920			// no return params
921			0x00,
922
923			// func 2, form=1
924			0x60,
925			// param_count=2
926			2,
927				// first param
928				0x7e,
929				// second param
930				0x7d,
931			// return param (is_present, param_type)
932			0x01, 0x7e
933		]
934	}
935
936	#[test]
937	fn type_section_len() {
938		let type_section: TypeSection =
939			deserialize_buffer(types_test_payload()).expect("type_section be deserialized");
940
941		assert_eq!(type_section.types().len(), 2);
942	}
943
944	#[test]
945	fn type_section_infer() {
946		let type_section: TypeSection =
947			deserialize_buffer(types_test_payload()).expect("type_section be deserialized");
948
949		let t1 = match &type_section.types()[1] {
950			&Type::Function(ref func_type) => func_type
951		};
952
953		assert_eq!(vec![ValueType::I64], t1.results());
954		assert_eq!(2, t1.params().len());
955	}
956
957	fn export_payload() -> &'static [u8] {
958		&[
959			// section id
960			0x07,
961			// section length
962			28,
963			// 6 entries
964			6,
965			// func "A", index 6
966			// [name_len(1-5 bytes), name_bytes(name_len, internal_kind(1byte), internal_index(1-5 bytes)])
967			0x01, 0x41,  0x01, 0x86, 0x80, 0x00,
968			// func "B", index 8
969			0x01, 0x42,  0x01, 0x86, 0x00,
970			// func "C", index 7
971			0x01, 0x43,  0x01, 0x07,
972			// memory "D", index 0
973			0x01, 0x44,  0x02, 0x00,
974			// func "E", index 1
975			0x01, 0x45,  0x01, 0x01,
976			// func "F", index 2
977			0x01, 0x46,  0x01, 0x02
978		]
979	}
980
981
982	#[test]
983	fn export_detect() {
984		let section: Section =
985			deserialize_buffer(export_payload()).expect("section to be deserialized");
986
987		match section {
988			Section::Export(_) => {},
989			_ => {
990				panic!("Payload should be recognized as export section")
991			}
992		}
993	}
994
995	fn code_payload() -> &'static [u8] {
996		&[
997			// sectionid
998			0x0Au8,
999			// section length, 32
1000			0x20,
1001			// body count
1002			0x01,
1003			// body 1, length 30
1004			0x1E,
1005			0x01, 0x01, 0x7F, // local i32 (one collection of length one of type i32)
1006			0x02, 0x7F, // block i32
1007				0x23, 0x00, // get_global 0
1008				0x21, 0x01, // set_local 1
1009				0x23, 0x00, // get_global 0
1010				0x20, 0x00, // get_local 0
1011				0x6A,       // i32.add
1012				0x24, 0x00, // set_global 0
1013				0x23, 0x00, // get_global 0
1014				0x41, 0x0F, // i32.const 15
1015				0x6A,       // i32.add
1016				0x41, 0x70, // i32.const -16
1017				0x71,       // i32.and
1018				0x24, 0x00, // set_global 0
1019				0x20, 0x01, // get_local 1
1020			0x0B,
1021			0x0B,
1022		]
1023	}
1024
1025	#[test]
1026	fn code_detect() {
1027
1028		let section: Section =
1029			deserialize_buffer(code_payload()).expect("section to be deserialized");
1030
1031		match section {
1032			Section::Code(_) => {},
1033			_ => {
1034				panic!("Payload should be recognized as a code section")
1035			}
1036		}
1037	}
1038
1039	fn data_payload() -> &'static [u8] {
1040		&[
1041			0x0bu8,  // section id
1042			20,      // 20 bytes overall
1043			0x01,    // number of segments
1044			0x00,    // index
1045			0x0b,    // just `end` op
1046			0x10,
1047			// 16x 0x00
1048			0x00, 0x00, 0x00, 0x00,
1049			0x00, 0x00, 0x00, 0x00,
1050			0x00, 0x00, 0x00, 0x00,
1051			0x00, 0x00, 0x00, 0x00
1052		]
1053	}
1054
1055	#[test]
1056	fn data_section_ser() {
1057		let data_section = DataSection::with_entries(
1058			vec![DataSegment::new(0u32, Some(InitExpr::empty()), vec![0u8; 16])]
1059		);
1060
1061		let buf = serialize(data_section).expect("Data section to be serialized");
1062
1063		assert_eq!(buf, vec![
1064			20u8, // 19 bytes overall
1065			0x01, // number of segments
1066			0x00, // index
1067			0x0b, // just `end` op
1068			16,   // value of length 16
1069			0x00, 0x00, 0x00, 0x00, // 16x 0x00 as in initialization
1070			0x00, 0x00, 0x00, 0x00,
1071			0x00, 0x00, 0x00, 0x00,
1072			0x00, 0x00, 0x00, 0x00
1073		]);
1074	}
1075
1076	#[test]
1077	fn data_section_detect() {
1078		let section: Section =
1079			deserialize_buffer(data_payload()).expect("section to be deserialized");
1080
1081		match section {
1082			Section::Data(_) => {},
1083			_ => {
1084				panic!("Payload should be recognized as a data section")
1085			}
1086		}
1087	}
1088
1089	#[test]
1090	fn element_section_ser() {
1091		let element_section = ElementSection::with_entries(
1092			vec![ElementSegment::new(0u32, Some(InitExpr::empty()), vec![0u32; 4])]
1093		);
1094
1095		let buf = serialize(element_section).expect("Element section to be serialized");
1096
1097		assert_eq!(buf, vec![
1098			08u8, // 8 bytes overall
1099			0x01, // number of segments
1100			0x00, // index
1101			0x0b, // just `end` op
1102			0x04, // 4 elements
1103			0x00, 0x00, 0x00, 0x00 // 4x 0x00 as in initialization
1104		]);
1105	}
1106
1107	#[test]
1108	fn code_section_ser() {
1109		use super::super::Instruction::*;
1110
1111		let code_section = CodeSection::with_bodies(
1112			vec![
1113				FuncBody::new(
1114					vec![Local::new(1, ValueType::I32)],
1115					Instructions::new(vec![
1116						Block(BlockType::Value(ValueType::I32)),
1117						GetGlobal(0),
1118						End,
1119						End,
1120					])
1121				)
1122			]);
1123
1124		let buf = serialize(code_section).expect("Code section to be serialized");
1125
1126		assert_eq!(buf, vec![
1127			11u8,            // 11 bytes total section size
1128			0x01,            // 1 function
1129			  9,             //   function #1 total code size
1130			  1,             //   1 local variable declaration
1131			  1,             //      amount of variables
1132			  0x7f,          //      type of variable (7-bit, -0x01), negative
1133			  0x02,          //   block
1134				0x7f,        //      block return type (7-bit, -0x01), negative
1135				0x23, 0x00,  //      get_global(0)
1136				0x0b,        //   block end
1137			0x0b,            // function end
1138		]);
1139	}
1140
1141	#[test]
1142	fn start_section() {
1143		let section: Section = deserialize_buffer(&[08u8, 01u8, 00u8]).expect("Start section to deserialize");
1144		if let Section::Start(_) = section {
1145		} else {
1146			panic!("Payload should be a start section");
1147		}
1148
1149		let serialized = serialize(section).expect("Start section to successfully serializen");
1150
1151		assert_eq!(serialized, vec![08u8, 01u8, 00u8]);
1152	}
1153}