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

View File

@ -4,8 +4,9 @@ mod module;
mod func;
use std::fmt;
use elements::{Module, ResizableLimits, MemoryType, TableType};
use elements::{Module, ResizableLimits, MemoryType, TableType, GlobalType, External};
use common::stack;
use self::module::ModuleContext;
pub struct Error(String);
@ -22,8 +23,6 @@ impl From<stack::Error> for Error {
}
pub fn validate_module(module: &Module) -> Result<(), Error> {
// TODO: Functions
if let Some(table_section) = module.table_section() {
table_section
.entries()
@ -43,6 +42,43 @@ pub fn validate_module(module: &Module) -> Result<(), Error> {
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 {
fn validate(&self) -> Result<(), Error> {
if let Some(maximum) = self.maximum() {

View File

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