parity_wasm/elements/
func.rs1use super::{
2 CountedList, CountedListWriter, CountedWriter, Deserialize, Error, Instructions, Serialize,
3 ValueType, VarUint32,
4};
5use crate::{elements::section::SectionReader, io};
6use alloc::vec::Vec;
7
8#[derive(Debug, Copy, Clone, PartialEq)]
10pub struct Func(u32);
11
12impl Func {
13 pub fn new(type_ref: u32) -> Self {
15 Func(type_ref)
16 }
17
18 pub fn type_ref(&self) -> u32 {
20 self.0
21 }
22
23 pub fn type_ref_mut(&mut self) -> &mut u32 {
25 &mut self.0
26 }
27}
28
29impl Serialize for Func {
30 type Error = Error;
31
32 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
33 VarUint32::from(self.0).serialize(writer)
34 }
35}
36
37impl Deserialize for Func {
38 type Error = Error;
39
40 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
41 Ok(Func(VarUint32::deserialize(reader)?.into()))
42 }
43}
44
45#[derive(Debug, Copy, Clone, PartialEq)]
47pub struct Local {
48 count: u32,
49 value_type: ValueType,
50}
51
52impl Local {
53 pub fn new(count: u32, value_type: ValueType) -> Self {
55 Local { count, value_type }
56 }
57
58 pub fn count(&self) -> u32 {
60 self.count
61 }
62
63 pub fn value_type(&self) -> ValueType {
65 self.value_type
66 }
67}
68
69impl Deserialize for Local {
70 type Error = Error;
71
72 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
73 let count = VarUint32::deserialize(reader)?;
74 let value_type = ValueType::deserialize(reader)?;
75 Ok(Local { count: count.into(), value_type })
76 }
77}
78
79impl Serialize for Local {
80 type Error = Error;
81
82 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
83 VarUint32::from(self.count).serialize(writer)?;
84 self.value_type.serialize(writer)?;
85 Ok(())
86 }
87}
88
89#[derive(Debug, Clone, PartialEq)]
91pub struct FuncBody {
92 locals: Vec<Local>,
93 instructions: Instructions,
94}
95
96impl FuncBody {
97 pub fn new(locals: Vec<Local>, instructions: Instructions) -> Self {
99 FuncBody { locals, instructions }
100 }
101
102 pub fn empty() -> Self {
104 FuncBody { locals: Vec::new(), instructions: Instructions::empty() }
105 }
106
107 pub fn locals(&self) -> &[Local] {
109 &self.locals
110 }
111
112 pub fn code(&self) -> &Instructions {
116 &self.instructions
117 }
118
119 pub fn locals_mut(&mut self) -> &mut Vec<Local> {
121 &mut self.locals
122 }
123
124 pub fn code_mut(&mut self) -> &mut Instructions {
126 &mut self.instructions
127 }
128}
129
130impl Deserialize for FuncBody {
131 type Error = Error;
132
133 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
134 let mut body_reader = SectionReader::new(reader)?;
135 let locals: Vec<Local> = CountedList::<Local>::deserialize(&mut body_reader)?.into_inner();
136
137 locals
140 .iter()
141 .try_fold(0u32, |acc, &Local { count, .. }| acc.checked_add(count))
142 .ok_or(Error::TooManyLocals)?;
143
144 let instructions = Instructions::deserialize(&mut body_reader)?;
145 body_reader.close()?;
146 Ok(FuncBody { locals, instructions })
147 }
148}
149
150impl Serialize for FuncBody {
151 type Error = Error;
152
153 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
154 let mut counted_writer = CountedWriter::new(writer);
155
156 let data = self.locals;
157 let counted_list =
158 CountedListWriter::<Local, _>(data.len(), data.into_iter().map(Into::into));
159 counted_list.serialize(&mut counted_writer)?;
160
161 let code = self.instructions;
162 code.serialize(&mut counted_writer)?;
163
164 counted_writer.done()?;
165
166 Ok(())
167 }
168}