mirror of
https://github.com/fluencelabs/parity-wasm
synced 2025-06-19 18:01:46 +00:00
Module fill context
This commit is contained in:
@ -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> {
|
||||||
|
@ -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() {
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user