tetsy_wasm/elements/
types.rs

1use alloc::vec::Vec;
2use crate::io;
3use super::{
4	Deserialize, Serialize, Error, VarUint7, VarInt7, CountedList,
5	CountedListWriter,
6};
7use core::fmt;
8
9/// Type definition in types section. Currently can be only of the function type.
10#[derive(Debug, Clone, PartialEq, Hash, Eq)]
11pub enum Type {
12	/// Function type.
13	Function(FunctionType),
14}
15
16impl Deserialize for Type {
17	type Error = Error;
18
19	fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
20		Ok(Type::Function(FunctionType::deserialize(reader)?))
21	}
22}
23
24impl Serialize for Type {
25	type Error = Error;
26
27	fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
28		match self {
29			Type::Function(fn_type) => fn_type.serialize(writer)
30		}
31	}
32}
33
34/// Value type.
35#[derive(Clone, Copy, Debug, PartialEq, Hash, Eq)]
36pub enum ValueType {
37	/// 32-bit signed integer
38	I32,
39	/// 64-bit signed integer
40	I64,
41	/// 32-bit float
42	F32,
43	/// 64-bit float
44	F64,
45	#[cfg(feature="simd")]
46	/// 128-bit SIMD register
47	V128,
48}
49
50impl Deserialize for ValueType {
51	type Error = Error;
52
53	fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
54		let val = VarInt7::deserialize(reader)?;
55
56		match val.into() {
57			-0x01 => Ok(ValueType::I32),
58			-0x02 => Ok(ValueType::I64),
59			-0x03 => Ok(ValueType::F32),
60			-0x04 => Ok(ValueType::F64),
61			#[cfg(feature="simd")]
62			-0x05 => Ok(ValueType::V128),
63			_ => Err(Error::UnknownValueType(val.into())),
64		}
65	}
66}
67
68impl Serialize for ValueType {
69	type Error = Error;
70
71	fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
72		let val: VarInt7 = match self {
73			ValueType::I32 => -0x01,
74			ValueType::I64 => -0x02,
75			ValueType::F32 => -0x03,
76			ValueType::F64 => -0x04,
77			#[cfg(feature="simd")]
78			ValueType::V128 => -0x05,
79		}.into();
80		val.serialize(writer)?;
81		Ok(())
82	}
83}
84
85impl fmt::Display for ValueType {
86	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
87		match *self {
88			ValueType::I32 => write!(f, "i32"),
89			ValueType::I64 => write!(f, "i64"),
90			ValueType::F32 => write!(f, "f32"),
91			ValueType::F64 => write!(f, "f64"),
92			#[cfg(feature="simd")]
93			ValueType::V128 => write!(f, "v128"),
94		}
95	}
96}
97
98/// Block type which is basically `ValueType` + NoResult (to define blocks that have no return type)
99#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
100pub enum BlockType {
101	/// Value-type specified block type
102	Value(ValueType),
103	/// No specified block type
104	NoResult,
105}
106
107impl Deserialize for BlockType {
108	type Error = Error;
109
110	fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
111		let val = VarInt7::deserialize(reader)?;
112
113		match val.into() {
114			-0x01 => Ok(BlockType::Value(ValueType::I32)),
115			-0x02 => Ok(BlockType::Value(ValueType::I64)),
116			-0x03 => Ok(BlockType::Value(ValueType::F32)),
117			-0x04 => Ok(BlockType::Value(ValueType::F64)),
118			#[cfg(feature="simd")]
119			0x7b => Ok(BlockType::Value(ValueType::V128)),
120			-0x40 => Ok(BlockType::NoResult),
121			_ => Err(Error::UnknownValueType(val.into())),
122		}
123	}
124}
125
126impl Serialize for BlockType {
127	type Error = Error;
128
129	fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
130		let val: VarInt7 = match self {
131			BlockType::NoResult => -0x40i8,
132			BlockType::Value(ValueType::I32) => -0x01,
133			BlockType::Value(ValueType::I64) => -0x02,
134			BlockType::Value(ValueType::F32) => -0x03,
135			BlockType::Value(ValueType::F64) => -0x04,
136			#[cfg(feature="simd")]
137			BlockType::Value(ValueType::V128) => 0x7b,
138		}.into();
139		val.serialize(writer)?;
140		Ok(())
141	}
142}
143
144/// Function signature type.
145#[derive(Debug, Clone, PartialEq, Hash, Eq)]
146pub struct FunctionType {
147	form: u8,
148	params: Vec<ValueType>,
149	results: Vec<ValueType>,
150}
151
152impl Default for FunctionType {
153	fn default() -> Self {
154		FunctionType {
155			form: 0x60,
156			params: Vec::new(),
157			results: Vec::new(),
158		}
159	}
160}
161
162impl FunctionType {
163	/// New function type given the params and results as vectors
164	pub fn new(params: Vec<ValueType>, results: Vec<ValueType>) -> Self {
165		FunctionType {
166			form: 0,
167			params,
168			results,
169		}
170	}
171	/// Function form (currently only valid value is `0x60`)
172	pub fn form(&self) -> u8 { self.form }
173	/// Parameters in the function signature.
174	pub fn params(&self) -> &[ValueType] { &self.params }
175	/// Mutable parameters in the function signature.
176	pub fn params_mut(&mut self) -> &mut Vec<ValueType> { &mut self.params }
177	/// Results in the function signature, if any.
178	pub fn results(&self) -> &[ValueType] { &self.results }
179	/// Mutable type in the function signature, if any.
180	pub fn results_mut(&mut self) -> &mut Vec<ValueType> { &mut self.results }
181}
182
183impl Deserialize for FunctionType {
184	type Error = Error;
185
186	fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
187		let form: u8 = VarUint7::deserialize(reader)?.into();
188
189		if form != 0x60 {
190			return Err(Error::UnknownFunctionForm(form));
191		}
192
193		let params: Vec<ValueType> = CountedList::deserialize(reader)?.into_inner();
194		let results: Vec<ValueType> = CountedList::deserialize(reader)?.into_inner();
195
196		#[cfg(not(feature="multi_value"))]
197		if results.len() > 1 {
198			return Err(Error::Other("Enable the multi_value feature to deserialize more than one function result"));
199		}
200
201		Ok(FunctionType {
202			form,
203			params,
204			results,
205		})
206	}
207}
208
209impl Serialize for FunctionType {
210	type Error = Error;
211
212	fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
213		VarUint7::from(self.form).serialize(writer)?;
214
215		let params_counted_list = CountedListWriter::<ValueType, _>(
216			self.params.len(),
217			self.params.into_iter().map(Into::into),
218		);
219		params_counted_list.serialize(writer)?;
220
221		let results_counted_list = CountedListWriter::<ValueType, _>(
222			self.results.len(),
223			self.results.into_iter().map(Into::into),
224		);
225		results_counted_list.serialize(writer)?;
226
227		Ok(())
228	}
229}
230
231/// Table element type.
232#[derive(Clone, Copy, Debug, PartialEq)]
233pub enum TableElementType {
234	/// A reference to a function with any signature.
235	AnyFunc,
236}
237
238impl Deserialize for TableElementType {
239	type Error = Error;
240
241	fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
242		let val = VarInt7::deserialize(reader)?;
243
244		match val.into() {
245			-0x10 => Ok(TableElementType::AnyFunc),
246			_ => Err(Error::UnknownTableElementType(val.into())),
247		}
248	}
249}
250
251impl Serialize for TableElementType {
252	type Error = Error;
253
254	fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
255		let val: VarInt7 = match self {
256			TableElementType::AnyFunc => -0x10,
257		}.into();
258		val.serialize(writer)?;
259		Ok(())
260	}
261}