2017-04-21 14:35:12 +03:00
|
|
|
use std::u32;
|
2017-12-12 18:18:08 +01:00
|
|
|
use std::fmt;
|
2017-12-18 16:13:14 +03:00
|
|
|
use std::cell::RefCell;
|
2017-12-18 16:46:04 +03:00
|
|
|
use elements::{ResizableLimits, TableType};
|
2017-11-25 22:55:45 +03:00
|
|
|
use interpreter::Error;
|
2018-01-05 13:10:01 +03:00
|
|
|
use interpreter::module::FuncRef;
|
2017-06-08 10:49:32 +03:00
|
|
|
use interpreter::module::check_limits;
|
2017-04-21 14:35:12 +03:00
|
|
|
|
|
|
|
/// Table instance.
|
2017-12-19 20:46:05 +03:00
|
|
|
pub struct TableInstance {
|
2017-09-04 12:00:01 +03:00
|
|
|
/// Table limits.
|
|
|
|
limits: ResizableLimits,
|
2017-04-21 14:35:12 +03:00
|
|
|
/// Table memory buffer.
|
2018-01-05 13:10:01 +03:00
|
|
|
buffer: RefCell<Vec<Option<FuncRef>>>,
|
2017-07-31 11:58:24 +03:00
|
|
|
}
|
|
|
|
|
2017-12-19 20:46:05 +03:00
|
|
|
impl fmt::Debug for TableInstance {
|
2017-12-13 18:15:13 +01:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.debug_struct("TableInstance")
|
2017-12-12 18:18:08 +01:00
|
|
|
.field("limits", &self.limits)
|
2017-12-18 16:13:14 +03:00
|
|
|
.field("buffer.len", &self.buffer.borrow().len())
|
2017-12-12 18:18:08 +01:00
|
|
|
.finish()
|
2017-12-13 18:15:13 +01:00
|
|
|
}
|
2017-12-12 18:18:08 +01:00
|
|
|
}
|
|
|
|
|
2017-12-19 20:46:05 +03:00
|
|
|
impl TableInstance {
|
2017-05-22 19:54:56 +03:00
|
|
|
/// New instance of the table
|
2017-12-09 15:32:19 +01:00
|
|
|
pub fn new(table_type: &TableType) -> Result<Self, Error> {
|
2017-06-08 10:49:32 +03:00
|
|
|
check_limits(table_type.limits())?;
|
2017-12-09 15:32:19 +01:00
|
|
|
Ok(TableInstance {
|
2017-09-04 12:00:01 +03:00
|
|
|
limits: table_type.limits().clone(),
|
2017-12-18 16:46:04 +03:00
|
|
|
buffer: RefCell::new(vec![None; table_type.limits().initial() as usize]),
|
2017-12-09 15:32:19 +01:00
|
|
|
})
|
2017-04-21 14:35:12 +03:00
|
|
|
}
|
|
|
|
|
2017-09-04 12:00:01 +03:00
|
|
|
/// Return table limits.
|
|
|
|
pub fn limits(&self) -> &ResizableLimits {
|
|
|
|
&self.limits
|
|
|
|
}
|
|
|
|
|
2017-05-22 19:54:56 +03:00
|
|
|
/// Get the specific value in the table
|
2018-01-05 13:10:01 +03:00
|
|
|
pub fn get(&self, offset: u32) -> Result<FuncRef, Error> {
|
2017-12-18 16:13:14 +03:00
|
|
|
let buffer = self.buffer.borrow();
|
2017-04-26 15:41:22 +03:00
|
|
|
let buffer_len = buffer.len();
|
2017-12-18 16:46:04 +03:00
|
|
|
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
|
|
|
|
)),
|
|
|
|
)?;
|
2017-12-09 15:32:19 +01:00
|
|
|
Ok(table_elem.ok_or(Error::Table(format!(
|
|
|
|
"trying to read uninitialized element on index {}",
|
|
|
|
offset
|
|
|
|
)))?)
|
2017-04-26 15:41:22 +03:00
|
|
|
}
|
|
|
|
|
2017-12-09 15:32:19 +01:00
|
|
|
/// Set the table element to the specified function.
|
2018-01-05 13:10:01 +03:00
|
|
|
pub fn set(&self, offset: u32, value: FuncRef) -> Result<(), Error> {
|
2017-12-18 16:13:14 +03:00
|
|
|
let mut buffer = self.buffer.borrow_mut();
|
2017-04-26 15:41:22 +03:00
|
|
|
let buffer_len = buffer.len();
|
2017-12-09 15:32:19 +01:00
|
|
|
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(())
|
2017-04-21 14:35:12 +03:00
|
|
|
}
|
|
|
|
}
|