2017-12-01 19:42:34 +03:00
|
|
|
use elements::{MemoryType, TableType, GlobalType, Type};
|
2017-12-05 17:10:40 +01:00
|
|
|
use elements::{BlockType, ValueType};
|
2017-12-01 19:42:34 +03:00
|
|
|
use validation::Error;
|
|
|
|
|
|
|
|
pub struct ModuleContext {
|
|
|
|
pub memories: Vec<MemoryType>,
|
|
|
|
pub tables: Vec<TableType>,
|
|
|
|
pub globals: Vec<GlobalType>,
|
|
|
|
pub types: Vec<Type>,
|
|
|
|
pub func_type_indexes: Vec<u32>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ModuleContext {
|
|
|
|
pub fn memories(&self) -> &[MemoryType] {
|
|
|
|
&self.memories
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn tables(&self) -> &[TableType] {
|
|
|
|
&self.tables
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn globals(&self) -> &[GlobalType] {
|
|
|
|
&self.globals
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn types(&self) -> &[Type] {
|
|
|
|
&self.types
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn func_type_indexes(&self) -> &[u32] {
|
|
|
|
&self.func_type_indexes
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn require_memory(&self, idx: u32) -> Result<(), Error> {
|
|
|
|
if self.memories().get(idx as usize).is_none() {
|
|
|
|
return Err(Error(format!("Memory at index {} doesn't exists", idx)));
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2017-12-05 12:03:06 +01:00
|
|
|
pub fn require_table(&self, idx: u32) -> Result<&TableType, Error> {
|
2017-12-01 19:42:34 +03:00
|
|
|
let table = match self.tables().get(idx as usize) {
|
|
|
|
Some(table) => table,
|
|
|
|
None => {
|
|
|
|
return Err(Error(format!("Table at index {} doesn't exists", idx)));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-12-05 12:03:06 +01:00
|
|
|
Ok(table)
|
2017-12-01 19:42:34 +03:00
|
|
|
}
|
|
|
|
|
2017-12-05 12:06:41 +01:00
|
|
|
pub fn require_function(&self, idx: u32) -> Result<(&[ValueType], BlockType), Error> {
|
2017-12-01 19:42:34 +03:00
|
|
|
let ty_idx = match self.func_type_indexes().get(idx as usize) {
|
|
|
|
Some(ty_idx) => *ty_idx,
|
|
|
|
None => {
|
|
|
|
return Err(Error(
|
|
|
|
format!("Function at index {} doesn't exists", idx),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
self.require_function_type(ty_idx)
|
|
|
|
}
|
|
|
|
|
2017-12-05 12:06:41 +01:00
|
|
|
pub fn require_function_type(&self, idx: u32) -> Result<(&[ValueType], BlockType), Error> {
|
2017-12-01 19:42:34 +03:00
|
|
|
let ty = match self.types().get(idx as usize) {
|
|
|
|
Some(&Type::Function(ref func_ty)) => func_ty,
|
|
|
|
None => {
|
|
|
|
return Err(Error(
|
|
|
|
format!("Type at index {} doesn't exists", idx),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-12-05 12:06:41 +01:00
|
|
|
let params = ty.params();
|
2017-12-01 19:42:34 +03:00
|
|
|
let return_ty = ty.return_type()
|
|
|
|
.map(BlockType::Value)
|
|
|
|
.unwrap_or(BlockType::NoResult);
|
|
|
|
Ok((params, return_ty))
|
|
|
|
}
|
2017-12-05 12:03:06 +01:00
|
|
|
|
|
|
|
pub fn require_global(
|
|
|
|
&self,
|
|
|
|
idx: u32,
|
|
|
|
mutability: Option<bool>,
|
|
|
|
) -> Result<&GlobalType, Error> {
|
|
|
|
let global = match self.globals().get(idx as usize) {
|
|
|
|
Some(global) => global,
|
|
|
|
None => {
|
|
|
|
return Err(Error(format!("Global at index {} doesn't exists", idx)));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
if let Some(expected_mutable) = mutability {
|
|
|
|
if expected_mutable && !global.is_mutable() {
|
|
|
|
return Err(Error(format!("Expected global {} to be mutable", idx)));
|
|
|
|
}
|
|
|
|
if !expected_mutable && global.is_mutable() {
|
|
|
|
return Err(Error(format!("Expected global {} to be immutable", idx)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(global)
|
|
|
|
}
|
2017-12-01 19:42:34 +03:00
|
|
|
}
|