1use super::*;
2
3#[allow(non_camel_case_types)]
4#[derive(Copy, Clone, Debug, PartialEq)]
5pub enum NumberType {
6 i32,
7 i64,
8 f32,
9 f64,
10}
11
12#[derive(Copy, Clone, Debug, PartialEq)]
27pub enum ReferenceType {
28 FuncRef,
29 ExternRef,
30}
31
32impl<'a> Parser<'a> {
33 pub(super) fn read_ref_type(&mut self) -> Result<ReferenceType> {
34 match self.byte()? {
35 0x70 => Ok(ReferenceType::FuncRef),
36 0x6f => Ok(ReferenceType::ExternRef),
37 _ => error!(ErrorType::InvalidReferenceType),
38 }
39 }
40}
41
42#[allow(non_camel_case_types)]
43#[derive(Copy, Clone, Debug, PartialEq)]
44pub enum VectorType {
45 v128,
46}
47
48#[derive(Copy, Clone, Debug, PartialEq)]
60pub enum ValueType {
61 Number(NumberType),
62 Reference(ReferenceType),
63 Vector128,
64}
65
66impl<'a> Parser<'a> {
67 pub(super) fn read_value_type(&mut self) -> Result<ValueType> {
68 match self.byte()? {
69 0x7f => Ok(ValueType::Number(NumberType::i32)),
70 0x7e => Ok(ValueType::Number(NumberType::i64)),
71 0x7d => Ok(ValueType::Number(NumberType::f32)),
72 0x7c => Ok(ValueType::Number(NumberType::f64)),
73 0x7b => Ok(ValueType::Vector128),
74 0x70 => Ok(ValueType::Reference(ReferenceType::FuncRef)),
75 0x6f => Ok(ValueType::Reference(ReferenceType::ExternRef)),
76 _ => error!(ErrorType::InvalidValueType),
77 }
78 }
79
80 pub(super) fn read_result_type(&mut self) -> Result<Vec<ValueType>> {
81 let mut out = Vec::new();
82 self.collect(&mut out, Self::read_value_type)?;
83 Ok(out)
84 }
85}
86
87#[derive(Clone, Debug, PartialEq)]
88pub struct FunctionType {
89 pub parameters: Vec<ValueType>,
90 pub returned: Vec<ValueType>,
91}
92
93impl<'a> Parser<'a> {
94 pub(super) fn read_function_type(&mut self) -> Result<FunctionType> {
95 if self.byte()? == 0x60 {
96
97 let parameters = self.read_result_type()?;
98 let returned = self.read_result_type()?;
99
100 let func = FunctionType {
101 parameters,
102 returned,
103 };
104
105 Ok(func)
106
107 } else {
108 error!(ErrorType::InvalidFunctionType)
109 }
110 }
111}
112
113#[derive(Copy, Clone, Debug, PartialEq)]
114pub struct Limits {
115 pub min: u32,
116 pub max: Option<u32>,
117}
118
119impl<'a> Parser<'a> {
120 pub(super) fn read_limits(&mut self) -> Result<Limits> {
122 let (min, max) = match self.byte()? {
123 0x00 => Ok((self.read_u32()?, None)),
124 0x01 => {
125 let min = self.read_u32()?;
126 let max = self.read_u32()?;
127 Ok((min, Some(max)))
128 },
129 _ => error!(ErrorType::InvalidLimits),
130 }?;
131
132 let limits = Limits {
133 min, max,
134 };
135
136 Ok(limits)
137 }
138}
139
140#[derive(Copy, Clone, Debug, PartialEq)]
141pub struct TableType {
142 pub element_type: ReferenceType,
143 pub limits: Limits,
144}
145
146impl<'a> Parser<'a> {
147 pub(super) fn read_table_type(&mut self) -> Result<TableType> {
148 let element_type = self.read_ref_type()?;
149 let limits = self.read_limits()?;
150
151 let table_type = TableType {
152 element_type,
153 limits,
154 };
155
156 Ok(table_type)
157 }
158}
159
160#[derive(Clone, Debug, PartialEq)]
161pub struct GlobalType {
162 pub value_type: ValueType,
163 pub mutable: bool,
164}
165
166impl<'a> Parser<'a> {
167 pub(super) fn read_global_type(&mut self) -> Result<GlobalType> {
168 let value_type = self.read_value_type()?;
169 let mutable = match self.byte()? {
170 0x00 => Ok(false),
171 0x01 => Ok(true),
172 _ => error!(ErrorType::InvalidMutability),
173 }?;
174
175 let global_type = GlobalType {
176 value_type,
177 mutable,
178 };
179
180 Ok(global_type)
181 }
182}