Merge pull request #119 from paritytech/env-refactor

Env refactor
This commit is contained in:
Svyatoslav Nikolsky 2017-11-27 20:36:14 +03:00 committed by GitHub
commit e85a8dec42
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 153 additions and 124 deletions

View File

@ -41,7 +41,7 @@ fn export_entry_performance(b: &mut Bencher) {
.build(); .build();
// add both modules to program // add both modules to program
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
program.add_module("callee_module", callee_module, None).unwrap(); program.add_module("callee_module", callee_module, None).unwrap();
let caller_module = program.add_module("caller_module", caller_module, None).unwrap(); let caller_module = program.add_module("caller_module", caller_module, None).unwrap();

View File

@ -16,8 +16,8 @@ fn main() {
// Intrepreter initialization. // Intrepreter initialization.
// It also initializes a default "env" module. // It also initializes a default "env" module.
let program = parity_wasm::ProgramInstance::with_env_params( let program = parity_wasm::ProgramInstance::with_emscripten_env(
interpreter::EnvParams { interpreter::EmscriptenParams {
total_stack: 128*1024, total_stack: 128*1024,
..Default::default() ..Default::default()
} }

View File

@ -17,8 +17,8 @@ fn main() {
// Intrepreter initialization. // Intrepreter initialization.
// It also initializes a default "env" module. // It also initializes a default "env" module.
let program = parity_wasm::ProgramInstance::with_env_params( let program = parity_wasm::ProgramInstance::with_emscripten_env(
interpreter::EnvParams { interpreter::EmscriptenParams {
total_stack: 128*1024, total_stack: 128*1024,
..Default::default() ..Default::default()
} }

View File

@ -59,7 +59,7 @@ fn try_deserialize(base_dir: &str, module_path: &str) -> Result<elements::Module
fn try_load(base_dir: &str, module_path: &str) -> Result<(), InterpreterError> { fn try_load(base_dir: &str, module_path: &str) -> Result<(), InterpreterError> {
let module = try_deserialize(base_dir, module_path).map_err(|e| parity_wasm::interpreter::Error::Program(format!("{:?}", e)))?; let module = try_deserialize(base_dir, module_path).map_err(|e| parity_wasm::interpreter::Error::Program(format!("{:?}", e)))?;
let program = ProgramInstance::new().expect("Failed creating program"); let program = ProgramInstance::new();
program.add_module("try_load", module, None).map(|_| ()) program.add_module("try_load", module, None).map(|_| ())
} }
@ -172,7 +172,7 @@ pub fn spec(name: &str) {
.expect(&format!("Failed to load json file {}", &fixture.json)); .expect(&format!("Failed to load json file {}", &fixture.json));
let spec: test::Spec = serde_json::from_reader(&mut f).expect("Failed to deserialize JSON file"); let spec: test::Spec = serde_json::from_reader(&mut f).expect("Failed to deserialize JSON file");
let program = ProgramInstance::new().expect("Failed creating program"); let program = ProgramInstance::new();
let mut last_module = None; let mut last_module = None;
for command in &spec.commands { for command in &spec.commands {
println!("command {:?}", command); println!("command {:?}", command);

View File

@ -1,10 +1,13 @@
//! This module provides some of the simplest exports
//! from the Emscripten runtime, such as `STACKTOP` or `abort`.
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use std::collections::HashMap; use std::collections::HashMap;
use builder::module; use builder::module;
use elements::{Module, ExportEntry, Internal, GlobalEntry, GlobalType, use elements::{Module, ExportEntry, Internal, GlobalEntry, GlobalType,
ValueType, InitExpr, Opcode, Opcodes}; ValueType, InitExpr, Opcode, Opcodes};
use interpreter::Error; use interpreter::Error;
use interpreter::env_native::NATIVE_INDEX_FUNC_MIN; use interpreter::native::NATIVE_INDEX_FUNC_MIN;
use interpreter::module::{ModuleInstanceInterface, ModuleInstance, ExecutionParams, use interpreter::module::{ModuleInstanceInterface, ModuleInstance, ExecutionParams,
ItemIndex, CallerContext, ExportEntryType, InternalFunctionReference, InternalFunction, FunctionSignature}; ItemIndex, CallerContext, ExportEntryType, InternalFunctionReference, InternalFunction, FunctionSignature};
use interpreter::memory::{MemoryInstance, LINEAR_MEMORY_PAGE_SIZE}; use interpreter::memory::{MemoryInstance, LINEAR_MEMORY_PAGE_SIZE};
@ -27,7 +30,7 @@ const DEFAULT_TABLE_BASE: u32 = 0;
/// Default tableBase variable value. /// Default tableBase variable value.
const DEFAULT_MEMORY_BASE: u32 = 0; const DEFAULT_MEMORY_BASE: u32 = 0;
/// Defaul table size. /// Default table size.
const DEFAULT_TABLE_SIZE: u32 = 64; const DEFAULT_TABLE_SIZE: u32 = 64;
/// Index of default memory. /// Index of default memory.
@ -70,8 +73,8 @@ const INDEX_FUNC_MIN_NONUSED: u32 = 4;
/// Max index of reserved function. /// Max index of reserved function.
const INDEX_FUNC_MAX: u32 = NATIVE_INDEX_FUNC_MIN - 1; const INDEX_FUNC_MAX: u32 = NATIVE_INDEX_FUNC_MIN - 1;
/// Environment parameters. /// Emscripten environment parameters.
pub struct EnvParams { pub struct EmscriptenParams {
/// Stack size in bytes. /// Stack size in bytes.
pub total_stack: u32, pub total_stack: u32,
/// Total memory size in bytes. /// Total memory size in bytes.
@ -84,24 +87,24 @@ pub struct EnvParams {
pub static_size: Option<u32>, pub static_size: Option<u32>,
} }
pub struct EnvModuleInstance { pub struct EmscriptenModuleInstance {
_params: EnvParams, _params: EmscriptenParams,
instance: ModuleInstance, instance: ModuleInstance,
} }
impl EnvModuleInstance { impl EmscriptenModuleInstance {
pub fn new(params: EnvParams, module: Module) -> Result<Self, Error> { pub fn new(params: EmscriptenParams, module: Module) -> Result<Self, Error> {
let mut instance = ModuleInstance::new(Weak::default(), "env".into(), module)?; let mut instance = ModuleInstance::new(Weak::default(), "env".into(), module)?;
instance.instantiate(None)?; instance.instantiate(None)?;
Ok(EnvModuleInstance { Ok(EmscriptenModuleInstance {
_params: params, _params: params,
instance: instance, instance: instance,
}) })
} }
} }
impl ModuleInstanceInterface for EnvModuleInstance { impl ModuleInstanceInterface for EmscriptenModuleInstance {
fn execute_index(&self, index: u32, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> { fn execute_index(&self, index: u32, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> {
self.instance.execute_index(index, params) self.instance.execute_index(index, params)
} }
@ -173,7 +176,7 @@ impl ModuleInstanceInterface for EnvModuleInstance {
} }
} }
pub fn env_module(params: EnvParams) -> Result<EnvModuleInstance, Error> { pub fn env_module(params: EmscriptenParams) -> Result<EmscriptenModuleInstance, Error> {
debug_assert!(params.total_stack < params.total_memory); debug_assert!(params.total_stack < params.total_memory);
debug_assert!((params.total_stack % LINEAR_MEMORY_PAGE_SIZE) == 0); debug_assert!((params.total_stack % LINEAR_MEMORY_PAGE_SIZE) == 0);
debug_assert!((params.total_memory % LINEAR_MEMORY_PAGE_SIZE) == 0); debug_assert!((params.total_memory % LINEAR_MEMORY_PAGE_SIZE) == 0);
@ -241,12 +244,12 @@ pub fn env_module(params: EnvParams) -> Result<EnvModuleInstance, Error> {
.build() .build()
.with_export(ExportEntry::new("getTotalMemory".into(), Internal::Function(INDEX_FUNC_GET_TOTAL_MEMORY))); .with_export(ExportEntry::new("getTotalMemory".into(), Internal::Function(INDEX_FUNC_GET_TOTAL_MEMORY)));
EnvModuleInstance::new(params, builder.build()) EmscriptenModuleInstance::new(params, builder.build())
} }
impl Default for EnvParams { impl Default for EmscriptenParams {
fn default() -> Self { fn default() -> Self {
EnvParams { EmscriptenParams {
total_stack: DEFAULT_TOTAL_STACK, total_stack: DEFAULT_TOTAL_STACK,
total_memory: DEFAULT_TOTAL_MEMORY, total_memory: DEFAULT_TOTAL_MEMORY,
allow_memory_growth: DEFAULT_ALLOW_MEMORY_GROWTH, allow_memory_growth: DEFAULT_ALLOW_MEMORY_GROWTH,
@ -256,7 +259,7 @@ impl Default for EnvParams {
} }
} }
impl EnvParams { impl EmscriptenParams {
fn max_memory(&self) -> Option<u32> { fn max_memory(&self) -> Option<u32> {
if self.allow_memory_growth { None } else { Some(self.total_memory) } if self.allow_memory_growth { None } else { Some(self.total_memory) }
} }

View File

@ -58,8 +58,6 @@ pub enum Error {
Value(String), Value(String),
/// Interpreter (code) error. /// Interpreter (code) error.
Interpreter(String), Interpreter(String),
/// Env module error.
Env(String),
/// Native module error. /// Native module error.
Native(String), Native(String),
/// Trap. /// Trap.
@ -83,7 +81,6 @@ impl Into<String> for Error {
Error::Stack(s) => s, Error::Stack(s) => s,
Error::Interpreter(s) => s, Error::Interpreter(s) => s,
Error::Value(s) => s, Error::Value(s) => s,
Error::Env(s) => s,
Error::Native(s) => s, Error::Native(s) => s,
Error::Trap(s) => format!("trap: {}", s), Error::Trap(s) => format!("trap: {}", s),
Error::User(e) => format!("user: {}", e), Error::User(e) => format!("user: {}", e),
@ -106,7 +103,6 @@ impl ::std::fmt::Display for Error {
Error::Stack(ref s) => write!(f, "Stack: {}", s), Error::Stack(ref s) => write!(f, "Stack: {}", s),
Error::Interpreter(ref s) => write!(f, "Interpreter: {}", s), Error::Interpreter(ref s) => write!(f, "Interpreter: {}", s),
Error::Value(ref s) => write!(f, "Value: {}", s), Error::Value(ref s) => write!(f, "Value: {}", s),
Error::Env(ref s) => write!(f, "Env: {}", s),
Error::Native(ref s) => write!(f, "Native: {}", s), Error::Native(ref s) => write!(f, "Native: {}", s),
Error::Trap(ref s) => write!(f, "Trap: {}", s), Error::Trap(ref s) => write!(f, "Trap: {}", s),
Error::User(ref e) => write!(f, "User: {}", e), Error::User(ref e) => write!(f, "User: {}", e),
@ -120,8 +116,8 @@ impl<U> From<U> for Error where U: UserError + Sized {
} }
} }
mod env; mod emscripten;
mod env_native; mod native;
mod imports; mod imports;
mod memory; mod memory;
mod module; mod module;
@ -143,5 +139,5 @@ pub use self::table::TableInstance;
pub use self::program::ProgramInstance; pub use self::program::ProgramInstance;
pub use self::value::RuntimeValue; pub use self::value::RuntimeValue;
pub use self::variable::{VariableInstance, VariableType, ExternalVariableValue}; pub use self::variable::{VariableInstance, VariableType, ExternalVariableValue};
pub use self::env_native::{env_native_module, UserDefinedElements, UserFunctionExecutor, UserFunctionDescriptor}; pub use self::native::{native_module, UserDefinedElements, UserFunctionExecutor, UserFunctionDescriptor};
pub use self::env::EnvParams; pub use self::emscripten::EmscriptenParams;

View File

@ -4,7 +4,7 @@ use std::sync::{Arc, Weak};
use std::fmt; use std::fmt;
use elements::{Module, InitExpr, Opcode, Type, FunctionType, Internal, External, BlockType, ResizableLimits, Local, ValueType}; use elements::{Module, InitExpr, Opcode, Type, FunctionType, Internal, External, BlockType, ResizableLimits, Local, ValueType};
use interpreter::Error; use interpreter::Error;
use interpreter::env_native::UserFunctionDescriptor; use interpreter::native::UserFunctionDescriptor;
use interpreter::imports::ModuleImports; use interpreter::imports::ModuleImports;
use interpreter::memory::MemoryInstance; use interpreter::memory::MemoryInstance;
use interpreter::program::ProgramInstanceEssence; use interpreter::program::ProgramInstanceEssence;

View File

@ -1,3 +1,4 @@
use std::sync::Arc; use std::sync::Arc;
use std::collections::HashMap; use std::collections::HashMap;
use std::borrow::Cow; use std::borrow::Cow;
@ -79,8 +80,8 @@ pub struct UserDefinedElements<'a> {
/// Native module instance. /// Native module instance.
pub struct NativeModuleInstance<'a> { pub struct NativeModuleInstance<'a> {
/// Underllying module reference. /// Underlying module reference.
env: Arc<ModuleInstanceInterface>, base: Arc<ModuleInstanceInterface>,
/// User function executor. /// User function executor.
executor: RwLock<Option<&'a mut UserFunctionExecutor>>, executor: RwLock<Option<&'a mut UserFunctionExecutor>>,
/// By-name functions index. /// By-name functions index.
@ -95,13 +96,13 @@ pub struct NativeModuleInstance<'a> {
impl<'a> NativeModuleInstance<'a> { impl<'a> NativeModuleInstance<'a> {
/// Create new native module /// Create new native module
pub fn new(env: Arc<ModuleInstanceInterface>, elements: UserDefinedElements<'a>) -> Result<Self, Error> { pub fn new(base: Arc<ModuleInstanceInterface>, elements: UserDefinedElements<'a>) -> Result<Self, Error> {
if !elements.functions.is_empty() && elements.executor.is_none() { if !elements.functions.is_empty() && elements.executor.is_none() {
return Err(Error::Function("trying to construct native env module with functions, but without executor".into())); return Err(Error::Function("trying to construct native module with functions, but without executor".into()));
} }
Ok(NativeModuleInstance { Ok(NativeModuleInstance {
env: env, base: base,
executor: RwLock::new(elements.executor), executor: RwLock::new(elements.executor),
functions_by_name: elements.functions.iter().enumerate().map(|(i, f)| (f.name().to_owned(), i as u32)).collect(), functions_by_name: elements.functions.iter().enumerate().map(|(i, f)| (f.name().to_owned(), i as u32)).collect(),
functions: elements.functions, functions: elements.functions,
@ -113,11 +114,11 @@ impl<'a> NativeModuleInstance<'a> {
impl<'a> ModuleInstanceInterface for NativeModuleInstance<'a> { impl<'a> ModuleInstanceInterface for NativeModuleInstance<'a> {
fn execute_index(&self, index: u32, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> { fn execute_index(&self, index: u32, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> {
self.env.execute_index(index, params) self.base.execute_index(index, params)
} }
fn execute_export(&self, name: &str, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> { fn execute_export(&self, name: &str, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> {
self.env.execute_export(name, params) self.base.execute_export(name, params)
} }
fn export_entry<'b>(&self, name: &str, required_type: &ExportEntryType) -> Result<Internal, Error> { fn export_entry<'b>(&self, name: &str, required_type: &ExportEntryType) -> Result<Internal, Error> {
@ -174,25 +175,25 @@ impl<'a> ModuleInstanceInterface for NativeModuleInstance<'a> {
} }
} }
self.env.export_entry(name, required_type) self.base.export_entry(name, required_type)
} }
fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance>, Error> { fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance>, Error> {
self.env.table(index) self.base.table(index)
} }
fn memory(&self, index: ItemIndex) -> Result<Arc<MemoryInstance>, Error> { fn memory(&self, index: ItemIndex) -> Result<Arc<MemoryInstance>, Error> {
self.env.memory(index) self.base.memory(index)
} }
fn global<'b>(&self, global_index: ItemIndex, variable_type: Option<VariableType>, externals: Option<&'b HashMap<String, Arc<ModuleInstanceInterface + 'b>>>) -> Result<Arc<VariableInstance>, Error> { fn global<'b>(&self, global_index: ItemIndex, variable_type: Option<VariableType>, externals: Option<&'b HashMap<String, Arc<ModuleInstanceInterface + 'b>>>) -> Result<Arc<VariableInstance>, Error> {
let index = match global_index { let index = match global_index {
ItemIndex::IndexSpace(index) | ItemIndex::Internal(index) => index, ItemIndex::IndexSpace(index) | ItemIndex::Internal(index) => index,
ItemIndex::External(_) => unreachable!("trying to get global, exported by native env module"), ItemIndex::External(_) => unreachable!("trying to get global, exported by native module"),
}; };
if index < NATIVE_INDEX_GLOBAL_MIN { if index < NATIVE_INDEX_GLOBAL_MIN {
return self.env.global(global_index, variable_type, externals); return self.base.global(global_index, variable_type, externals);
} }
self.globals self.globals
@ -204,16 +205,16 @@ impl<'a> ModuleInstanceInterface for NativeModuleInstance<'a> {
fn function_type(&self, function_index: ItemIndex) -> Result<FunctionSignature, Error> { fn function_type(&self, function_index: ItemIndex) -> Result<FunctionSignature, Error> {
let index = match function_index { let index = match function_index {
ItemIndex::IndexSpace(index) | ItemIndex::Internal(index) => index, ItemIndex::IndexSpace(index) | ItemIndex::Internal(index) => index,
ItemIndex::External(_) => unreachable!("trying to call function, exported by native env module"), ItemIndex::External(_) => unreachable!("trying to call function, exported by native module"),
}; };
if index < NATIVE_INDEX_FUNC_MIN || index >= NATIVE_INDEX_GLOBAL_MIN { if index < NATIVE_INDEX_FUNC_MIN || index >= NATIVE_INDEX_GLOBAL_MIN {
return self.env.function_type(function_index); return self.base.function_type(function_index);
} }
Ok(FunctionSignature::User(self.functions Ok(FunctionSignature::User(self.functions
.get((index - NATIVE_INDEX_FUNC_MIN) as usize) .get((index - NATIVE_INDEX_FUNC_MIN) as usize)
.ok_or(Error::Native(format!("missing native env function with index {}", index)))?)) .ok_or(Error::Native(format!("missing native function with index {}", index)))?))
} }
fn function_type_by_index(&self, type_index: u32) -> Result<FunctionSignature, Error> { fn function_type_by_index(&self, type_index: u32) -> Result<FunctionSignature, Error> {
@ -221,11 +222,11 @@ impl<'a> ModuleInstanceInterface for NativeModuleInstance<'a> {
} }
fn function_reference<'b>(&self, index: ItemIndex, externals: Option<&'b HashMap<String, Arc<ModuleInstanceInterface + 'b>>>) -> Result<InternalFunctionReference<'b>, Error> { fn function_reference<'b>(&self, index: ItemIndex, externals: Option<&'b HashMap<String, Arc<ModuleInstanceInterface + 'b>>>) -> Result<InternalFunctionReference<'b>, Error> {
self.env.function_reference(index, externals) self.base.function_reference(index, externals)
} }
fn function_reference_indirect<'b>(&self, table_idx: u32, type_idx: u32, func_idx: u32, externals: Option<&'b HashMap<String, Arc<ModuleInstanceInterface + 'b>>>) -> Result<InternalFunctionReference<'b>, Error> { fn function_reference_indirect<'b>(&self, table_idx: u32, type_idx: u32, func_idx: u32, externals: Option<&'b HashMap<String, Arc<ModuleInstanceInterface + 'b>>>) -> Result<InternalFunctionReference<'b>, Error> {
self.env.function_reference_indirect(table_idx, type_idx, func_idx, externals) self.base.function_reference_indirect(table_idx, type_idx, func_idx, externals)
} }
fn function_body<'b>(&'b self, _internal_index: u32) -> Result<Option<InternalFunction<'b>>, Error> { fn function_body<'b>(&'b self, _internal_index: u32) -> Result<Option<InternalFunction<'b>>, Error> {
@ -234,7 +235,7 @@ impl<'a> ModuleInstanceInterface for NativeModuleInstance<'a> {
fn call_internal_function(&self, outer: CallerContext, index: u32) -> Result<Option<RuntimeValue>, Error> { fn call_internal_function(&self, outer: CallerContext, index: u32) -> Result<Option<RuntimeValue>, Error> {
if index < NATIVE_INDEX_FUNC_MIN || index >= NATIVE_INDEX_GLOBAL_MIN { if index < NATIVE_INDEX_FUNC_MIN || index >= NATIVE_INDEX_GLOBAL_MIN {
return self.env.call_internal_function(outer, index); return self.base.call_internal_function(outer, index);
} }
self.functions self.functions
@ -242,14 +243,45 @@ impl<'a> ModuleInstanceInterface for NativeModuleInstance<'a> {
.ok_or(Error::Native(format!("trying to call native function with index {}", index)).into()) .ok_or(Error::Native(format!("trying to call native function with index {}", index)).into())
.and_then(|f| self.executor.write() .and_then(|f| self.executor.write()
.as_mut() .as_mut()
.expect("function existss; if function exists, executor must also exists [checked in constructor]; qed") .expect("function exists; if function exists, executor must also exists [checked in constructor]; qed")
.execute(&f.name(), outer)) .execute(&f.name(), outer))
} }
} }
/// Create wrapper for env module with given native user functions. /// Create wrapper for a module with given native user functions.
pub fn env_native_module<'a>(env: Arc<ModuleInstanceInterface>, user_elements: UserDefinedElements<'a>) -> Result<NativeModuleInstance, Error> { ///
NativeModuleInstance::new(env, user_elements) /// # Examples
///
/// ```rust
/// use parity_wasm::interpreter::{CallerContext, Error, ExecutionParams, ExportEntryType,
/// FunctionSignature, ItemIndex, ModuleInstance,
/// ModuleInstanceInterface, ProgramInstance, RuntimeValue,
/// UserDefinedElements, UserError, UserFunctionDescriptor,
/// UserFunctionExecutor};
///
/// struct MyExecutor;
///
/// impl UserFunctionExecutor for MyExecutor {
/// fn execute(
/// &mut self,
/// name: &str,
/// context: CallerContext,
/// ) -> Result<Option<RuntimeValue>, Error> {
/// match name {
/// "add" => {
/// // fn add(a: u32, b: u32) -> u32
/// let b = context.value_stack.pop_as::<u32>()? as u32;
/// let a = context.value_stack.pop_as::<u32>()? as u32;
/// let sum = a + b;
/// Ok(Some(RuntimeValue::I32(sum as i32)))
/// }
/// _ => Err(Error::Trap("not implemented".into()).into()),
/// }
/// }
/// }
/// ```
pub fn native_module<'a>(base: Arc<ModuleInstanceInterface>, user_elements: UserDefinedElements<'a>) -> Result<NativeModuleInstance, Error> {
NativeModuleInstance::new(base, user_elements)
} }
impl<'a> PartialEq for UserFunctionDescriptor { impl<'a> PartialEq for UserFunctionDescriptor {

View File

@ -3,7 +3,7 @@ use std::collections::HashMap;
use parking_lot::RwLock; use parking_lot::RwLock;
use elements::Module; use elements::Module;
use interpreter::Error; use interpreter::Error;
use interpreter::env::{self, env_module}; use interpreter::emscripten::{EmscriptenParams, env_module};
use interpreter::module::{ModuleInstance, ModuleInstanceInterface}; use interpreter::module::{ModuleInstance, ModuleInstanceInterface};
/// Program instance. Program is a set of instantiated modules. /// Program instance. Program is a set of instantiated modules.
@ -20,24 +20,21 @@ pub struct ProgramInstanceEssence {
impl ProgramInstance { impl ProgramInstance {
/// Create new program instance. /// Create new program instance.
pub fn new() -> Result<Self, Error> { pub fn new() -> Self {
ProgramInstance::with_env_params(env::EnvParams::default()) ProgramInstance {
essence: Arc::new(ProgramInstanceEssence::new()),
}
} }
/// Create new program instance with custom env module params (mostly memory) /// Create new program instance with added Emscripten's `env` module.
pub fn with_env_params(params: env::EnvParams) -> Result<Self, Error> { ///
/// You can specify desired environment params. Or you can just pass `Default::default()`.
pub fn with_emscripten_env(params: EmscriptenParams) -> Result<Self, Error> {
Ok(ProgramInstance { Ok(ProgramInstance {
essence: Arc::new(ProgramInstanceEssence::with_env_params(params)?), essence: Arc::new(ProgramInstanceEssence::with_env_params(params)?),
}) })
} }
/// Create a new program instance with a custom env module
pub fn with_env_module(env_module: Arc<ModuleInstanceInterface>) -> Self {
ProgramInstance {
essence: Arc::new(ProgramInstanceEssence::with_env_module(env_module)),
}
}
/// Instantiate module with validation. /// Instantiate module with validation.
pub fn add_module<'a>(&self, name: &str, module: Module, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>) -> Result<Arc<ModuleInstance>, Error> { pub fn add_module<'a>(&self, name: &str, module: Module, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>) -> Result<Arc<ModuleInstance>, Error> {
let mut module_instance = ModuleInstance::new(Arc::downgrade(&self.essence), name.into(), module)?; let mut module_instance = ModuleInstance::new(Arc::downgrade(&self.essence), name.into(), module)?;
@ -64,11 +61,13 @@ impl ProgramInstance {
impl ProgramInstanceEssence { impl ProgramInstanceEssence {
/// Create new program essence. /// Create new program essence.
pub fn new() -> Result<Self, Error> { pub fn new() -> Self {
ProgramInstanceEssence::with_env_params(env::EnvParams::default()) ProgramInstanceEssence {
modules: RwLock::new(HashMap::new()),
}
} }
pub fn with_env_params(env_params: env::EnvParams) -> Result<Self, Error> { pub fn with_env_params(env_params: EmscriptenParams) -> Result<Self, Error> {
let env_mod = env_module(env_params)?; let env_mod = env_module(env_params)?;
Ok(ProgramInstanceEssence::with_env_module(Arc::new(env_mod))) Ok(ProgramInstanceEssence::with_env_module(Arc::new(env_mod)))
} }
@ -81,7 +80,6 @@ impl ProgramInstanceEssence {
} }
} }
/// Get module reference. /// Get module reference.
pub fn module(&self, name: &str) -> Option<Arc<ModuleInstanceInterface>> { pub fn module(&self, name: &str) -> Option<Arc<ModuleInstanceInterface>> {
self.modules.read().get(name).cloned() self.modules.read().get(name).cloned()

View File

@ -7,7 +7,7 @@ use builder::module;
use elements::{ExportEntry, Internal, ImportEntry, External, GlobalEntry, GlobalType, use elements::{ExportEntry, Internal, ImportEntry, External, GlobalEntry, GlobalType,
InitExpr, ValueType, BlockType, Opcodes, Opcode, FunctionType, TableType, MemoryType}; InitExpr, ValueType, BlockType, Opcodes, Opcode, FunctionType, TableType, MemoryType};
use interpreter::{Error, UserError, ProgramInstance}; use interpreter::{Error, UserError, ProgramInstance};
use interpreter::env_native::{env_native_module, UserDefinedElements, UserFunctionExecutor, UserFunctionDescriptor}; use interpreter::native::{native_module, UserDefinedElements, UserFunctionExecutor, UserFunctionDescriptor};
use interpreter::memory::MemoryInstance; use interpreter::memory::MemoryInstance;
use interpreter::module::{ModuleInstance, ModuleInstanceInterface, CallerContext, ItemIndex, ExecutionParams, ExportEntryType, FunctionSignature}; use interpreter::module::{ModuleInstance, ModuleInstanceInterface, CallerContext, ItemIndex, ExecutionParams, ExportEntryType, FunctionSignature};
use interpreter::validator::{FunctionValidationContext, Validator}; use interpreter::validator::{FunctionValidationContext, Validator};
@ -40,7 +40,7 @@ fn import_function() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let external_module = program.add_module("external_module", module1, None).unwrap(); let external_module = program.add_module("external_module", module1, None).unwrap();
let main_module = program.add_module("main", module2, None).unwrap(); let main_module = program.add_module("main", module2, None).unwrap();
@ -74,7 +74,7 @@ fn wrong_import() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let _side_module_instance = program.add_module("side_module", side_module, None).unwrap(); let _side_module_instance = program.add_module("side_module", side_module, None).unwrap();
assert!(program.add_module("main", module, None).is_err()); assert!(program.add_module("main", module, None).is_err());
} }
@ -96,7 +96,7 @@ fn global_get_set() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(50)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(50));
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(58)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(58));
@ -196,7 +196,7 @@ impl UserFunctionExecutor for FunctionExecutor {
#[test] #[test]
fn native_env_function() { fn native_env_function() {
// create new program // create new program
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::with_emscripten_env(Default::default()).unwrap();
// => env module is created // => env module is created
let env_instance = program.module("env").unwrap(); let env_instance = program.module("env").unwrap();
// => linear memory is created // => linear memory is created
@ -213,7 +213,7 @@ fn native_env_function() {
globals: HashMap::new(), globals: HashMap::new(),
functions: ::std::borrow::Cow::from(SIGNATURES), functions: ::std::borrow::Cow::from(SIGNATURES),
}; };
let native_env_instance = Arc::new(env_native_module(env_instance, functions).unwrap()); let native_env_instance = Arc::new(native_module(env_instance, functions).unwrap());
let params = ExecutionParams::with_external("env".into(), native_env_instance); let params = ExecutionParams::with_external("env".into(), native_env_instance);
let module = module() let module = module()
@ -256,7 +256,7 @@ fn native_env_function() {
#[test] #[test]
fn native_env_function_own_memory() { fn native_env_function_own_memory() {
// create program + env module is auto instantiated + env module memory is instantiated (we do not need this) // create program + env module is auto instantiated + env module memory is instantiated (we do not need this)
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::with_emscripten_env(Default::default()).unwrap();
struct OwnMemoryReference { struct OwnMemoryReference {
pub memory: RefCell<Option<Arc<MemoryInstance>>>, pub memory: RefCell<Option<Arc<MemoryInstance>>>,
@ -287,7 +287,7 @@ fn native_env_function_own_memory() {
let env_instance = program.module("env").unwrap(); let env_instance = program.module("env").unwrap();
let memory_ref = Arc::new(OwnMemoryReference { memory: RefCell::new(None) }); let memory_ref = Arc::new(OwnMemoryReference { memory: RefCell::new(None) });
let mut executor = OwnMemoryExecutor { memory_ref: memory_ref.clone() }; let mut executor = OwnMemoryExecutor { memory_ref: memory_ref.clone() };
let native_env_instance = Arc::new(env_native_module(env_instance, UserDefinedElements { let native_env_instance = Arc::new(native_module(env_instance, UserDefinedElements {
executor: Some(&mut executor), executor: Some(&mut executor),
globals: HashMap::new(), globals: HashMap::new(),
functions: ::std::borrow::Cow::from(SIGNATURES), functions: ::std::borrow::Cow::from(SIGNATURES),
@ -326,9 +326,9 @@ fn native_env_function_own_memory() {
fn native_env_global() { fn native_env_global() {
// module constructor // module constructor
let module_constructor = |elements| { let module_constructor = |elements| {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::with_emscripten_env(Default::default()).unwrap();
let env_instance = program.module("env").unwrap(); let env_instance = program.module("env").unwrap();
let native_env_instance = Arc::new(env_native_module(env_instance.clone(), elements).unwrap()); let native_env_instance = Arc::new(native_module(env_instance.clone(), elements).unwrap());
let params = ExecutionParams::with_external("env".into(), native_env_instance); let params = ExecutionParams::with_external("env".into(), native_env_instance);
let module = module() let module = module()
@ -375,7 +375,7 @@ fn native_env_global() {
#[test] #[test]
fn native_custom_error() { fn native_custom_error() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::with_emscripten_env(Default::default()).unwrap();
let env_instance = program.module("env").unwrap(); let env_instance = program.module("env").unwrap();
let env_memory = env_instance.memory(ItemIndex::Internal(0)).unwrap(); let env_memory = env_instance.memory(ItemIndex::Internal(0)).unwrap();
let mut executor = FunctionExecutor { memory: env_memory.clone(), values: Vec::new() }; let mut executor = FunctionExecutor { memory: env_memory.clone(), values: Vec::new() };
@ -384,7 +384,7 @@ fn native_custom_error() {
globals: HashMap::new(), globals: HashMap::new(),
functions: ::std::borrow::Cow::from(SIGNATURES), functions: ::std::borrow::Cow::from(SIGNATURES),
}; };
let native_env_instance = Arc::new(env_native_module(env_instance, functions).unwrap()); let native_env_instance = Arc::new(native_module(env_instance, functions).unwrap());
let params = ExecutionParams::with_external("env".into(), native_env_instance); let params = ExecutionParams::with_external("env".into(), native_env_instance);
let module = module() let module = module()
@ -428,7 +428,7 @@ fn native_custom_error() {
#[test] #[test]
fn import_env_mutable_global() { fn import_env_mutable_global() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::with_emscripten_env(Default::default()).unwrap();
let module = module() let module = module()
.with_import(ImportEntry::new("env".into(), "STACKTOP".into(), External::Global(GlobalType::new(ValueType::I32, false)))) .with_import(ImportEntry::new("env".into(), "STACKTOP".into(), External::Global(GlobalType::new(ValueType::I32, false))))
@ -439,12 +439,12 @@ fn import_env_mutable_global() {
#[test] #[test]
fn env_native_export_entry_type_check() { fn env_native_export_entry_type_check() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::with_emscripten_env(Default::default()).unwrap();
let mut function_executor = FunctionExecutor { let mut function_executor = FunctionExecutor {
memory: program.module("env").unwrap().memory(ItemIndex::Internal(0)).unwrap(), memory: program.module("env").unwrap().memory(ItemIndex::Internal(0)).unwrap(),
values: Vec::new(), values: Vec::new(),
}; };
let native_env_instance = Arc::new(env_native_module(program.module("env").unwrap(), UserDefinedElements { let native_env_instance = Arc::new(native_module(program.module("env").unwrap(), UserDefinedElements {
executor: Some(&mut function_executor), executor: Some(&mut function_executor),
globals: vec![("ext_global".into(), Arc::new(VariableInstance::new(false, VariableType::I32, RuntimeValue::I32(1312)).unwrap()))].into_iter().collect(), globals: vec![("ext_global".into(), Arc::new(VariableInstance::new(false, VariableType::I32, RuntimeValue::I32(1312)).unwrap()))].into_iter().collect(),
functions: ::std::borrow::Cow::from(SIGNATURES), functions: ::std::borrow::Cow::from(SIGNATURES),
@ -498,7 +498,7 @@ fn memory_import_limits_initial() {
.with_export(ExportEntry::new("memory".into(), Internal::Memory(0))) .with_export(ExportEntry::new("memory".into(), Internal::Memory(0)))
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
program.add_module("core", core_module, None).unwrap(); program.add_module("core", core_module, None).unwrap();
let test_cases = vec![ let test_cases = vec![
@ -535,7 +535,7 @@ fn memory_import_limits_maximum() {
(None, None, MaximumError::Ok), (None, None, MaximumError::Ok),
]; ];
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
for test_case in test_cases { for test_case in test_cases {
let (core_maximum, client_maximum, expected_err) = test_case; let (core_maximum, client_maximum, expected_err) = test_case;
let core_module = module() let core_module = module()
@ -566,7 +566,7 @@ fn table_import_limits_initial() {
.with_export(ExportEntry::new("table".into(), Internal::Table(0))) .with_export(ExportEntry::new("table".into(), Internal::Table(0)))
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
program.add_module("core", core_module, None).unwrap(); program.add_module("core", core_module, None).unwrap();
let test_cases = vec![ let test_cases = vec![
@ -603,7 +603,7 @@ fn table_import_limits_maximum() {
(None, None, MaximumError::Ok), (None, None, MaximumError::Ok),
]; ];
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
for test_case in test_cases { for test_case in test_cases {
let (core_maximum, client_maximum, expected_err) = test_case; let (core_maximum, client_maximum, expected_err) = test_case;
let core_module = module() let core_module = module()

View File

@ -17,7 +17,7 @@ fn make_function_i32(body: Opcodes) -> (ProgramInstance, Arc<ModuleInstanceInter
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
(program, module) (program, module)
} }
@ -461,7 +461,7 @@ fn return_void() {
.body().with_opcodes(body).build() .body().with_opcodes(body).build()
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
module.execute_index(0, vec![RuntimeValue::I32(0)].into()).unwrap(); module.execute_index(0, vec![RuntimeValue::I32(0)].into()).unwrap();
@ -520,7 +520,7 @@ fn call_1() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(10)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(10));
} }
@ -567,7 +567,7 @@ fn call_2() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(3628800)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(3628800));
} }
@ -612,7 +612,7 @@ fn call_zero_args() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(43)); assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(43));
} }
@ -658,7 +658,7 @@ fn callindirect_1() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(2, vec![RuntimeValue::I32(0)].into()).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(2, vec![RuntimeValue::I32(0)].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(2, vec![RuntimeValue::I32(1)].into()).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(2, vec![RuntimeValue::I32(1)].into()).unwrap().unwrap(), RuntimeValue::I32(1));
@ -731,7 +731,7 @@ fn callindirect_2() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(3, vec![RuntimeValue::I32(10), RuntimeValue::I32(4), RuntimeValue::I32(0)].into()).unwrap().unwrap(), RuntimeValue::I32(14)); assert_eq!(module.execute_index(3, vec![RuntimeValue::I32(10), RuntimeValue::I32(4), RuntimeValue::I32(0)].into()).unwrap().unwrap(), RuntimeValue::I32(14));
assert_eq!(module.execute_index(3, vec![RuntimeValue::I32(10), RuntimeValue::I32(4), RuntimeValue::I32(1)].into()).unwrap().unwrap(), RuntimeValue::I32(6)); assert_eq!(module.execute_index(3, vec![RuntimeValue::I32(10), RuntimeValue::I32(4), RuntimeValue::I32(1)].into()).unwrap().unwrap(), RuntimeValue::I32(6));
@ -813,7 +813,7 @@ fn select() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(0, vec![RuntimeValue::I32(0)].into()).unwrap().unwrap(), RuntimeValue::I32(2)); assert_eq!(module.execute_index(0, vec![RuntimeValue::I32(0)].into()).unwrap().unwrap(), RuntimeValue::I32(2));
assert_eq!(module.execute_index(0, vec![RuntimeValue::I32(1)].into()).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(0, vec![RuntimeValue::I32(1)].into()).unwrap().unwrap(), RuntimeValue::I32(1));
@ -966,7 +966,7 @@ fn binary_i32() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(3)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(3));
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(16)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(16));
@ -1126,7 +1126,7 @@ fn binary_i64() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(3)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(3));
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(16)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(16));
@ -1216,7 +1216,7 @@ fn binary_f32() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(5.000000)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(5.000000));
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(-9995.500000)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(-9995.500000));
@ -1298,7 +1298,7 @@ fn binary_f64() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(1111111110.000000)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(1111111110.000000));
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(123400000000000007812762268812638756607430593436581896388608.000000)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(123400000000000007812762268812638756607430593436581896388608.000000));
@ -1351,7 +1351,7 @@ fn cast() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(4.5)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(4.5));
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1067450368)); // 3227516928 assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1067450368)); // 3227516928
@ -1617,7 +1617,7 @@ fn compare_i32() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
@ -1907,7 +1907,7 @@ fn compare_i64() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
@ -2091,7 +2091,7 @@ fn compare_f32() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
@ -2263,7 +2263,7 @@ fn compare_f64() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
@ -2331,7 +2331,7 @@ fn convert_i32() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1)); // 4294967295 assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1)); // 4294967295
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-100)); // 4294967196 assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-100)); // 4294967196
@ -2404,7 +2404,7 @@ fn convert_i64() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(4294967295)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(4294967295));
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-1)); // 18446744073709551615 assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-1)); // 18446744073709551615
@ -2462,7 +2462,7 @@ fn convert_f32() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(-1.000000)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(-1.000000));
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(4294967296.000000)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(4294967296.000000));
@ -2519,7 +2519,7 @@ fn convert_f64() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(-1.000000)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(-1.000000));
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(4294967295.000000)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(4294967295.000000));
@ -2579,7 +2579,7 @@ fn load_i32() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1));
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1));
@ -2655,7 +2655,7 @@ fn load_i64() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-1)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-1));
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-1)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-1));
@ -2685,7 +2685,7 @@ fn load_f32() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(25.750000)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(25.750000));
} }
@ -2709,7 +2709,7 @@ fn load_f64() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(1023.875000)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(1023.875000));
} }
@ -2766,7 +2766,7 @@ fn store_i32() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-16909061)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-16909061));
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-859059511)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-859059511));
@ -2836,7 +2836,7 @@ fn store_i64() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(4278058235)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(4278058235));
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(3435907785)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(3435907785));
@ -2864,7 +2864,7 @@ fn store_f32() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1069547520)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1069547520));
} }
@ -2889,7 +2889,7 @@ fn store_f64() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1064352256)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1064352256));
} }
@ -2940,7 +2940,7 @@ fn unary_i32() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
@ -2995,7 +2995,7 @@ fn unary_i64() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
@ -3094,7 +3094,7 @@ fn unary_f32() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(-100.000000)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(-100.000000));
assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(100.000000)); assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(100.000000));
@ -3197,7 +3197,7 @@ fn unary_f64() {
.build() .build()
.build(); .build();
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new();
let module = program.add_module("main", module, None).unwrap(); let module = program.add_module("main", module, None).unwrap();
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(-100.000000)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(-100.000000));
assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(100.000000)); assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(100.000000));

