use ModuleInstance methods for validation

This commit is contained in:
Svyatoslav Nikolsky
2017-06-23 10:39:31 +03:00
parent c944b4c91e
commit 8209ff7d6d
4 changed files with 64 additions and 122 deletions

View File

@ -39,14 +39,8 @@ pub enum ExportEntryType {
Global(VariableType),
}
pub struct InstantiationParams {
}
/// Module instance API.
pub trait ModuleInstanceInterface {
/// Run instantiation-time procedures (validation and start function [if any] call). Module is not completely validated until this call.
//fn instantiate<'a>(&self, is_user_module: bool, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>) -> Result<(), Error>;
/// Execute function with the given index.
fn execute_index(&self, index: u32, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error>;
/// Execute function with the given export name.
@ -214,6 +208,7 @@ impl ModuleInstance {
})
}
/// Run instantiation-time procedures (validation). Module is not completely validated until this call.
pub fn instantiate<'a>(&mut self, is_user_module: bool, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>) -> Result<(), Error> {
// validate start section
if let Some(start_function) = self.module.start_section() {
@ -319,24 +314,27 @@ impl ModuleInstance {
let function_body = code_section.bodies().get(index as usize).ok_or(Error::Validation(format!("Missing body for function {}", index)))?;
let mut locals = function_type.params().to_vec();
locals.extend(function_body.locals().iter().flat_map(|l| repeat(l.value_type()).take(l.count() as usize)));
let mut context = FunctionValidationContext::new(
&self.module,
&self.imports,
&locals,
DEFAULT_VALUE_STACK_LIMIT,
DEFAULT_FRAME_STACK_LIMIT,
&function_type);
let block_type = function_type.return_type().map(BlockType::Value).unwrap_or(BlockType::NoResult);
Validator::validate_function(&mut context, block_type, function_body.code().elements())
.map_err(|e| {
if let Error::Validation(msg) = e {
Error::Validation(format!("Function #{} validation error: {}", index, msg))
} else {
e
}
})?;
self.functions_labels.insert(index as u32, context.function_labels());
let function_labels = {
let mut context = FunctionValidationContext::new(
self,
&locals,
DEFAULT_VALUE_STACK_LIMIT,
DEFAULT_FRAME_STACK_LIMIT,
&function_type);
let block_type = function_type.return_type().map(BlockType::Value).unwrap_or(BlockType::NoResult);
Validator::validate_function(&mut context, block_type, function_body.code().elements())
.map_err(|e| {
if let Error::Validation(msg) = e {
Error::Validation(format!("Function #{} validation error: {}", index, msg))
} else {
e
}
})?;
context.function_labels()
};
self.functions_labels.insert(index as u32, function_labels);
}
}
@ -369,6 +367,7 @@ impl ModuleInstance {
Ok(())
}
/// Run start function [if any].
pub fn run_start_function(&self) -> Result<(), Error> {
// execute start function (if any)
if let Some(start_function) = self.module.start_section() {