use std::u32; use std::fmt; use std::rc::Rc; use std::cell::RefCell; use elements::{ResizableLimits, TableType}; use interpreter::Error; use interpreter::module::check_limits; use interpreter::func::FuncInstance; /// Table instance. pub struct TableInstance { /// Table limits. limits: ResizableLimits, /// Table memory buffer. buffer: RefCell>>>, } impl fmt::Debug for TableInstance { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("TableInstance") .field("limits", &self.limits) .field("buffer.len", &self.buffer.borrow().len()) .finish() } } impl TableInstance { /// New instance of the table pub fn new(table_type: &TableType) -> Result { check_limits(table_type.limits())?; Ok(TableInstance { limits: table_type.limits().clone(), buffer: RefCell::new(vec![None; table_type.limits().initial() as usize]), }) } /// Return table limits. pub fn limits(&self) -> &ResizableLimits { &self.limits } /// Get the specific value in the table pub fn get(&self, offset: u32) -> Result, Error> { let buffer = self.buffer.borrow(); let buffer_len = buffer.len(); let table_elem = buffer.get(offset as usize).cloned().ok_or( Error::Table(format!( "trying to read table item with index {} when there are only {} items", offset, buffer_len )), )?; Ok(table_elem.ok_or(Error::Table(format!( "trying to read uninitialized element on index {}", offset )))?) } /// Set the table element to the specified function. pub fn set(&self, offset: u32, value: Rc) -> Result<(), Error> { let mut buffer = self.buffer.borrow_mut(); let buffer_len = buffer.len(); let table_elem = buffer.get_mut(offset as usize).ok_or(Error::Table(format!( "trying to update table item with index {} when there are only {} items", offset, buffer_len )))?; *table_elem = Some(value); Ok(()) } }