parity_wasm/elements/
segment.rs1use super::{CountedList, CountedListWriter, Deserialize, Error, InitExpr, Serialize, VarUint32};
2use crate::io;
3use alloc::vec::Vec;
4
5#[cfg(feature = "bulk")]
6const FLAG_MEMZERO: u32 = 0;
7#[cfg(feature = "bulk")]
8const FLAG_PASSIVE: u32 = 1;
9#[cfg(feature = "bulk")]
10const FLAG_MEM_NONZERO: u32 = 2;
11
12#[cfg(feature = "reduced-stack-buffer")]
13const VALUES_BUFFER_LENGTH: usize = 256;
14
15#[cfg(not(feature = "reduced-stack-buffer"))]
16const VALUES_BUFFER_LENGTH: usize = 16384;
17
18#[derive(Debug, Clone, PartialEq)]
20pub struct ElementSegment {
21 index: u32,
22 offset: Option<InitExpr>,
23 members: Vec<u32>,
24
25 #[cfg(feature = "bulk")]
26 passive: bool,
27}
28
29impl ElementSegment {
30 pub fn new(index: u32, offset: Option<InitExpr>, members: Vec<u32>) -> Self {
32 ElementSegment {
33 index,
34 offset,
35 members,
36
37 #[cfg(feature = "bulk")]
38 passive: false,
39 }
40 }
41
42 pub fn members(&self) -> &[u32] {
44 &self.members
45 }
46
47 pub fn members_mut(&mut self) -> &mut Vec<u32> {
49 &mut self.members
50 }
51
52 pub fn index(&self) -> u32 {
54 self.index
55 }
56
57 pub fn offset(&self) -> &Option<InitExpr> {
61 &self.offset
62 }
63
64 pub fn offset_mut(&mut self) -> &mut Option<InitExpr> {
68 &mut self.offset
69 }
70}
71
72#[cfg(feature = "bulk")]
73impl ElementSegment {
74 pub fn passive(&self) -> bool {
76 self.passive
77 }
78
79 pub fn passive_mut(&mut self) -> &mut bool {
81 &mut self.passive
82 }
83
84 pub fn set_passive(&mut self, passive: bool) {
86 self.passive = passive;
87 }
88}
89
90impl Deserialize for ElementSegment {
91 type Error = Error;
92
93 #[cfg(not(feature = "bulk"))]
94 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
95 let index: u32 = VarUint32::deserialize(reader)?.into();
96 let offset = InitExpr::deserialize(reader)?;
97 let members: Vec<u32> = CountedList::<VarUint32>::deserialize(reader)?
98 .into_inner()
99 .into_iter()
100 .map(Into::into)
101 .collect();
102
103 Ok(ElementSegment { index, offset: Some(offset), members })
104 }
105
106 #[cfg(feature = "bulk")]
107 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
108 let flags: u32 = VarUint32::deserialize(reader)?.into();
111 let index = if flags == FLAG_MEMZERO || flags == FLAG_PASSIVE {
112 0u32
113 } else if flags == FLAG_MEM_NONZERO {
114 VarUint32::deserialize(reader)?.into()
115 } else {
116 return Err(Error::InvalidSegmentFlags(flags))
117 };
118 let offset =
119 if flags == FLAG_PASSIVE { None } else { Some(InitExpr::deserialize(reader)?) };
120
121 let members: Vec<u32> = CountedList::<VarUint32>::deserialize(reader)?
122 .into_inner()
123 .into_iter()
124 .map(Into::into)
125 .collect();
126
127 Ok(ElementSegment { index, offset, members, passive: flags == FLAG_PASSIVE })
128 }
129}
130
131impl Serialize for ElementSegment {
132 type Error = Error;
133
134 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
135 #[cfg(feature = "bulk")]
136 {
137 if self.passive {
138 VarUint32::from(FLAG_PASSIVE).serialize(writer)?;
139 } else if self.index != 0 {
140 VarUint32::from(FLAG_MEM_NONZERO).serialize(writer)?;
141 VarUint32::from(self.index).serialize(writer)?;
142 } else {
143 VarUint32::from(FLAG_MEMZERO).serialize(writer)?;
144 }
145 }
146 #[cfg(not(feature = "bulk"))]
147 VarUint32::from(self.index).serialize(writer)?;
148
149 if let Some(offset) = self.offset {
150 offset.serialize(writer)?;
151 }
152 let data = self.members;
153 let counted_list =
154 CountedListWriter::<VarUint32, _>(data.len(), data.into_iter().map(Into::into));
155 counted_list.serialize(writer)?;
156 Ok(())
157 }
158}
159
160#[derive(Clone, Debug, PartialEq)]
162pub struct DataSegment {
163 index: u32,
164 offset: Option<InitExpr>,
165 value: Vec<u8>,
166
167 #[cfg(feature = "bulk")]
168 passive: bool,
169}
170
171impl DataSegment {
172 pub fn new(index: u32, offset: Option<InitExpr>, value: Vec<u8>) -> Self {
174 DataSegment {
175 index,
176 offset,
177 value,
178
179 #[cfg(feature = "bulk")]
180 passive: false,
181 }
182 }
183
184 pub fn index(&self) -> u32 {
186 self.index
187 }
188
189 pub fn offset(&self) -> &Option<InitExpr> {
193 &self.offset
194 }
195
196 pub fn offset_mut(&mut self) -> &mut Option<InitExpr> {
200 &mut self.offset
201 }
202
203 pub fn value(&self) -> &[u8] {
205 &self.value
206 }
207
208 pub fn value_mut(&mut self) -> &mut Vec<u8> {
210 &mut self.value
211 }
212}
213
214#[cfg(feature = "bulk")]
215impl DataSegment {
216 pub fn passive(&self) -> bool {
218 self.passive
219 }
220
221 pub fn passive_mut(&mut self) -> &mut bool {
223 &mut self.passive
224 }
225
226 pub fn set_passive(&mut self, passive: bool) {
228 self.passive = passive;
229 }
230}
231
232impl Deserialize for DataSegment {
233 type Error = Error;
234
235 #[cfg(not(feature = "bulk"))]
236 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
237 let index = VarUint32::deserialize(reader)?;
238 let offset = InitExpr::deserialize(reader)?;
239 let value_len = u32::from(VarUint32::deserialize(reader)?) as usize;
240 let value = buffered_read!(VALUES_BUFFER_LENGTH, value_len, reader);
241
242 Ok(DataSegment { index: index.into(), offset: Some(offset), value })
243 }
244
245 #[cfg(feature = "bulk")]
246 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
247 let flags: u32 = VarUint32::deserialize(reader)?.into();
248 let index = if flags == FLAG_MEMZERO || flags == FLAG_PASSIVE {
249 0u32
250 } else if flags == FLAG_MEM_NONZERO {
251 VarUint32::deserialize(reader)?.into()
252 } else {
253 return Err(Error::InvalidSegmentFlags(flags))
254 };
255 let offset =
256 if flags == FLAG_PASSIVE { None } else { Some(InitExpr::deserialize(reader)?) };
257 let value_len = u32::from(VarUint32::deserialize(reader)?) as usize;
258 let value = buffered_read!(VALUES_BUFFER_LENGTH, value_len, reader);
259
260 Ok(DataSegment { index, offset, value, passive: flags == FLAG_PASSIVE })
261 }
262}
263
264impl Serialize for DataSegment {
265 type Error = Error;
266
267 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
268 #[cfg(feature = "bulk")]
269 {
270 if self.passive {
271 VarUint32::from(FLAG_PASSIVE).serialize(writer)?;
272 } else if self.index != 0 {
273 VarUint32::from(FLAG_MEM_NONZERO).serialize(writer)?;
274 VarUint32::from(self.index).serialize(writer)?;
275 } else {
276 VarUint32::from(FLAG_MEMZERO).serialize(writer)?;
277 }
278 }
279 #[cfg(not(feature = "bulk"))]
280 VarUint32::from(self.index).serialize(writer)?;
281
282 if let Some(offset) = self.offset {
283 offset.serialize(writer)?;
284 }
285
286 let value = self.value;
287 VarUint32::from(value.len()).serialize(writer)?;
288 writer.write(&value[..])?;
289 Ok(())
290 }
291}