wasm/execution/runtime_structure/
table_instances.rs

1use alloc::{vec, vec::Vec};
2
3use crate::{core::utils::ToUsizeExt, Limits, Ref, RuntimeError, TableType, TrapError};
4
5#[derive(Debug)]
6pub struct TableInst {
7    pub ty: TableType,
8    pub elem: Vec<Ref>,
9}
10
11impl TableInst {
12    pub fn len(&self) -> usize {
13        self.elem.len()
14    }
15
16    /// <https://webassembly.github.io/spec/core/exec/modules.html#growing-tables>
17    pub fn grow(&mut self, n: u32, reff: Ref) -> Result<(), RuntimeError> {
18        // TODO refactor error, the spec Table.grow raises Table.{SizeOverflow, SizeLimit, OutOfMemory}
19        let len = n
20            .checked_add(self.elem.len() as u32)
21            .ok_or(TrapError::TableOrElementAccessOutOfBounds)?;
22
23        // roughly matches step 4,5,6
24        // checks limits_prime.valid() for limits_prime := { min: len, max: self.ty.lim.max }
25        // https://webassembly.github.io/spec/core/valid/types.html#limits
26        if self.ty.lim.max.map(|max| len > max).unwrap_or(false) {
27            return Err(TrapError::TableOrElementAccessOutOfBounds.into());
28        }
29        let limits_prime = Limits {
30            min: len,
31            max: self.ty.lim.max,
32        };
33
34        self.elem.extend(vec![reff; n.into_usize()]);
35
36        self.ty.lim = limits_prime;
37        Ok(())
38    }
39}