TableInstance is specialized for any func

This commit is contained in:
Sergey Pepyakin
2017-12-09 15:32:19 +01:00
parent 0a92032956
commit 987fffb6c3
4 changed files with 149 additions and 148 deletions

View File

@ -1,20 +1,19 @@
use std::u32;
use std::sync::Arc;
use parking_lot::RwLock;
use elements::{TableType, ResizableLimits};
use interpreter::Error;
use interpreter::module::check_limits;
use interpreter::variable::{VariableInstance, VariableType};
use interpreter::value::RuntimeValue;
use interpreter::store::FuncId;
/// Table instance.
pub struct TableInstance {
/// Table limits.
limits: ResizableLimits,
/// Table variables type.
variable_type: VariableType,
/// Table memory buffer.
buffer: RwLock<Vec<TableElement>>,
buffer: RwLock<Vec<Option<FuncId>>>,
}
/// Table element. Cloneable wrapper around VariableInstance.
@ -24,17 +23,14 @@ struct TableElement {
impl TableInstance {
/// New instance of the table
pub fn new(table_type: &TableType) -> Result<Arc<Self>, Error> {
pub fn new(table_type: &TableType) -> Result<Self, Error> {
check_limits(table_type.limits())?;
let variable_type = table_type.elem_type().into();
Ok(Arc::new(TableInstance {
Ok(TableInstance {
limits: table_type.limits().clone(),
variable_type: variable_type,
buffer: RwLock::new(
vec![TableElement::new(VariableInstance::new(true, variable_type, RuntimeValue::Null)?); table_type.limits().initial() as usize]
vec![None; table_type.limits().initial() as usize]
),
}))
})
}
/// Return table limits.
@ -44,51 +40,34 @@ impl TableInstance {
/// Get variable type for this table.
pub fn variable_type(&self) -> VariableType {
self.variable_type
panic!("TODO")
}
/// Get the specific value in the table
pub fn get(&self, offset: u32) -> Result<RuntimeValue, Error> {
pub fn get(&self, offset: u32) -> Result<FuncId, Error> {
let buffer = self.buffer.read();
let buffer_len = buffer.len();
buffer.get(offset as usize)
.map(|v| v.var.get())
.ok_or(Error::Table(format!("trying to read table item with index {} when there are only {} items", offset, 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
)))?)
}
/// Set the table value from raw slice
pub fn set_raw(&self, mut offset: u32, module_name: String, value: &[u32]) -> Result<(), Error> {
for val in value {
match self.variable_type {
VariableType::AnyFunc => self.set(offset, RuntimeValue::AnyFunc(module_name.clone(), *val))?,
_ => return Err(Error::Table(format!("table of type {:?} is not supported", self.variable_type))),
}
offset += 1;
}
Ok(())
}
/// Set the table from runtime variable value
pub fn set(&self, offset: u32, value: RuntimeValue) -> Result<(), Error> {
/// Set the table element to the specified function.
pub fn set(&self, offset: u32, value: FuncId) -> Result<(), Error> {
let mut buffer = self.buffer.write();
let buffer_len = buffer.len();
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)))
.and_then(|v| v.var.set(value))
}
}
impl TableElement {
pub fn new(var: VariableInstance) -> Self {
TableElement {
var: var,
}
}
}
impl Clone for TableElement {
fn clone(&self) -> Self {
TableElement::new(VariableInstance::new(self.var.is_mutable(), self.var.variable_type(), self.var.get())
.expect("it only fails when variable_type() != passed variable value; both are read from already constructed var; qed"))
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(())
}
}