TableElementType

This commit is contained in:
Svyatoslav Nikolsky
2017-06-21 11:35:09 +03:00
parent 4eb04d2732
commit 08c8bf330e
6 changed files with 70 additions and 23 deletions

View File

@ -1,7 +1,7 @@
use std::io; use std::io;
use super::{ use super::{
Deserialize, Serialize, Error, VarUint7, VarInt7, VarUint32, VarUint1, Deserialize, Serialize, Error, VarUint7, VarInt7, VarUint32, VarUint1,
ValueType ValueType, TableElementType
}; };
/// Global definition struct /// Global definition struct
@ -53,7 +53,7 @@ impl Serialize for GlobalType {
/// Table entry /// Table entry
#[derive(Debug)] #[derive(Debug)]
pub struct TableType { pub struct TableType {
elem_type: i8, elem_type: TableElementType,
limits: ResizableLimits, limits: ResizableLimits,
} }
@ -61,22 +61,26 @@ impl TableType {
/// New table definition /// New table definition
pub fn new(min: u32, max: Option<u32>) -> Self { pub fn new(min: u32, max: Option<u32>) -> Self {
TableType { TableType {
elem_type: 0, elem_type: TableElementType::AnyFunc,
limits: ResizableLimits::new(min, max), limits: ResizableLimits::new(min, max),
} }
} }
/// Table memory specification /// Table memory specification
pub fn limits(&self) -> &ResizableLimits { &self.limits } pub fn limits(&self) -> &ResizableLimits { &self.limits }
/// Table element type
pub fn elem_type(&self) -> TableElementType { self.elem_type }
} }
impl Deserialize for TableType { impl Deserialize for TableType {
type Error = Error; type Error = Error;
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> { fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
let elem_type = VarInt7::deserialize(reader)?; let elem_type = TableElementType::deserialize(reader)?;
let limits = ResizableLimits::deserialize(reader)?; let limits = ResizableLimits::deserialize(reader)?;
Ok(TableType { Ok(TableType {
elem_type: elem_type.into(), elem_type: elem_type,
limits: limits, limits: limits,
}) })
} }
@ -86,7 +90,7 @@ impl Serialize for TableType {
type Error = Error; type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> { fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
VarInt7::from(self.elem_type).serialize(writer)?; self.elem_type.serialize(writer)?;
self.limits.serialize(writer) self.limits.serialize(writer)
} }
} }

View File

@ -26,7 +26,7 @@ pub use self::primitives::{
VarUint32, VarUint7, VarUint1, VarInt7, Uint32, VarInt32, VarInt64, VarUint32, VarUint7, VarUint1, VarInt7, Uint32, VarInt32, VarInt64,
Uint64, VarUint64, CountedList, CountedWriter, CountedListWriter, Uint64, VarUint64, CountedList, CountedWriter, CountedListWriter,
}; };
pub use self::types::{Type, ValueType, BlockType, FunctionType}; pub use self::types::{Type, ValueType, BlockType, FunctionType, TableElementType};
pub use self::ops::{Opcode, Opcodes, InitExpr}; pub use self::ops::{Opcode, Opcodes, InitExpr};
pub use self::func::{Func, FuncBody, Local}; pub use self::func::{Func, FuncBody, Local};
pub use self::segment::{ElementSegment, DataSegment}; pub use self::segment::{ElementSegment, DataSegment};
@ -69,6 +69,8 @@ pub enum Error {
HeapOther(String), HeapOther(String),
/// Invalid/unknown value type declaration /// Invalid/unknown value type declaration
UnknownValueType(i8), UnknownValueType(i8),
/// Invalid/unknown table element type declaration
UnknownTableElementType(i8),
/// Non-utf8 string /// Non-utf8 string
NonUtf8String, NonUtf8String,
/// Unknown external kind code /// Unknown external kind code

View File

@ -200,3 +200,35 @@ impl Serialize for FunctionType {
Ok(()) Ok(())
} }
} }
/// Table element type.
#[derive(Clone, Copy, PartialEq, Debug)]
pub enum TableElementType {
/// A reference to a function with any signature.
AnyFunc,
}
impl Deserialize for TableElementType {
type Error = Error;
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
let val = VarInt7::deserialize(reader)?;
match val.into() {
-0x10 => Ok(TableElementType::AnyFunc),
_ => Err(Error::UnknownTableElementType(val.into())),
}
}
}
impl Serialize for TableElementType {
type Error = Error;
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
let val: VarInt7 = match self {
TableElementType::AnyFunc => 0x70,
}.into();
val.serialize(writer)?;
Ok(())
}
}

View File

@ -177,7 +177,7 @@ impl ModuleInstance {
let tables = match module.table_section() { let tables = match module.table_section() {
Some(table_section) => table_section.entries() Some(table_section) => table_section.entries()
.iter() .iter()
.map(|tt| TableInstance::new(VariableType::AnyFunc, tt)) // TODO: actual table type .map(|tt| TableInstance::new(tt))
.collect::<Result<Vec<_>, _>>()?, .collect::<Result<Vec<_>, _>>()?,
None => Vec::new(), None => Vec::new(),
}; };

View File

@ -17,9 +17,10 @@ pub struct TableInstance {
impl TableInstance { impl TableInstance {
/// New instance of the table /// New instance of the table
pub fn new(variable_type: VariableType, table_type: &TableType) -> Result<Arc<Self>, Error> { pub fn new(table_type: &TableType) -> Result<Arc<Self>, Error> {
check_limits(table_type.limits())?; check_limits(table_type.limits())?;
let variable_type = table_type.elem_type().into();
Ok(Arc::new(TableInstance { Ok(Arc::new(TableInstance {
variable_type: variable_type, variable_type: variable_type,
buffer: RwLock::new( buffer: RwLock::new(

View File

@ -1,5 +1,5 @@
use parking_lot::RwLock; use parking_lot::RwLock;
use elements::{GlobalType, ValueType}; use elements::{GlobalType, ValueType, TableElementType};
use interpreter::Error; use interpreter::Error;
use interpreter::value::RuntimeValue; use interpreter::value::RuntimeValue;
@ -98,3 +98,11 @@ impl From<ValueType> for VariableType {
} }
} }
} }
impl From<TableElementType> for VariableType {
fn from(tt: TableElementType) -> VariableType {
match tt {
TableElementType::AnyFunc => VariableType::AnyFunc,
}
}
}