74 lines
1.9 KiB
Rust
Raw Normal View History

2017-04-21 14:35:12 +03:00
use std::u32;
2017-04-26 15:41:22 +03:00
use parking_lot::RwLock;
use elements::{TableType, ResizableLimits};
2017-11-25 22:55:45 +03:00
use interpreter::Error;
2017-06-08 10:49:32 +03:00
use interpreter::module::check_limits;
2017-04-26 15:41:22 +03:00
use interpreter::variable::{VariableInstance, VariableType};
2017-04-21 14:35:12 +03:00
use interpreter::value::RuntimeValue;
use interpreter::store::FuncId;
2017-04-21 14:35:12 +03:00
/// Table instance.
2017-11-25 22:55:45 +03:00
pub struct TableInstance {
/// Table limits.
limits: ResizableLimits,
2017-04-21 14:35:12 +03:00
/// Table memory buffer.
buffer: RwLock<Vec<Option<FuncId>>>,
2017-07-31 11:58:24 +03:00
}
/// Table element. Cloneable wrapper around VariableInstance.
2017-11-25 22:55:45 +03:00
struct TableElement {
pub var: VariableInstance,
2017-04-21 14:35:12 +03:00
}
2017-11-25 22:55:45 +03:00
impl TableInstance {
2017-05-22 19:54:56 +03:00
/// New instance of the table
pub fn new(table_type: &TableType) -> Result<Self, Error> {
2017-06-08 10:49:32 +03:00
check_limits(table_type.limits())?;
Ok(TableInstance {
limits: table_type.limits().clone(),
2017-04-26 15:41:22 +03:00
buffer: RwLock::new(
vec![None; table_type.limits().initial() as usize]
2017-04-26 15:41:22 +03:00
),
})
2017-04-21 14:35:12 +03:00
}
/// Return table limits.
pub fn limits(&self) -> &ResizableLimits {
&self.limits
}
/// Get variable type for this table.
pub fn variable_type(&self) -> VariableType {
panic!("TODO")
}
2017-05-22 19:54:56 +03:00
/// Get the specific value in the table
pub fn get(&self, offset: u32) -> Result<FuncId, Error> {
2017-04-26 15:41:22 +03:00
let buffer = self.buffer.read();
let buffer_len = buffer.len();
let table_elem = buffer.get(offset as usize).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
)))?)
2017-04-26 15:41:22 +03:00
}
/// Set the table element to the specified function.
pub fn set(&self, offset: u32, value: FuncId) -> Result<(), Error> {
2017-04-26 15:41:22 +03:00
let mut buffer = self.buffer.write();
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(())
2017-04-21 14:35:12 +03:00
}
}