Hide validation stuff.
This commit is contained in:
parent
469e9ef6b1
commit
aae9a3c129
53
src/lib.rs
53
src/lib.rs
|
@ -10,10 +10,15 @@ extern crate byteorder;
|
|||
|
||||
use std::fmt;
|
||||
use std::error;
|
||||
use std::path::Path;
|
||||
use std::collections::HashMap;
|
||||
use parity_wasm::elements::Module;
|
||||
|
||||
/// Internal interpreter error.
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
/// Module validation error. Might occur only at load time.
|
||||
Validation(String),
|
||||
/// Error while instantiating a module. Might occur when provided
|
||||
/// with incorrect exports (i.e. linkage failure).
|
||||
Instantiation(String),
|
||||
|
@ -38,6 +43,7 @@ pub enum Error {
|
|||
impl Into<String> for Error {
|
||||
fn into(self) -> String {
|
||||
match self {
|
||||
Error::Validation(s) => s,
|
||||
Error::Instantiation(s) => s,
|
||||
Error::Function(s) => s,
|
||||
Error::Table(s) => s,
|
||||
|
@ -54,6 +60,7 @@ impl Into<String> for Error {
|
|||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Error::Validation(ref s) => write!(f, "Validation: {}", s),
|
||||
Error::Instantiation(ref s) => write!(f, "Instantiation: {}", s),
|
||||
Error::Function(ref s) => write!(f, "Function: {}", s),
|
||||
Error::Table(ref s) => write!(f, "Table: {}", s),
|
||||
|
@ -72,6 +79,7 @@ impl fmt::Display for Error {
|
|||
impl error::Error for Error {
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
Error::Validation(ref s) => s,
|
||||
Error::Instantiation(ref s) => s,
|
||||
Error::Function(ref s) => s,
|
||||
Error::Table(ref s) => s,
|
||||
|
@ -85,12 +93,19 @@ impl error::Error for Error {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
impl<U> From<U> for Error where U: host::HostError + Sized {
|
||||
fn from(e: U) -> Self {
|
||||
Error::Host(Box::new(e))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<validation::Error> for Error {
|
||||
fn from(e: validation::Error) -> Error {
|
||||
Error::Validation(e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<::common::stack::Error> for Error {
|
||||
fn from(e: ::common::stack::Error) -> Self {
|
||||
Error::Stack(e.to_string())
|
||||
|
@ -122,3 +137,41 @@ pub use self::module::{ModuleInstance, ModuleRef, ExternVal, NotStartedModuleRef
|
|||
pub use self::global::{GlobalInstance, GlobalRef};
|
||||
pub use self::func::{FuncInstance, FuncRef};
|
||||
pub use self::types::{Signature, ValueType};
|
||||
|
||||
pub struct LoadedModule {
|
||||
labels: HashMap<usize, HashMap<usize, usize>>,
|
||||
module: Module,
|
||||
}
|
||||
|
||||
impl LoadedModule {
|
||||
pub(crate) fn module(&self) -> &Module {
|
||||
&self.module
|
||||
}
|
||||
|
||||
pub(crate) fn labels(&self) -> &HashMap<usize, HashMap<usize, usize>> {
|
||||
&self.labels
|
||||
}
|
||||
|
||||
pub fn into_module(self) -> Module {
|
||||
self.module
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_from_module(module: Module) -> Result<LoadedModule, Error> {
|
||||
use validation::{validate_module, ValidatedModule};
|
||||
let ValidatedModule {
|
||||
labels,
|
||||
module,
|
||||
} = validate_module(module)?;
|
||||
|
||||
Ok(LoadedModule {
|
||||
labels,
|
||||
module,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn load_from_buffer<B: AsRef<[u8]>>(buffer: B) -> Result<LoadedModule, Error> {
|
||||
let module = parity_wasm::elements::deserialize_buffer(buffer.as_ref())
|
||||
.map_err(|e: parity_wasm::elements::Error| Error::Validation(e.to_string()))?;
|
||||
load_from_module(module)
|
||||
}
|
||||
|
|
|
@ -4,14 +4,13 @@ use std::fmt;
|
|||
use std::collections::HashMap;
|
||||
use std::borrow::Cow;
|
||||
use parity_wasm::elements::{External, InitExpr, Internal, Opcode, ResizableLimits, Type};
|
||||
use {Error, Signature, MemoryInstance, RuntimeValue, TableInstance};
|
||||
use {LoadedModule, Error, Signature, MemoryInstance, RuntimeValue, TableInstance};
|
||||
use imports::ImportResolver;
|
||||
use global::{GlobalInstance, GlobalRef};
|
||||
use func::{FuncRef, FuncBody, FuncInstance};
|
||||
use table::TableRef;
|
||||
use memory::MemoryRef;
|
||||
use host::Externals;
|
||||
use validation::ValidatedModule;
|
||||
use common::{DEFAULT_MEMORY_INDEX, DEFAULT_TABLE_INDEX};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
@ -158,10 +157,10 @@ impl ModuleInstance {
|
|||
}
|
||||
|
||||
fn alloc_module(
|
||||
validated_module: &ValidatedModule,
|
||||
loaded_module: &LoadedModule,
|
||||
extern_vals: &[ExternVal]
|
||||
) -> Result<ModuleRef, Error> {
|
||||
let module = validated_module.module();
|
||||
let module = loaded_module.module();
|
||||
let instance = ModuleRef(Rc::new(ModuleInstance::default()));
|
||||
|
||||
for &Type::Function(ref ty) in module.type_section().map(|ts| ts.types()).unwrap_or(&[]) {
|
||||
|
@ -227,7 +226,7 @@ impl ModuleInstance {
|
|||
}
|
||||
}
|
||||
|
||||
let labels = validated_module.labels();
|
||||
let labels = loaded_module.labels();
|
||||
{
|
||||
let funcs = module.function_section().map(|fs| fs.entries()).unwrap_or(
|
||||
&[],
|
||||
|
@ -327,12 +326,12 @@ impl ModuleInstance {
|
|||
}
|
||||
|
||||
fn instantiate_with_externvals(
|
||||
validated_module: &ValidatedModule,
|
||||
loaded_module: &LoadedModule,
|
||||
extern_vals: &[ExternVal],
|
||||
) -> Result<ModuleRef, Error> {
|
||||
let module = validated_module.module();
|
||||
let module = loaded_module.module();
|
||||
|
||||
let module_ref = ModuleInstance::alloc_module(validated_module, extern_vals)?;
|
||||
let module_ref = ModuleInstance::alloc_module(loaded_module, extern_vals)?;
|
||||
|
||||
for element_segment in module.elements_section().map(|es| es.entries()).unwrap_or(
|
||||
&[],
|
||||
|
@ -371,10 +370,10 @@ impl ModuleInstance {
|
|||
}
|
||||
|
||||
pub fn new<'m, I: ImportResolver>(
|
||||
validated_module: &'m ValidatedModule,
|
||||
loaded_module: &'m LoadedModule,
|
||||
imports: &I,
|
||||
) -> Result<NotStartedModuleRef<'m>, Error> {
|
||||
let module = validated_module.module();
|
||||
let module = loaded_module.module();
|
||||
|
||||
let mut extern_vals = Vec::new();
|
||||
for import_entry in module.import_section().map(|s| s.entries()).unwrap_or(&[]) {
|
||||
|
@ -406,9 +405,9 @@ impl ModuleInstance {
|
|||
extern_vals.push(extern_val);
|
||||
}
|
||||
|
||||
let instance = Self::instantiate_with_externvals(validated_module, &extern_vals)?;
|
||||
let instance = Self::instantiate_with_externvals(loaded_module, &extern_vals)?;
|
||||
Ok(NotStartedModuleRef {
|
||||
validated_module,
|
||||
loaded_module,
|
||||
instance,
|
||||
})
|
||||
}
|
||||
|
@ -439,7 +438,7 @@ impl ModuleInstance {
|
|||
}
|
||||
|
||||
pub struct NotStartedModuleRef<'a> {
|
||||
validated_module: &'a ValidatedModule,
|
||||
loaded_module: &'a LoadedModule,
|
||||
instance: ModuleRef,
|
||||
}
|
||||
|
||||
|
@ -449,7 +448,7 @@ impl<'a> NotStartedModuleRef<'a> {
|
|||
}
|
||||
|
||||
pub fn run_start<'b, E: Externals>(self, state: &'b mut E) -> Result<ModuleRef, Error> {
|
||||
if let Some(start_fn_idx) = self.validated_module.module().start_section() {
|
||||
if let Some(start_fn_idx) = self.loaded_module.module().start_section() {
|
||||
let start_func = self.instance.func_by_index(start_fn_idx).expect(
|
||||
"Due to validation start function should exists",
|
||||
);
|
||||
|
@ -459,7 +458,7 @@ impl<'a> NotStartedModuleRef<'a> {
|
|||
}
|
||||
|
||||
pub fn assert_no_start(self) -> ModuleRef {
|
||||
assert!(self.validated_module.module().start_section().is_none());
|
||||
assert!(self.loaded_module.module().start_section().is_none());
|
||||
self.instance
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
|
||||
use parity_wasm::elements::{deserialize_buffer, MemoryType, TableType};
|
||||
use validation::{validate_module, ValidatedModule};
|
||||
use {
|
||||
Error, Signature, Externals, FuncInstance, FuncRef, HostError, ImportsBuilder,
|
||||
MemoryInstance, MemoryRef, TableInstance, TableRef, ModuleImportResolver, ModuleInstance, ModuleRef,
|
||||
RuntimeValue, TryInto,
|
||||
RuntimeValue, TryInto, LoadedModule, load_from_buffer,
|
||||
};
|
||||
use types::ValueType;
|
||||
use wabt::wat2wasm;
|
||||
|
@ -204,11 +203,9 @@ impl ModuleImportResolver for TestHost {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_wat(source: &str) -> ValidatedModule {
|
||||
fn parse_wat(source: &str) -> LoadedModule {
|
||||
let wasm_binary = wat2wasm(source).expect("Failed to parse wat source");
|
||||
let module = deserialize_buffer(&wasm_binary).expect("Failed to deserialize module");
|
||||
let validated_module = validate_module(module).expect("Failed to validate module");
|
||||
validated_module
|
||||
load_from_buffer(wasm_binary).expect("Failed to load parsed module")
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
use parity_wasm::elements::deserialize_file;
|
||||
use parity_wasm::elements::{GlobalType, MemoryType, Module, TableType};
|
||||
use {Error, Signature, FuncRef, GlobalInstance, GlobalRef, ImportsBuilder, MemoryInstance,
|
||||
use {
|
||||
Error, Signature, FuncRef, GlobalInstance, GlobalRef, ImportsBuilder, MemoryInstance,
|
||||
MemoryRef, ModuleImportResolver, ModuleInstance, NopExternals, RuntimeValue,
|
||||
TableInstance, TableRef};
|
||||
use validation::validate_module;
|
||||
TableInstance, TableRef, LoadedModule, load_from_buffer,
|
||||
};
|
||||
use std::fs::File;
|
||||
|
||||
struct Env {
|
||||
table_base: GlobalRef,
|
||||
|
@ -69,6 +70,14 @@ impl ModuleImportResolver for Env {
|
|||
}
|
||||
}
|
||||
|
||||
fn load_from_file(filename: &str) -> LoadedModule {
|
||||
use std::io::prelude::*;
|
||||
let mut file = File::open(filename).unwrap();
|
||||
let mut buf = Vec::new();
|
||||
file.read_to_end(&mut buf).unwrap();
|
||||
load_from_buffer(buf).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interpreter_inc_i32() {
|
||||
// Name of function contained in WASM file (note the leading underline)
|
||||
|
@ -76,14 +85,12 @@ fn interpreter_inc_i32() {
|
|||
// The WASM file containing the module and function
|
||||
const WASM_FILE: &str = &"res/cases/v1/inc_i32.wasm";
|
||||
|
||||
let module: Module =
|
||||
deserialize_file(WASM_FILE).expect("Failed to deserialize module from buffer");
|
||||
let validated_module = validate_module(module).expect("Failed to validate module");
|
||||
let module = load_from_file(WASM_FILE);
|
||||
|
||||
let env = Env::new();
|
||||
|
||||
let instance = ModuleInstance::new(
|
||||
&validated_module,
|
||||
&module,
|
||||
&ImportsBuilder::new().with_resolver("env", &env),
|
||||
).expect("Failed to instantiate module")
|
||||
.assert_no_start();
|
||||
|
@ -110,13 +117,11 @@ fn interpreter_accumulate_u8() {
|
|||
|
||||
|
||||
// Load the module-structure from wasm-file and add to program
|
||||
let module: Module =
|
||||
deserialize_file(WASM_FILE).expect("Failed to deserialize module from buffer");
|
||||
let validated_module = validate_module(module).expect("Failed to validate module");
|
||||
let module = load_from_file(WASM_FILE);
|
||||
|
||||
let env = Env::new();
|
||||
let instance = ModuleInstance::new(
|
||||
&validated_module,
|
||||
&module,
|
||||
&ImportsBuilder::new().with_resolver("env", &env),
|
||||
).expect("Failed to instantiate module")
|
||||
.assert_no_start();
|
||||
|
|
|
@ -38,8 +38,8 @@ impl From<stack::Error> for Error {
|
|||
|
||||
#[derive(Clone)]
|
||||
pub struct ValidatedModule {
|
||||
labels: HashMap<usize, HashMap<usize, usize>>,
|
||||
module: Module,
|
||||
pub labels: HashMap<usize, HashMap<usize, usize>>,
|
||||
pub module: Module,
|
||||
}
|
||||
|
||||
impl ValidatedModule {
|
||||
|
@ -50,10 +50,6 @@ impl ValidatedModule {
|
|||
pub fn into_module(self) -> Module {
|
||||
self.module
|
||||
}
|
||||
|
||||
pub(crate) fn labels(&self) -> &HashMap<usize, HashMap<usize, usize>> {
|
||||
&self.labels
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::Deref for ValidatedModule {
|
||||
|
|
Loading…
Reference in New Issue