Module fill context

This commit is contained in:
Sergey Pepyakin
2017-12-01 16:38:12 +03:00
parent 39f33cc32f
commit 859d985599
3 changed files with 58 additions and 22 deletions

View File

@ -4,7 +4,7 @@ use std::collections::HashMap;
use elements::{Opcode, BlockType, ValueType, TableElementType}; use elements::{Opcode, BlockType, ValueType, TableElementType};
use elements::{FunctionType, Type}; use elements::{FunctionType, Type};
use common::{DEFAULT_MEMORY_INDEX, DEFAULT_TABLE_INDEX}; use common::{DEFAULT_MEMORY_INDEX, DEFAULT_TABLE_INDEX};
use validation::module::ValidatedModule; use validation::module::ModuleContext;
use validation::Error; use validation::Error;
@ -17,7 +17,7 @@ const NATURAL_ALIGNMENT: u32 = 0xFFFFFFFF;
/// Function validation context. /// Function validation context.
pub struct FunctionValidationContext<'a> { pub struct FunctionValidationContext<'a> {
/// Wasm module /// Wasm module
module: &'a ValidatedModule, module: &'a ModuleContext,
/// Current instruction position. /// Current instruction position.
position: usize, position: usize,
/// Local variables. /// Local variables.
@ -546,7 +546,7 @@ impl Validator {
impl<'a> FunctionValidationContext<'a> { impl<'a> FunctionValidationContext<'a> {
pub fn new( pub fn new(
module: &'a ValidatedModule, module: &'a ModuleContext,
locals: &'a [ValueType], locals: &'a [ValueType],
value_stack_limit: usize, value_stack_limit: usize,
frame_stack_limit: usize, frame_stack_limit: usize,
@ -721,20 +721,15 @@ impl<'a> FunctionValidationContext<'a> {
} }
pub fn require_function(&self, idx: u32) -> Result<(Vec<ValueType>, BlockType), Error> { pub fn require_function(&self, idx: u32) -> Result<(Vec<ValueType>, BlockType), Error> {
let ty = match self.module.function_types().get(idx as usize) { let ty_idx = match self.module.func_type_indexes().get(idx as usize) {
Some(&Type::Function(ref func_ty)) => func_ty, Some(ty_idx) => *ty_idx,
None => { None => {
return Err(Error( return Err(Error(
format!("Function at index {} doesn't exists", idx), format!("Function at index {} doesn't exists", idx),
)); ));
} }
}; };
self.require_function_type(ty_idx)
let params = ty.params().to_vec();
let return_ty = ty.return_type()
.map(BlockType::Value)
.unwrap_or(BlockType::NoResult);
Ok((params, return_ty))
} }
pub fn require_function_type(&self, idx: u32) -> Result<(Vec<ValueType>, BlockType), Error> { pub fn require_function_type(&self, idx: u32) -> Result<(Vec<ValueType>, BlockType), Error> {

View File

@ -4,8 +4,9 @@ mod module;
mod func; mod func;
use std::fmt; use std::fmt;
use elements::{Module, ResizableLimits, MemoryType, TableType}; use elements::{Module, ResizableLimits, MemoryType, TableType, GlobalType, External};
use common::stack; use common::stack;
use self::module::ModuleContext;
pub struct Error(String); pub struct Error(String);
@ -22,8 +23,6 @@ impl From<stack::Error> for Error {
} }
pub fn validate_module(module: &Module) -> Result<(), Error> { pub fn validate_module(module: &Module) -> Result<(), Error> {
// TODO: Functions
if let Some(table_section) = module.table_section() { if let Some(table_section) = module.table_section() {
table_section table_section
.entries() .entries()
@ -43,6 +42,43 @@ pub fn validate_module(module: &Module) -> Result<(), Error> {
Ok(()) Ok(())
} }
fn prepare_context(module: &Module) -> ModuleContext {
// Copy types from module as is.
let types = module
.type_section()
.map(|ts| ts.types().into_iter().cloned().collect())
.unwrap_or_default();
// Fill elements with imported values.
let mut func_type_indexes = Vec::new();
let mut tables = Vec::new();
let mut memories = Vec::new();
let mut globals = Vec::new();
for import_entry in module
.import_section()
.map(|i| i.entries())
.unwrap_or_default()
{
match import_entry.external() {
&External::Function(idx) => func_type_indexes.push(idx),
&External::Table(ref table) => tables.push(table.clone()),
&External::Memory(ref memory) => memories.push(memory.clone()),
&External::Global(ref global) => globals.push(global.clone()),
}
}
// Concatenate elements with defined in the module.
ModuleContext {
types,
tables,
memories,
globals,
func_type_indexes,
}
}
impl ResizableLimits { impl ResizableLimits {
fn validate(&self) -> Result<(), Error> { fn validate(&self) -> Result<(), Error> {
if let Some(maximum) = self.maximum() { if let Some(maximum) = self.maximum() {

View File

@ -1,26 +1,31 @@
use elements::{MemoryType, TableType, GlobalType, Type}; use elements::{MemoryType, TableType, GlobalType, Type};
pub struct ValidatedModule { 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 ValidatedModule { impl ModuleContext {
pub fn memories(&self) -> &[MemoryType] { pub fn memories(&self) -> &[MemoryType] {
unimplemented!(); &self.memories
} }
pub fn tables(&self) -> &[TableType] { pub fn tables(&self) -> &[TableType] {
unimplemented!(); &self.tables
} }
pub fn globals(&self) -> &[GlobalType] { pub fn globals(&self) -> &[GlobalType] {
unimplemented!(); &self.globals
} }
pub fn types(&self) -> &[Type] { pub fn types(&self) -> &[Type] {
unimplemented!(); &self.types
} }
pub fn function_types(&self) -> &[Type] { pub fn func_type_indexes(&self) -> &[u32] {
unimplemented!(); &self.func_type_indexes
} }
} }