wasm/core/decoding/modules/
code_section.rs1use alloc::vec::Vec;
2use core::iter;
3
4use crate::{
5 core::{decoding::reader::WasmDecoder, utils::ToUsizeExt},
6 DecodingError, ValType,
7};
8
9pub fn decode_locals(wasm: &mut WasmDecoder) -> Result<Vec<ValType>, DecodingError> {
10 let locals = wasm.decode_vec(|wasm| {
11 let n = wasm.decode_var_u32()?.into_usize();
12 let valtype = ValType::decode(wasm)?;
13
14 Ok((n, valtype))
15 })?;
16
17 let mut total_no_of_locals: u64 = 0;
22 for local in &locals {
23 let temp = local.0 as u64;
24 if temp > u32::MAX.into() {
25 return Err(DecodingError::TooManyLocals(total_no_of_locals));
26 };
27 total_no_of_locals = match total_no_of_locals.checked_add(temp) {
28 None => return Err(DecodingError::TooManyLocals(total_no_of_locals)),
29 Some(n) => n,
30 }
31 }
32
33 if total_no_of_locals > u32::MAX.into() {
34 return Err(DecodingError::TooManyLocals(total_no_of_locals));
35 }
36
37 let locals = locals
39 .into_iter()
40 .flat_map(|entry| iter::repeat_n(entry.1, entry.0))
41 .collect::<Vec<ValType>>();
42
43 Ok(locals)
44}