parity_wasm/elements/
types.rs

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