wasm/core/decoding/
values.rs1use alloc::vec::Vec;
9
10use crate::{
11 core::{decoding::reader::WasmDecoder, utils::ToUsizeExt},
12 DecodingError,
13};
14
15const CONTINUATION_BIT: u8 = 0b10000000;
21
22const INTEGER_BIT_FLAG: u8 = !CONTINUATION_BIT;
23
24impl<'wasm> WasmDecoder<'wasm> {
25 pub fn decode_u8(&mut self) -> Result<u8, DecodingError> {
27 let byte = self.peek_u8()?;
28 self.pc += 1;
29 Ok(byte)
30 }
31
32 pub fn decode_var_u32(&mut self) -> Result<u32, DecodingError> {
35 const PADDING_IN_LAST_BYTE_BIT_MASK: u8 = 0b01110000;
39
40 let mut result: u32 = 0;
41
42 let byte = self.decode_u8()?;
43 result |= u32::from(byte & INTEGER_BIT_FLAG);
44 if byte & CONTINUATION_BIT == 0 {
45 return Ok(result);
46 }
47
48 let byte = self.decode_u8()?;
49 result |= u32::from(byte & INTEGER_BIT_FLAG) << 7;
50 if byte & CONTINUATION_BIT == 0 {
51 return Ok(result);
52 }
53
54 let byte = self.decode_u8()?;
55 result |= u32::from(byte & INTEGER_BIT_FLAG) << 14;
56 if byte & CONTINUATION_BIT == 0 {
57 return Ok(result);
58 }
59
60 let byte = self.decode_u8()?;
61 result |= u32::from(byte & INTEGER_BIT_FLAG) << 21;
62 if byte & CONTINUATION_BIT == 0 {
63 return Ok(result);
64 }
65
66 let byte = self.decode_u8()?;
67 result |= u32::from(byte & INTEGER_BIT_FLAG) << 28;
68
69 let has_next_byte = byte & CONTINUATION_BIT > 0;
71 let padding_bits_are_not_zero = byte & PADDING_IN_LAST_BYTE_BIT_MASK > 0;
72 if has_next_byte || padding_bits_are_not_zero {
73 return Err(DecodingError::MalformedVariableLengthInteger);
75 }
76
77 Ok(result)
78 }
79
80 pub fn decode_f64(&mut self) -> Result<u64, DecodingError> {
81 let bytes = self.strip_bytes::<8>()?;
82 Ok(u64::from_le_bytes(bytes))
83 }
84
85 pub fn decode_var_i32(&mut self) -> Result<i32, DecodingError> {
86 const PADDING_IN_LAST_BYTE_BITMASK: u8 = 0b01110000;
90
91 const SIGN_IN_LAST_BYTE_BITFLAG: u8 = 0b00001000;
93
94 const NUM_BITS: u32 = 32;
96
97 let mut result: i32 = 0;
98
99 let byte = self.decode_u8()?;
100 result |= i32::from(byte & INTEGER_BIT_FLAG);
101 if byte & CONTINUATION_BIT == 0 {
102 const NUM_UNSPECIFIED_BITS: u32 = NUM_BITS - 7;
104 let sign_extended_result = (result << NUM_UNSPECIFIED_BITS) >> NUM_UNSPECIFIED_BITS;
105 return Ok(sign_extended_result);
106 }
107
108 let byte = self.decode_u8()?;
109 result |= i32::from(byte & INTEGER_BIT_FLAG) << 7;
110 if byte & CONTINUATION_BIT == 0 {
111 const NUM_UNSPECIFIED_BITS: u32 = NUM_BITS - 14;
112 let sign_extended_result = (result << NUM_UNSPECIFIED_BITS) >> NUM_UNSPECIFIED_BITS;
113 return Ok(sign_extended_result);
114 }
115
116 let byte = self.decode_u8()?;
117 result |= i32::from(byte & INTEGER_BIT_FLAG) << 14;
118 if byte & CONTINUATION_BIT == 0 {
119 const NUM_UNSPECIFIED_BITS: u32 = NUM_BITS - 21;
120 let sign_extended_result = (result << NUM_UNSPECIFIED_BITS) >> NUM_UNSPECIFIED_BITS;
121 return Ok(sign_extended_result);
122 }
123
124 let byte = self.decode_u8()?;
125 result |= i32::from(byte & INTEGER_BIT_FLAG) << 21;
126 if byte & CONTINUATION_BIT == 0 {
127 const NUM_UNSPECIFIED_BITS: u32 = NUM_BITS - 28;
128 let sign_extended_result = (result << NUM_UNSPECIFIED_BITS) >> NUM_UNSPECIFIED_BITS;
129 return Ok(sign_extended_result);
130 }
131
132 let byte = self.decode_u8()?;
133 result |= i32::from(byte & INTEGER_BIT_FLAG) << 28;
134
135 let has_next_byte = byte & CONTINUATION_BIT > 0;
137 if has_next_byte {
138 return Err(DecodingError::MalformedVariableLengthInteger);
140 }
141
142 const PADDING_AND_SIGN_BITMASK: u8 =
146 PADDING_IN_LAST_BYTE_BITMASK | SIGN_IN_LAST_BYTE_BITFLAG;
147 let number_of_ones_in_padding_and_sign_bits =
148 (byte & PADDING_AND_SIGN_BITMASK).count_ones();
149 let padding_bits_match_sign_bit = number_of_ones_in_padding_and_sign_bits
150 == PADDING_AND_SIGN_BITMASK.count_ones()
151 || number_of_ones_in_padding_and_sign_bits == 0;
152 if !padding_bits_match_sign_bit {
153 return Err(DecodingError::MalformedVariableLengthInteger);
155 }
156
157 Ok(result)
158 }
159
160 pub fn decode_var_i33_as_u32(&mut self) -> Result<u32, DecodingError> {
161 const PADDING_IN_LAST_BYTE_BITMASK: u8 = 0b01100000;
165
166 const SIGN_IN_LAST_BYTE_BITFLAG: u8 = 0b00010000;
168
169 const NUM_BITS: u32 = 33;
171
172 let mut result: i64 = 0;
173
174 let byte = self.decode_u8()?;
175 result |= i64::from(byte & INTEGER_BIT_FLAG);
176 if byte & CONTINUATION_BIT == 0 {
177 const NUM_UNSPECIFIED_BITS: u32 = NUM_BITS - 7;
179 let sign_extended_result = (result << NUM_UNSPECIFIED_BITS) >> NUM_UNSPECIFIED_BITS;
180 return u32::try_from(sign_extended_result).map_err(|_| DecodingError::I33IsNegative);
181 }
182
183 let byte = self.decode_u8()?;
184 result |= i64::from(byte & INTEGER_BIT_FLAG) << 7;
185 if byte & CONTINUATION_BIT == 0 {
186 const NUM_UNSPECIFIED_BITS: u32 = NUM_BITS - 14;
187 let sign_extended_result = (result << NUM_UNSPECIFIED_BITS) >> NUM_UNSPECIFIED_BITS;
188 return u32::try_from(sign_extended_result).map_err(|_| DecodingError::I33IsNegative);
189 }
190
191 let byte = self.decode_u8()?;
192 result |= i64::from(byte & INTEGER_BIT_FLAG) << 14;
193 if byte & CONTINUATION_BIT == 0 {
194 const NUM_UNSPECIFIED_BITS: u32 = NUM_BITS - 21;
195 let sign_extended_result = (result << NUM_UNSPECIFIED_BITS) >> NUM_UNSPECIFIED_BITS;
196 return u32::try_from(sign_extended_result).map_err(|_| DecodingError::I33IsNegative);
197 }
198
199 let byte = self.decode_u8()?;
200 result |= i64::from(byte & INTEGER_BIT_FLAG) << 21;
201 if byte & CONTINUATION_BIT == 0 {
202 const NUM_UNSPECIFIED_BITS: u32 = NUM_BITS - 28;
203 let sign_extended_result = (result << NUM_UNSPECIFIED_BITS) >> NUM_UNSPECIFIED_BITS;
204 return u32::try_from(sign_extended_result).map_err(|_| DecodingError::I33IsNegative);
205 }
206
207 let byte = self.decode_u8()?;
208 result |= i64::from(byte & INTEGER_BIT_FLAG) << 28;
209
210 let has_next_byte = byte & CONTINUATION_BIT > 0;
212 if has_next_byte {
213 return Err(DecodingError::MalformedVariableLengthInteger);
215 }
216
217 const PADDING_AND_SIGN_BITMASK: u8 =
221 PADDING_IN_LAST_BYTE_BITMASK | SIGN_IN_LAST_BYTE_BITFLAG;
222 let number_of_ones_in_padding_and_sign_bits =
223 (byte & PADDING_AND_SIGN_BITMASK).count_ones();
224 let padding_bits_match_sign_bit = number_of_ones_in_padding_and_sign_bits
225 == PADDING_AND_SIGN_BITMASK.count_ones()
226 || number_of_ones_in_padding_and_sign_bits == 0;
227 if !padding_bits_match_sign_bit {
228 return Err(DecodingError::MalformedVariableLengthInteger);
230 }
231
232 u32::try_from(result).map_err(|_| DecodingError::I33IsNegative)
233 }
234
235 pub fn decode_f32(&mut self) -> Result<u32, DecodingError> {
236 let bytes = self.strip_bytes::<4>()?;
237 Ok(u32::from_le_bytes(bytes))
238 }
239
240 pub fn decode_var_i64(&mut self) -> Result<i64, DecodingError> {
241 const PADDING_IN_LAST_BYTE_BITMASK: u8 = 0b01111110;
245
246 const SIGN_IN_LAST_BYTE_BITFLAG: u8 = 0b00000001;
248
249 const NUM_BITS: u32 = 64;
251
252 let mut result: i64 = 0;
253
254 let byte = self.decode_u8()?;
255 result |= i64::from(byte & INTEGER_BIT_FLAG);
256 if byte & CONTINUATION_BIT == 0 {
257 const NUM_UNSPECIFIED_BITS: u32 = NUM_BITS - 7;
259 let sign_extended_result = (result << NUM_UNSPECIFIED_BITS) >> NUM_UNSPECIFIED_BITS;
260 return Ok(sign_extended_result);
261 }
262
263 let byte = self.decode_u8()?;
264 result |= i64::from(byte & INTEGER_BIT_FLAG) << 7;
265 if byte & CONTINUATION_BIT == 0 {
266 const NUM_UNSPECIFIED_BITS: u32 = NUM_BITS - 14;
267 let sign_extended_result = (result << NUM_UNSPECIFIED_BITS) >> NUM_UNSPECIFIED_BITS;
268 return Ok(sign_extended_result);
269 }
270
271 let byte = self.decode_u8()?;
272 result |= i64::from(byte & INTEGER_BIT_FLAG) << 14;
273 if byte & CONTINUATION_BIT == 0 {
274 const NUM_UNSPECIFIED_BITS: u32 = NUM_BITS - 21;
275 let sign_extended_result = (result << NUM_UNSPECIFIED_BITS) >> NUM_UNSPECIFIED_BITS;
276 return Ok(sign_extended_result);
277 }
278
279 let byte = self.decode_u8()?;
280 result |= i64::from(byte & INTEGER_BIT_FLAG) << 21;
281 if byte & CONTINUATION_BIT == 0 {
282 const NUM_UNSPECIFIED_BITS: u32 = NUM_BITS - 28;
283 let sign_extended_result = (result << NUM_UNSPECIFIED_BITS) >> NUM_UNSPECIFIED_BITS;
284 return Ok(sign_extended_result);
285 }
286
287 let byte = self.decode_u8()?;
288 result |= i64::from(byte & INTEGER_BIT_FLAG) << 28;
289 if byte & CONTINUATION_BIT == 0 {
290 const NUM_UNSPECIFIED_BITS: u32 = NUM_BITS - 35;
291 let sign_extended_result = (result << NUM_UNSPECIFIED_BITS) >> NUM_UNSPECIFIED_BITS;
292 return Ok(sign_extended_result);
293 }
294
295 let byte = self.decode_u8()?;
296 result |= i64::from(byte & INTEGER_BIT_FLAG) << 35;
297 if byte & CONTINUATION_BIT == 0 {
298 const NUM_UNSPECIFIED_BITS: u32 = NUM_BITS - 42;
299 let sign_extended_result = (result << NUM_UNSPECIFIED_BITS) >> NUM_UNSPECIFIED_BITS;
300 return Ok(sign_extended_result);
301 }
302
303 let byte = self.decode_u8()?;
304 result |= i64::from(byte & INTEGER_BIT_FLAG) << 42;
305 if byte & CONTINUATION_BIT == 0 {
306 const NUM_UNSPECIFIED_BITS: u32 = NUM_BITS - 49;
307 let sign_extended_result = (result << NUM_UNSPECIFIED_BITS) >> NUM_UNSPECIFIED_BITS;
308 return Ok(sign_extended_result);
309 }
310
311 let byte = self.decode_u8()?;
312 result |= i64::from(byte & INTEGER_BIT_FLAG) << 49;
313 if byte & CONTINUATION_BIT == 0 {
314 const NUM_UNSPECIFIED_BITS: u32 = NUM_BITS - 56;
315 let sign_extended_result = (result << NUM_UNSPECIFIED_BITS) >> NUM_UNSPECIFIED_BITS;
316 return Ok(sign_extended_result);
317 }
318
319 let byte = self.decode_u8()?;
320 result |= i64::from(byte & INTEGER_BIT_FLAG) << 56;
321 if byte & CONTINUATION_BIT == 0 {
322 const NUM_UNSPECIFIED_BITS: u32 = NUM_BITS - 63;
323 let sign_extended_result = (result << NUM_UNSPECIFIED_BITS) >> NUM_UNSPECIFIED_BITS;
324 return Ok(sign_extended_result);
325 }
326
327 let byte = self.decode_u8()?;
328 result |= i64::from(byte & INTEGER_BIT_FLAG) << 63;
329
330 let has_next_byte = byte & CONTINUATION_BIT > 0;
332 if has_next_byte {
333 return Err(DecodingError::MalformedVariableLengthInteger);
335 }
336
337 const PADDING_AND_SIGN_BITMASK: u8 =
341 PADDING_IN_LAST_BYTE_BITMASK | SIGN_IN_LAST_BYTE_BITFLAG;
342 let number_of_ones_in_padding_and_sign_bits =
343 (byte & PADDING_AND_SIGN_BITMASK).count_ones();
344 let padding_bits_match_sign_bit = number_of_ones_in_padding_and_sign_bits
345 == PADDING_AND_SIGN_BITMASK.count_ones()
346 || number_of_ones_in_padding_and_sign_bits == 0;
347 if !padding_bits_match_sign_bit {
348 return Err(DecodingError::MalformedVariableLengthInteger);
350 }
351
352 Ok(result)
353 }
354
355 pub fn decode_name(&mut self) -> Result<&'wasm str, DecodingError> {
357 let len = self.decode_var_u32()?.into_usize();
358
359 let utf8_str = &self
360 .full_wasm_binary
361 .get(self.pc..(self.pc + len))
362 .ok_or(DecodingError::Eof)?;
363
364 self.pc += len;
365
366 core::str::from_utf8(utf8_str).map_err(DecodingError::MalformedUtf8)
367 }
368
369 pub fn decode_vec_enumerated<T, F, E>(&mut self, mut read_element: F) -> Result<Vec<T>, E>
371 where
372 T: 'wasm,
373 F: FnMut(&mut WasmDecoder<'wasm>, u32) -> Result<T, E>,
374 E: From<DecodingError>,
375 {
376 let mut idx = 0;
377 self.decode_vec(|wasm| {
378 let ret = read_element(wasm, idx);
379 idx = idx
380 .checked_add(1)
381 .expect("the length of vectors to be encoded as a u32");
382 ret
383 })
384 }
385
386 pub fn decode_vec<T, F, E>(&mut self, mut read_element: F) -> Result<Vec<T>, E>
390 where
391 T: 'wasm,
392 F: FnMut(&mut WasmDecoder<'wasm>) -> Result<T, E>,
393 E: From<DecodingError>,
394 {
395 let len = self.decode_var_u32()?;
396 core::iter::repeat_with(|| read_element(self))
397 .take(len.into_usize())
398 .collect()
399 }
400}
401
402#[cfg(test)]
403mod tests {
404 use crate::core::decoding::reader::WasmDecoder;
405
406 #[test]
407 fn test_var_i32() {
408 let bytes = [0xC0, 0xBB, 0x78];
409 let mut wasm = WasmDecoder::new(&bytes);
410
411 assert_eq!(wasm.decode_var_i32(), Ok(-123456));
412 }
413}