View File

@ -11,7 +11,7 @@ fn interpreter_inc_i32() {
// The WASM file containing the module and function // The WASM file containing the module and function
const WASM_FILE: &str = &"res/cases/v1/inc_i32.wasm"; const WASM_FILE: &str = &"res/cases/v1/inc_i32.wasm";
let program = ProgramInstance::new().expect("Failed to instanciate program"); let program = ProgramInstance::with_emscripten_env(Default::default()).expect("Failed to instanciate program");
let module: Module = let module: Module =
deserialize_file(WASM_FILE).expect("Failed to deserialize module from buffer"); deserialize_file(WASM_FILE).expect("Failed to deserialize module from buffer");
@ -43,7 +43,7 @@ fn interpreter_accumulate_u8() {
const BUF: &[u8] = &[9,8,7,6,5,4,3,2,1]; const BUF: &[u8] = &[9,8,7,6,5,4,3,2,1];
// Declare the memory limits of the runtime-environment // Declare the memory limits of the runtime-environment
let program = ProgramInstance::new().expect("Failed to instanciate program"); let program = ProgramInstance::with_emscripten_env(Default::default()).expect("Failed to instanciate program");
// Load the module-structure from wasm-file and add to program // Load the module-structure from wasm-file and add to program
let module: Module = let module: Module =