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();
// add both modules to program
let program = ProgramInstance::new().unwrap();
let program = ProgramInstance::new();
program.add_module("callee_module", callee_module, None).unwrap();
let caller_module = program.add_module("caller_module", caller_module, None).unwrap();

View File

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

View File

@ -17,8 +17,8 @@ fn main() {
// Intrepreter initialization.
// It also initializes a default "env" module.
let program = parity_wasm::ProgramInstance::with_env_params(
interpreter::EnvParams {
let program = parity_wasm::ProgramInstance::with_emscripten_env(
interpreter::EmscriptenParams {
total_stack: 128*1024,
..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> {
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(|_| ())
}
@ -172,7 +172,7 @@ pub fn spec(name: &str) {
.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 program = ProgramInstance::new().expect("Failed creating program");
let program = ProgramInstance::new();
let mut last_module = None;
for command in &spec.commands {
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::collections::HashMap;
use builder::module;
use elements::{Module, ExportEntry, Internal, GlobalEntry, GlobalType,
ValueType, InitExpr, Opcode, Opcodes};
use interpreter::Error;
use interpreter::env_native::NATIVE_INDEX_FUNC_MIN;
use interpreter::native::NATIVE_INDEX_FUNC_MIN;
use interpreter::module::{ModuleInstanceInterface, ModuleInstance, ExecutionParams,
ItemIndex, CallerContext, ExportEntryType, InternalFunctionReference, InternalFunction, FunctionSignature};
use interpreter::memory::{MemoryInstance, LINEAR_MEMORY_PAGE_SIZE};
@ -27,7 +30,7 @@ const DEFAULT_TABLE_BASE: u32 = 0;
/// Default tableBase variable value.
const DEFAULT_MEMORY_BASE: u32 = 0;
/// Defaul table size.
/// Default table size.
const DEFAULT_TABLE_SIZE: u32 = 64;
/// Index of default memory.
@ -70,8 +73,8 @@ const INDEX_FUNC_MIN_NONUSED: u32 = 4;
/// Max index of reserved function.
const INDEX_FUNC_MAX: u32 = NATIVE_INDEX_FUNC_MIN - 1;
/// Environment parameters.
pub struct EnvParams {
/// Emscripten environment parameters.
pub struct EmscriptenParams {
/// Stack size in bytes.
pub total_stack: u32,
/// Total memory size in bytes.
@ -84,24 +87,24 @@ pub struct EnvParams {
pub static_size: Option<u32>,
}
pub struct EnvModuleInstance {
_params: EnvParams,
pub struct EmscriptenModuleInstance {
_params: EmscriptenParams,
instance: ModuleInstance,
}
impl EnvModuleInstance {
pub fn new(params: EnvParams, module: Module) -> Result<Self, Error> {
impl EmscriptenModuleInstance {
pub fn new(params: EmscriptenParams, module: Module) -> Result<Self, Error> {
let mut instance = ModuleInstance::new(Weak::default(), "env".into(), module)?;
instance.instantiate(None)?;
Ok(EnvModuleInstance {
Ok(EmscriptenModuleInstance {
_params: params,
instance: instance,
})
}
}
impl ModuleInstanceInterface for EnvModuleInstance {
impl ModuleInstanceInterface for EmscriptenModuleInstance {
fn execute_index(&self, index: u32, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> {
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 % 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()
.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 {
EnvParams {
EmscriptenParams {
total_stack: DEFAULT_TOTAL_STACK,
total_memory: DEFAULT_TOTAL_MEMORY,
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> {
if self.allow_memory_growth { None } else { Some(self.total_memory) }
}

View File

@ -58,8 +58,6 @@ pub enum Error {
Value(String),
/// Interpreter (code) error.
Interpreter(String),
/// Env module error.
Env(String),
/// Native module error.
Native(String),
/// Trap.
@ -83,7 +81,6 @@ impl Into<String> for Error {
Error::Stack(s) => s,
Error::Interpreter(s) => s,
Error::Value(s) => s,
Error::Env(s) => s,
Error::Native(s) => s,
Error::Trap(s) => format!("trap: {}", s),
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::Interpreter(ref s) => write!(f, "Interpreter: {}", 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::Trap(ref s) => write!(f, "Trap: {}", s),
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 env_native;
mod emscripten;
mod native;
mod imports;
mod memory;
mod module;
@ -143,5 +139,5 @@ pub use self::table::TableInstance;
pub use self::program::ProgramInstance;
pub use self::value::RuntimeValue;
pub use self::variable::{VariableInstance, VariableType, ExternalVariableValue};
pub use self::env_native::{env_native_module, UserDefinedElements, UserFunctionExecutor, UserFunctionDescriptor};
pub use self::env::EnvParams;
pub use self::native::{native_module, UserDefinedElements, UserFunctionExecutor, UserFunctionDescriptor};
pub use self::emscripten::EmscriptenParams;

View File

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

View File

@ -1,3 +1,4 @@
use std::sync::Arc;
use std::collections::HashMap;
use std::borrow::Cow;
@ -79,8 +80,8 @@ pub struct UserDefinedElements<'a> {
/// Native module instance.
pub struct NativeModuleInstance<'a> {
/// Underllying module reference.
env: Arc<ModuleInstanceInterface>,
/// Underlying module reference.
base: Arc<ModuleInstanceInterface>,
/// User function executor.
executor: RwLock<Option<&'a mut UserFunctionExecutor>>,
/// By-name functions index.
@ -95,13 +96,13 @@ pub struct NativeModuleInstance<'a> {
impl<'a> NativeModuleInstance<'a> {
/// 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() {
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 {
env: env,
base: base,
executor: RwLock::new(elements.executor),
functions_by_name: elements.functions.iter().enumerate().map(|(i, f)| (f.name().to_owned(), i as u32)).collect(),
functions: elements.functions,
@ -113,11 +114,11 @@ impl<'a> NativeModuleInstance<'a> {
impl<'a> ModuleInstanceInterface for NativeModuleInstance<'a> {
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> {
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> {
@ -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> {
self.env.table(index)
self.base.table(index)
}
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> {
let index = match global_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 {
return self.env.global(global_index, variable_type, externals);
return self.base.global(global_index, variable_type, externals);
}
self.globals
@ -204,16 +205,16 @@ impl<'a> ModuleInstanceInterface for NativeModuleInstance<'a> {
fn function_type(&self, function_index: ItemIndex) -> Result<FunctionSignature, Error> {
let index = match function_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 {
return self.env.function_type(function_index);
return self.base.function_type(function_index);
}
Ok(FunctionSignature::User(self.functions
.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> {
@ -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> {
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> {
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> {
@ -234,7 +235,7 @@ impl<'a> ModuleInstanceInterface for NativeModuleInstance<'a> {
fn call_internal_function(&self, outer: CallerContext, index: u32) -> Result<Option<RuntimeValue>, Error> {
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
@ -242,14 +243,45 @@ impl<'a> ModuleInstanceInterface for NativeModuleInstance<'a> {
.ok_or(Error::Native(format!("trying to call native function with index {}", index)).into())
.and_then(|f| self.executor.write()
.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))
}
}
/// Create wrapper for env 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)
/// Create wrapper for a module with given native user functions.
///
/// # 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 {

View File

@ -3,7 +3,7 @@ use std::collections::HashMap;
use parking_lot::RwLock;
use elements::Module;
use interpreter::Error;
use interpreter::env::{self, env_module};
use interpreter::emscripten::{EmscriptenParams, env_module};
use interpreter::module::{ModuleInstance, ModuleInstanceInterface};
/// Program instance. Program is a set of instantiated modules.
@ -20,24 +20,21 @@ pub struct ProgramInstanceEssence {
impl ProgramInstance {
/// Create new program instance.
pub fn new() -> Result<Self, Error> {
ProgramInstance::with_env_params(env::EnvParams::default())
pub fn new() -> Self {
ProgramInstance {
essence: Arc::new(ProgramInstanceEssence::new()),
}
}
/// Create new program instance with custom env module params (mostly memory)
pub fn with_env_params(params: env::EnvParams) -> Result<Self, Error> {
/// Create new program instance with added Emscripten's `env` module.
///
/// 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 {
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.
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)?;
@ -64,11 +61,13 @@ impl ProgramInstance {
impl ProgramInstanceEssence {
/// Create new program essence.
pub fn new() -> Result<Self, Error> {
ProgramInstanceEssence::with_env_params(env::EnvParams::default())
pub fn new() -> Self {
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)?;
Ok(ProgramInstanceEssence::with_env_module(Arc::new(env_mod)))
}
@ -81,7 +80,6 @@ impl ProgramInstanceEssence {
}
}
/// Get module reference.
pub fn module(&self, name: &str) -> Option<Arc<ModuleInstanceInterface>> {
self.modules.read().get(name).cloned()

View File

@ -7,7 +7,7 @@ use builder::module;
use elements::{ExportEntry, Internal, ImportEntry, External, GlobalEntry, GlobalType,
InitExpr, ValueType, BlockType, Opcodes, Opcode, FunctionType, TableType, MemoryType};
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::module::{ModuleInstance, ModuleInstanceInterface, CallerContext, ItemIndex, ExecutionParams, ExportEntryType, FunctionSignature};
use interpreter::validator::{FunctionValidationContext, Validator};
@ -40,7 +40,7 @@ fn import_function() {
.build()
.build();
let program = ProgramInstance::new().unwrap();
let program = ProgramInstance::new();
let external_module = program.add_module("external_module", module1, None).unwrap();
let main_module = program.add_module("main", module2, None).unwrap();
@ -74,7 +74,7 @@ fn wrong_import() {
.build()
.build();
let program = ProgramInstance::new().unwrap();
let program = ProgramInstance::new();
let _side_module_instance = program.add_module("side_module", side_module, None).unwrap();
assert!(program.add_module("main", module, None).is_err());
}
@ -96,7 +96,7 @@ fn global_get_set() {
.build()
.build();
let program = ProgramInstance::new().unwrap();
let program = ProgramInstance::new();
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(58));
@ -196,7 +196,7 @@ impl UserFunctionExecutor for FunctionExecutor {
#[test]
fn native_env_function() {
// create new program
let program = ProgramInstance::new().unwrap();
let program = ProgramInstance::with_emscripten_env(Default::default()).unwrap();
// => env module is created
let env_instance = program.module("env").unwrap();
// => linear memory is created
@ -213,7 +213,7 @@ fn native_env_function() {
globals: HashMap::new(),
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 module = module()
@ -256,7 +256,7 @@ fn native_env_function() {
#[test]
fn native_env_function_own_memory() {
// 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 {
pub memory: RefCell<Option<Arc<MemoryInstance>>>,
@ -287,7 +287,7 @@ fn native_env_function_own_memory() {
let env_instance = program.module("env").unwrap();
let memory_ref = Arc::new(OwnMemoryReference { memory: RefCell::new(None) });
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),
globals: HashMap::new(),
functions: ::std::borrow::Cow::from(SIGNATURES),
@ -326,9 +326,9 @@ fn native_env_function_own_memory() {
fn native_env_global() {
// module constructor
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 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 module = module()
@ -375,7 +375,7 @@ fn native_env_global() {
#[test]
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_memory = env_instance.memory(ItemIndex::Internal(0)).unwrap();
let mut executor = FunctionExecutor { memory: env_memory.clone(), values: Vec::new() };
@ -384,7 +384,7 @@ fn native_custom_error() {
globals: HashMap::new(),
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 module = module()
@ -428,7 +428,7 @@ fn native_custom_error() {
#[test]
fn import_env_mutable_global() {
let program = ProgramInstance::new().unwrap();
let program = ProgramInstance::with_emscripten_env(Default::default()).unwrap();
let module = module()
.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]
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 {
memory: program.module("env").unwrap().memory(ItemIndex::Internal(0)).unwrap(),
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),
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),
@ -498,7 +498,7 @@ fn memory_import_limits_initial() {
.with_export(ExportEntry::new("memory".into(), Internal::Memory(0)))
.build();
let program = ProgramInstance::new().unwrap();
let program = ProgramInstance::new();
program.add_module("core", core_module, None).unwrap();
let test_cases = vec![
@ -535,7 +535,7 @@ fn memory_import_limits_maximum() {
(None, None, MaximumError::Ok),
];
let program = ProgramInstance::new().unwrap();
let program = ProgramInstance::new();
for test_case in test_cases {
let (core_maximum, client_maximum, expected_err) = test_case;
let core_module = module()
@ -566,7 +566,7 @@ fn table_import_limits_initial() {
.with_export(ExportEntry::new("table".into(), Internal::Table(0)))
.build();
let program = ProgramInstance::new().unwrap();
let program = ProgramInstance::new();
program.add_module("core", core_module, None).unwrap();
let test_cases = vec![
@ -603,7 +603,7 @@ fn table_import_limits_maximum() {
(None, None, MaximumError::Ok),
];
let program = ProgramInstance::new().unwrap();
let program = ProgramInstance::new();
for test_case in test_cases {
let (core_maximum, client_maximum, expected_err) = test_case;
let core_module = module()

View File

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