Merge pull request #14 from svyatonik/program_adapter

Program adapter
This commit is contained in:
Nikolay Volf 2017-05-19 16:13:28 +03:00 committed by GitHub
commit 533c3a0c50
10 changed files with 588 additions and 489 deletions

View File

@ -16,5 +16,5 @@ fn main() {
let module = parity_wasm::deserialize_file(&args[1]).expect("Failed to load module"); let module = parity_wasm::deserialize_file(&args[1]).expect("Failed to load module");
let module = program.add_module("main", module).expect("Failed to initialize module"); let module = program.add_module("main", module).expect("Failed to initialize module");
let argument: i32 = args[2].parse().expect("Integer argument required"); let argument: i32 = args[2].parse().expect("Integer argument required");
println!("Result: {:?}", module.execute_export("_call", vec![parity_wasm::RuntimeValue::I32(argument)])); println!("Result: {:?}", module.execute_export("_call", vec![parity_wasm::RuntimeValue::I32(argument)].into()));
} }

View File

@ -1,11 +1,12 @@
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use std::collections::HashMap;
use builder::{module, function, export}; use builder::module;
use elements::{Module, FunctionType, ExportEntry, Internal, GlobalEntry, GlobalType, use elements::{Module, FunctionType, ExportEntry, Internal, GlobalEntry, GlobalType,
ValueType, InitExpr, Opcode, Opcodes}; ValueType, InitExpr, Opcode, Opcodes};
use interpreter::Error; use interpreter::Error;
use interpreter::module::{ModuleInstanceInterface, ModuleInstance, ItemIndex, CallerContext}; use interpreter::env_native::NATIVE_INDEX_FUNC_MIN;
use interpreter::module::{ModuleInstanceInterface, ModuleInstance, ExecutionParams,
ItemIndex, CallerContext};
use interpreter::memory::{MemoryInstance, LINEAR_MEMORY_PAGE_SIZE}; use interpreter::memory::{MemoryInstance, LINEAR_MEMORY_PAGE_SIZE};
use interpreter::table::TableInstance; use interpreter::table::TableInstance;
use interpreter::value::{RuntimeValue, TransmuteInto}; use interpreter::value::{RuntimeValue, TransmuteInto};
@ -58,44 +59,10 @@ const INDEX_FUNC_ASSERT: u32 = 1;
const INDEX_FUNC_ENLARGE_MEMORY: u32 = 2; const INDEX_FUNC_ENLARGE_MEMORY: u32 = 2;
/// Index of getTotalMemory function. /// Index of getTotalMemory function.
const INDEX_FUNC_GET_TOTAL_MEMORY: u32 = 3; const INDEX_FUNC_GET_TOTAL_MEMORY: u32 = 3;
/// Index of abortOnCannotGrowMemory function.
/*const INDEX_FUNC_ABORT_ON_CANNOT_GROW_MEMORY: u32 = 4;
/// Index of invoke_vi function.
const INDEX_FUNC_INVOKE_VI: u32 = 5;
/// Index of invoke function.
const INDEX_FUNC_INVOKE: u32 = 6;*/
/// Min index of reserver function. /// Min index of reserver function.
const INDEX_FUNC_MIN_NONUSED: u32 = 7; const INDEX_FUNC_MIN_NONUSED: u32 = 4;
/// Max index of reserved function. /// Max index of reserved function.
const INDEX_FUNC_MAX: u32 = 10000; const INDEX_FUNC_MAX: u32 = NATIVE_INDEX_FUNC_MIN - 1;
/// Set of user-defined functions
pub type UserFunctions = HashMap<String, UserFunction>;
/// User function closure
pub type UserFunctionClosure = Box<UserFunctionInterface>;
/// User-defined function execution interface
pub trait UserFunctionInterface {
/// Handles the user function invocation
fn call(&mut self, module: &ModuleInstance, context: CallerContext) -> Result<Option<RuntimeValue>, Error>;
}
impl<T> UserFunctionInterface for T where T: FnMut(&ModuleInstance, CallerContext) -> Result<Option<RuntimeValue>, Error> {
fn call(&mut self, module: &ModuleInstance, context: CallerContext) -> Result<Option<RuntimeValue>, Error> {
(&mut *self)(module, context)
}
}
/// Signature of user-defined env function
pub struct UserFunction {
/// User function parameters (for signature matching)
pub params: Vec<ValueType>,
/// User function return type (for signature matching)
pub result: Option<ValueType>,
/// Executor of the function
pub closure: UserFunctionClosure,
}
/// Environment parameters. /// Environment parameters.
pub struct EnvParams { pub struct EnvParams {
@ -107,41 +74,37 @@ pub struct EnvParams {
pub allow_memory_growth: bool, pub allow_memory_growth: bool,
} }
type UserFunctionsInternals = Vec<::std::cell::RefCell<UserFunctionClosure>>;
pub struct EnvModuleInstance { pub struct EnvModuleInstance {
_params: EnvParams, _params: EnvParams,
user_functions: UserFunctionsInternals,
instance: ModuleInstance, instance: ModuleInstance,
} }
impl EnvModuleInstance { impl EnvModuleInstance {
pub fn new(params: EnvParams, user_functions: UserFunctionsInternals, module: Module) -> Result<Self, Error> { pub fn new(params: EnvParams, module: Module) -> Result<Self, Error> {
let instance = ModuleInstance::new(Weak::default(), module)?; let instance = ModuleInstance::new(Weak::default(), module)?;
Ok(EnvModuleInstance { Ok(EnvModuleInstance {
_params: params, _params: params,
user_functions: user_functions,
instance: instance, instance: instance,
}) })
} }
} }
impl ModuleInstanceInterface for EnvModuleInstance { impl ModuleInstanceInterface for EnvModuleInstance {
fn execute_main(&self, args: Vec<RuntimeValue>) -> Result<Option<RuntimeValue>, Error> { fn execute_main(&self, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> {
self.instance.execute_main(args) self.instance.execute_main(params)
} }
fn execute_index(&self, index: u32, args: Vec<RuntimeValue>) -> Result<Option<RuntimeValue>, Error> { fn execute_index(&self, index: u32, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> {
self.instance.execute_index(index, args) self.instance.execute_index(index, params)
} }
fn execute_export(&self, name: &str, args: Vec<RuntimeValue>) -> Result<Option<RuntimeValue>, Error> { fn execute_export(&self, name: &str, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> {
self.instance.execute_export(name, args) self.instance.execute_export(name, params)
} }
fn module(&self) -> &Module { fn export_entry(&self, name: &str) -> Result<Internal, Error> {
self.instance.module() self.instance.export_entry(name)
} }
fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance>, Error> { fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance>, Error> {
@ -165,6 +128,7 @@ impl ModuleInstanceInterface for EnvModuleInstance {
} }
fn call_internal_function(&self, outer: CallerContext, index: u32, _function_type: Option<&FunctionType>) -> Result<Option<RuntimeValue>, Error> { fn call_internal_function(&self, outer: CallerContext, index: u32, _function_type: Option<&FunctionType>) -> Result<Option<RuntimeValue>, Error> {
// TODO: check function type
// to make interpreter independent of *SCRIPTEN runtime, just make abort/assert = interpreter Error // to make interpreter independent of *SCRIPTEN runtime, just make abort/assert = interpreter Error
match index { match index {
INDEX_FUNC_ABORT => self.global(ItemIndex::IndexSpace(INDEX_GLOBAL_ABORT)) INDEX_FUNC_ABORT => self.global(ItemIndex::IndexSpace(INDEX_GLOBAL_ABORT))
@ -183,26 +147,17 @@ impl ModuleInstanceInterface for EnvModuleInstance {
.map(|g| g.get()) .map(|g| g.get())
.map(Some), .map(Some),
INDEX_FUNC_MIN_NONUSED ... INDEX_FUNC_MAX => Err(Error::Trap("unimplemented".into())), INDEX_FUNC_MIN_NONUSED ... INDEX_FUNC_MAX => Err(Error::Trap("unimplemented".into())),
idx if idx > INDEX_FUNC_MAX && idx <= INDEX_FUNC_MAX + self.user_functions.len() as u32 => {
// user-defined function
let user_index = idx - (INDEX_FUNC_MAX+1);
let func = self.user_functions.get(user_index as usize).ok_or(Error::Trap(format!("Trying to invoke user-defined function {}", user_index)))?;
func.borrow_mut().call(&self.instance, outer)
},
// idx @ _ if idx == INDEX_FUNC_MAX + 1 => outer.value_stack.pop().map(|_| None), // TODO: `gas(i32) -> None` function
// idx @ _ if idx == INDEX_FUNC_MAX + 2 => Ok(Some(RuntimeValue::I32(0))), // TODO: `_storage_size() -> i32` function
// idx @ _ if idx == INDEX_FUNC_MAX + 3 => outer.value_stack.pop_triple().map(|_| Some(RuntimeValue::I32(0))), // TODO: `_storage_size(i32,i32,i32) -> i32` function
_ => Err(Error::Trap(format!("trying to call function with index {} in env module", index))), _ => Err(Error::Trap(format!("trying to call function with index {} in env module", index))),
} }
} }
} }
pub fn env_module(user_functions: UserFunctions) -> Result<EnvModuleInstance, Error> { pub fn env_module() -> Result<EnvModuleInstance, Error> {
let env_params = EnvParams::default(); let env_params = EnvParams::default();
debug_assert!(env_params.total_stack < env_params.total_memory); debug_assert!(env_params.total_stack < env_params.total_memory);
debug_assert!((env_params.total_stack % LINEAR_MEMORY_PAGE_SIZE) == 0); debug_assert!((env_params.total_stack % LINEAR_MEMORY_PAGE_SIZE) == 0);
debug_assert!((env_params.total_memory % LINEAR_MEMORY_PAGE_SIZE) == 0); debug_assert!((env_params.total_memory % LINEAR_MEMORY_PAGE_SIZE) == 0);
let mut builder = module() let builder = module()
// memory regions // memory regions
.memory() .memory()
.with_min(env_params.total_memory / LINEAR_MEMORY_PAGE_SIZE) .with_min(env_params.total_memory / LINEAR_MEMORY_PAGE_SIZE)
@ -255,29 +210,7 @@ pub fn env_module(user_functions: UserFunctions) -> Result<EnvModuleInstance, Er
.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)));
let mut funcs = user_functions; EnvModuleInstance::new(env_params, builder.build())
let mut internals = UserFunctionsInternals::new();
let mut index = INDEX_FUNC_MAX + 1;
for (func_name, func) in funcs.drain() {
let _location = builder.push_function(
function()
.signature().with_params(func.params).with_return_type(func.result).build()
.build()
);
let _export_idx = builder.push_export(
export()
.field(&func_name)
.internal().func(index)
.build()
);
internals.push(::std::cell::RefCell::new(func.closure));
index += 1;
}
EnvModuleInstance::new(env_params, internals, builder.build())
} }
impl Default for EnvParams { impl Default for EnvParams {

View File

@ -0,0 +1,124 @@
use std::sync::Arc;
use std::collections::HashMap;
use parking_lot::RwLock;
use elements::{FunctionType, Internal, ValueType};
use interpreter::Error;
use interpreter::module::{ModuleInstanceInterface, ExecutionParams, ItemIndex,
CallerContext};
use interpreter::memory::MemoryInstance;
use interpreter::table::TableInstance;
use interpreter::value::RuntimeValue;
use interpreter::variable::VariableInstance;
/// Min index of native function.
pub const NATIVE_INDEX_FUNC_MIN: u32 = 10001;
/// User function closure type.
// pub type UserFunctionClosure<'a> = &'a mut FnMut(context: CallerContext) -> Result<Option<RuntimeValue>, Error>;
/// User functions executor.
pub trait UserFunctionExecutor {
/// Execute function with given name.
fn execute(&mut self, name: &str, context: CallerContext) -> Result<Option<RuntimeValue>, Error>;
}
/// User function type.
pub struct UserFunction {
/// User function name.
pub name: String,
/// User function parameters (for signature matching).
pub params: Vec<ValueType>,
/// User function return type (for signature matching).
pub result: Option<ValueType>,
}
/// Set of user-defined functions
pub struct UserFunctions<'a> {
/// Functions list.
pub functions: Vec<UserFunction>,
/// Functions executor.
pub executor: &'a mut UserFunctionExecutor,
}
/// Native module instance.
pub struct NativeModuleInstance<'a> {
/// Underllying module reference.
env: Arc<ModuleInstanceInterface>,
/// User function executor.
executor: RwLock<&'a mut UserFunctionExecutor>,
/// By-name functions index.
by_name: HashMap<String, u32>,
/// User functions list.
functions: Vec<UserFunction>,
}
impl<'a> NativeModuleInstance<'a> {
/// Create new native module
pub fn new(env: Arc<ModuleInstanceInterface>, functions: UserFunctions<'a>) -> Result<Self, Error> {
Ok(NativeModuleInstance {
env: env,
executor: RwLock::new(functions.executor),
by_name: functions.functions.iter().enumerate().map(|(i, f)| (f.name.clone(), i as u32)).collect(),
functions: functions.functions,
})
}
}
impl<'a> ModuleInstanceInterface for NativeModuleInstance<'a> {
fn execute_main(&self, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> {
self.env.execute_main(params)
}
fn execute_index(&self, index: u32, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> {
self.env.execute_index(index, params)
}
fn execute_export(&self, name: &str, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> {
self.env.execute_export(name, params)
}
fn export_entry(&self, name: &str) -> Result<Internal, Error> {
if let Some(index) = self.by_name.get(name) {
return Ok(Internal::Function(NATIVE_INDEX_FUNC_MIN + *index));
}
self.env.export_entry(name)
}
fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance>, Error> {
self.env.table(index)
}
fn memory(&self, index: ItemIndex) -> Result<Arc<MemoryInstance>, Error> {
self.env.memory(index)
}
fn global(&self, index: ItemIndex) -> Result<Arc<VariableInstance>, Error> {
self.env.global(index)
}
fn call_function(&self, outer: CallerContext, index: ItemIndex) -> Result<Option<RuntimeValue>, Error> {
self.env.call_function(outer, index)
}
fn call_function_indirect(&self, outer: CallerContext, table_index: ItemIndex, type_index: u32, func_index: u32) -> Result<Option<RuntimeValue>, Error> {
self.env.call_function_indirect(outer, table_index, type_index, func_index)
}
fn call_internal_function(&self, outer: CallerContext, index: u32, function_type: Option<&FunctionType>) -> Result<Option<RuntimeValue>, Error> {
if index < NATIVE_INDEX_FUNC_MIN {
return self.env.call_internal_function(outer, index, function_type);
}
// TODO: check type
self.functions
.get((index - NATIVE_INDEX_FUNC_MIN) as usize)
.ok_or(Error::Native(format!("trying to call native function with index {}", index)))
.and_then(|f| self.executor.write().execute(&f.name, outer))
}
}
/// Create wrapper for env module with given native user functions.
pub fn env_native_module(env: Arc<ModuleInstanceInterface>, user_functions: UserFunctions) -> Result<NativeModuleInstance, Error> {
NativeModuleInstance::new(env, user_functions)
}

View File

@ -1,4 +1,5 @@
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use std::collections::HashMap;
use elements::{ImportSection, ImportEntry, External, Internal}; use elements::{ImportSection, ImportEntry, External, Internal};
use interpreter::Error; use interpreter::Error;
use interpreter::memory::MemoryInstance; use interpreter::memory::MemoryInstance;
@ -94,7 +95,13 @@ impl ModuleImports {
} }
/// Get module reference. /// Get module reference.
pub fn module(&self, name: &str) -> Result<Arc<ModuleInstanceInterface>, Error> { pub fn module<'a>(&self, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>, name: &str) -> Result<Arc<ModuleInstanceInterface + 'a>, Error> {
if let Some(externals) = externals {
if let Some(module) = externals.get(name).cloned() {
return Ok(module);
}
}
self.program self.program
.upgrade() .upgrade()
.ok_or(Error::Program("program unloaded".into())) .ok_or(Error::Program("program unloaded".into()))
@ -102,8 +109,8 @@ impl ModuleImports {
} }
/// Get function index. /// Get function index.
pub fn function(&self, import: &ImportEntry) -> Result<u32, Error> { pub fn function<'a>(&self, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>, import: &ImportEntry) -> Result<u32, Error> {
let (_, export) = self.external_export(import)?; let (_, export) = self.external_export(externals, import)?;
if let Internal::Function(external_index) = export { if let Internal::Function(external_index) = export {
return Ok(external_index); return Ok(external_index);
} }
@ -112,8 +119,8 @@ impl ModuleImports {
} }
/// Get table reference. /// Get table reference.
pub fn table(&self, import: &ImportEntry) -> Result<Arc<TableInstance>, Error> { pub fn table<'a>(&self, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>, import: &ImportEntry) -> Result<Arc<TableInstance>, Error> {
let (module, export) = self.external_export(import)?; let (module, export) = self.external_export(externals, import)?;
if let Internal::Table(external_index) = export { if let Internal::Table(external_index) = export {
return module.table(ItemIndex::Internal(external_index)); return module.table(ItemIndex::Internal(external_index));
} }
@ -122,8 +129,8 @@ impl ModuleImports {
} }
/// Get memory reference. /// Get memory reference.
pub fn memory(&self, import: &ImportEntry) -> Result<Arc<MemoryInstance>, Error> { pub fn memory<'a>(&self, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>, import: &ImportEntry) -> Result<Arc<MemoryInstance>, Error> {
let (module, export) = self.external_export(import)?; let (module, export) = self.external_export(externals, import)?;
if let Internal::Memory(external_index) = export { if let Internal::Memory(external_index) = export {
return module.memory(ItemIndex::Internal(external_index)); return module.memory(ItemIndex::Internal(external_index));
} }
@ -132,8 +139,8 @@ impl ModuleImports {
} }
/// Get global reference. /// Get global reference.
pub fn global(&self, import: &ImportEntry) -> Result<Arc<VariableInstance>, Error> { pub fn global<'a>(&self, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>, import: &ImportEntry) -> Result<Arc<VariableInstance>, Error> {
let (module, export) = self.external_export(import)?; let (module, export) = self.external_export(externals, import)?;
if let Internal::Global(external_index) = export { if let Internal::Global(external_index) = export {
return module.global(ItemIndex::Internal(external_index)); return module.global(ItemIndex::Internal(external_index));
} }
@ -141,14 +148,10 @@ impl ModuleImports {
Err(Error::Program(format!("wrong import {} from module {} (expecting global)", import.field(), import.module()))) Err(Error::Program(format!("wrong import {} from module {} (expecting global)", import.field(), import.module())))
} }
fn external_export(&self, import: &ImportEntry) -> Result<(Arc<ModuleInstanceInterface>, Internal), Error> { fn external_export<'a>(&self, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>, import: &ImportEntry) -> Result<(Arc<ModuleInstanceInterface + 'a>, Internal), Error> {
self.module(import.module()) self.module(externals, import.module())
.and_then(|m| m.module().export_section() .and_then(|m|
.ok_or(Error::Program(format!("trying to import from module {} without export section", import.module()))) m.export_entry(import.field())
.and_then(|s| s.entries().iter() .map(|e| (m, e)))
.find(|e| e.field() == import.field())
.map(|e| e.internal())
.ok_or(Error::Program(format!("unresolved import {} from module {}", import.field(), import.module())))
.map(|export| (m.clone(), *export))))
} }
} }

View File

@ -27,6 +27,8 @@ pub enum Error {
Interpreter(String), Interpreter(String),
/// Env module error. /// Env module error.
Env(String), Env(String),
/// Native module error.
Native(String),
/// Trap. /// Trap.
Trap(String), Trap(String),
} }
@ -46,12 +48,14 @@ impl Into<String> for Error {
Error::Interpreter(s) => s, Error::Interpreter(s) => s,
Error::Value(s) => s, Error::Value(s) => s,
Error::Env(s) => s, Error::Env(s) => s,
Error::Native(s) => s,
Error::Trap(s) => format!("trap: {}", s), Error::Trap(s) => format!("trap: {}", s),
} }
} }
} }
mod env; mod env;
mod env_native;
mod imports; mod imports;
mod memory; mod memory;
mod module; mod module;
@ -65,7 +69,10 @@ mod variable;
#[cfg(test)] #[cfg(test)]
mod tests; mod tests;
pub use self::module::{ModuleInstance, ModuleInstanceInterface, ItemIndex, CallerContext}; pub use self::memory::MemoryInstance;
pub use self::module::{ModuleInstance, ModuleInstanceInterface, ItemIndex, CallerContext, ExecutionParams};
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::env::{UserFunctions, UserFunction, UserFunctionInterface}; pub use self::variable::VariableInstance;
pub use self::env_native::{env_native_module, UserFunctions, UserFunction, UserFunctionExecutor};

View File

@ -1,3 +1,4 @@
use std::collections::HashMap;
use std::iter::repeat; use std::iter::repeat;
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use elements::{Module, InitExpr, Opcode, Type, FunctionType, FuncBody, Internal}; use elements::{Module, InitExpr, Opcode, Type, FunctionType, FuncBody, Internal};
@ -11,16 +12,25 @@ use interpreter::table::TableInstance;
use interpreter::value::{RuntimeValue, TryInto, TransmuteInto}; use interpreter::value::{RuntimeValue, TryInto, TransmuteInto};
use interpreter::variable::{VariableInstance, VariableType}; use interpreter::variable::{VariableInstance, VariableType};
#[derive(Default, Clone)]
/// Execution context.
pub struct ExecutionParams<'a> {
/// Arguments.
pub args: Vec<RuntimeValue>,
/// Execution-local external modules.
pub externals: HashMap<String, Arc<ModuleInstanceInterface + 'a>>,
}
/// Module instance API. /// Module instance API.
pub trait ModuleInstanceInterface { pub trait ModuleInstanceInterface {
/// Execute start function of the module. /// Execute start function of the module.
fn execute_main(&self, args: Vec<RuntimeValue>) -> Result<Option<RuntimeValue>, Error>; fn execute_main(&self, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error>;
/// Execute function with the given index. /// Execute function with the given index.
fn execute_index(&self, index: u32, args: Vec<RuntimeValue>) -> Result<Option<RuntimeValue>, Error>; fn execute_index(&self, index: u32, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error>;
/// Execute function with the given export name. /// Execute function with the given export name.
fn execute_export(&self, name: &str, args: Vec<RuntimeValue>) -> Result<Option<RuntimeValue>, Error>; fn execute_export(&self, name: &str, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error>;
/// Get module description reference. /// Get export entry.
fn module(&self) -> &Module; fn export_entry(&self, name: &str) -> Result<Internal, Error>;
/// Get table reference. /// Get table reference.
fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance>, Error>; fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance>, Error>;
/// Get memory reference. /// Get memory reference.
@ -42,7 +52,7 @@ pub enum ItemIndex {
IndexSpace(u32), IndexSpace(u32),
/// Internal item index (i.e. index of item in items section). /// Internal item index (i.e. index of item in items section).
Internal(u32), Internal(u32),
/// External item index (i.e. index of item in the import section). /// External module item index (i.e. index of item in the import section).
External(u32), External(u32),
} }
@ -68,6 +78,35 @@ pub struct CallerContext<'a> {
pub frame_stack_limit: usize, pub frame_stack_limit: usize,
/// Stack of the input parameters /// Stack of the input parameters
pub value_stack: &'a mut StackWithLimit<RuntimeValue>, pub value_stack: &'a mut StackWithLimit<RuntimeValue>,
/// Execution-local external modules.
pub externals: &'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>,
}
impl<'a> ExecutionParams<'a> {
/// Create new execution params with given externa; module override.
pub fn with_external(name: String, module: Arc<ModuleInstanceInterface + 'a>) -> Self {
let mut externals = HashMap::new();
externals.insert(name, module);
ExecutionParams {
args: Vec::new(),
externals: externals,
}
}
/// Add argument.
pub fn add_argument(mut self, arg: RuntimeValue) -> Self {
self.args.push(arg);
self
}
}
impl<'a> From<Vec<RuntimeValue>> for ExecutionParams<'a> {
fn from(args: Vec<RuntimeValue>) -> ExecutionParams<'a> {
ExecutionParams {
args: args,
externals: HashMap::new(),
}
}
} }
impl ModuleInstance { impl ModuleInstance {
@ -149,19 +188,19 @@ impl ModuleInstance {
} }
impl ModuleInstanceInterface for ModuleInstance { impl ModuleInstanceInterface for ModuleInstance {
fn execute_main(&self, args: Vec<RuntimeValue>) -> Result<Option<RuntimeValue>, Error> { fn execute_main(&self, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> {
let index = self.module.start_section().ok_or(Error::Program("module has no start section".into()))?; let index = self.module.start_section().ok_or(Error::Program("module has no start section".into()))?;
self.execute_index(index, args) self.execute_index(index, params)
} }
fn execute_index(&self, index: u32, args: Vec<RuntimeValue>) -> Result<Option<RuntimeValue>, Error> { fn execute_index(&self, index: u32, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> {
let args_len = args.len(); let args_len = params.args.len();
let mut args = StackWithLimit::with_data(args, args_len); let mut args = StackWithLimit::with_data(params.args, args_len);
let caller_context = CallerContext::topmost(&mut args); let caller_context = CallerContext::topmost(&mut args, &params.externals);
self.call_function(caller_context, ItemIndex::IndexSpace(index)) self.call_function(caller_context, ItemIndex::IndexSpace(index))
} }
fn execute_export(&self, name: &str, args: Vec<RuntimeValue>) -> Result<Option<RuntimeValue>, Error> { fn execute_export(&self, name: &str, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> {
let index = self.module.export_section() let index = self.module.export_section()
.ok_or(Error::Function("missing export section".into())) .ok_or(Error::Function("missing export section".into()))
.and_then(|s| s.entries().iter() .and_then(|s| s.entries().iter()
@ -175,11 +214,16 @@ impl ModuleInstanceInterface for ModuleInstance {
_ => unreachable!(), // checked couple of lines above _ => unreachable!(), // checked couple of lines above
}) })
)?; )?;
self.execute_index(index, args) self.execute_index(index, params)
} }
fn module(&self) -> &Module { fn export_entry(&self, name: &str) -> Result<Internal, Error> {
&self.module self.module.export_section()
.ok_or(Error::Program(format!("trying to import {} from module without export section", name)))
.and_then(|s| s.entries().iter()
.find(|e| e.field() == name)
.map(|e| *e.internal())
.ok_or(Error::Program(format!("unresolved import {}", name))))
} }
fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance>, Error> { fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance>, Error> {
@ -191,7 +235,7 @@ impl ModuleInstanceInterface for ModuleInstance {
.ok_or(Error::Table(format!("trying to access external table with index {} in module without import section", index))) .ok_or(Error::Table(format!("trying to access external table with index {} in module without import section", index)))
.and_then(|s| s.entries().get(index as usize) .and_then(|s| s.entries().get(index as usize)
.ok_or(Error::Table(format!("trying to access external table with index {} in module with {}-entries import section", index, s.entries().len())))) .ok_or(Error::Table(format!("trying to access external table with index {} in module with {}-entries import section", index, s.entries().len()))))
.and_then(|e| self.imports.table(e)), .and_then(|e| self.imports.table(None, e)),
} }
} }
@ -204,7 +248,7 @@ impl ModuleInstanceInterface for ModuleInstance {
.ok_or(Error::Memory(format!("trying to access external memory with index {} in module without import section", index))) .ok_or(Error::Memory(format!("trying to access external memory with index {} in module without import section", index)))
.and_then(|s| s.entries().get(index as usize) .and_then(|s| s.entries().get(index as usize)
.ok_or(Error::Memory(format!("trying to access external memory with index {} in module with {}-entries import section", index, s.entries().len())))) .ok_or(Error::Memory(format!("trying to access external memory with index {} in module with {}-entries import section", index, s.entries().len()))))
.and_then(|e| self.imports.memory(e)), .and_then(|e| self.imports.memory(None, e)),
} }
} }
@ -217,7 +261,7 @@ impl ModuleInstanceInterface for ModuleInstance {
.ok_or(Error::Global(format!("trying to access external global with index {} in module without import section", index))) .ok_or(Error::Global(format!("trying to access external global with index {} in module without import section", index)))
.and_then(|s| s.entries().get(index as usize) .and_then(|s| s.entries().get(index as usize)
.ok_or(Error::Global(format!("trying to access external global with index {} in module with {}-entries import section", index, s.entries().len())))) .ok_or(Error::Global(format!("trying to access external global with index {} in module with {}-entries import section", index, s.entries().len()))))
.and_then(|e| self.imports.global(e)), .and_then(|e| self.imports.global(None, e)),
} }
} }
@ -230,7 +274,7 @@ impl ModuleInstanceInterface for ModuleInstance {
.ok_or(Error::Function(format!("trying to access external function with index {} in module without import section", index))) .ok_or(Error::Function(format!("trying to access external function with index {} in module without import section", index)))
.and_then(|s| s.entries().get(index as usize) .and_then(|s| s.entries().get(index as usize)
.ok_or(Error::Function(format!("trying to access external function with index {} in module with {}-entries import section", index, s.entries().len())))) .ok_or(Error::Function(format!("trying to access external function with index {} in module with {}-entries import section", index, s.entries().len()))))
.and_then(|e| Ok((self.imports.module(e.module())?, self.imports.function(e)?))) .and_then(|e| Ok((self.imports.module(Some(outer.externals), e.module())?, self.imports.function(Some(outer.externals), e)?)))
.and_then(|(m, index)| m.call_internal_function(outer, index, None)), .and_then(|(m, index)| m.call_internal_function(outer, index, None)),
} }
} }
@ -263,13 +307,13 @@ impl ModuleInstanceInterface for ModuleInstance {
.ok_or(Error::Function(format!("trying to access external table with index {} in module without import section", table_index))) .ok_or(Error::Function(format!("trying to access external table with index {} in module without import section", table_index)))
.and_then(|s| s.entries().get(table_index as usize) .and_then(|s| s.entries().get(table_index as usize)
.ok_or(Error::Function(format!("trying to access external table with index {} in module with {}-entries import section", table_index, s.entries().len())))) .ok_or(Error::Function(format!("trying to access external table with index {} in module with {}-entries import section", table_index, s.entries().len()))))
.and_then(|e| self.imports.module(e.module()))?; .and_then(|e| self.imports.module(Some(outer.externals), e.module()))?;
module.call_internal_function(outer, index, Some(function_type)) module.call_internal_function(outer, index, Some(function_type))
} }
} }
} }
fn call_internal_function(&self, outer: CallerContext, index: u32, function_type: Option<&FunctionType>) -> Result<Option<RuntimeValue>, Error> { fn call_internal_function(&self, mut outer: CallerContext, index: u32, function_type: Option<&FunctionType>) -> Result<Option<RuntimeValue>, Error> {
// TODO: cache // TODO: cache
// internal index = index of function in functions section && index of code in code section // internal index = index of function in functions section && index of code in code section
// get function type index // get function type index
@ -311,19 +355,20 @@ impl ModuleInstanceInterface for ModuleInstance {
let function_code = function_body.code().elements(); let function_code = function_body.code().elements();
let value_stack_limit = outer.value_stack_limit; let value_stack_limit = outer.value_stack_limit;
let frame_stack_limit = outer.frame_stack_limit; let frame_stack_limit = outer.frame_stack_limit;
let locals = prepare_function_locals(actual_function_type, function_body, outer)?; let locals = prepare_function_locals(actual_function_type, function_body, &mut outer)?;
let mut innner = FunctionContext::new(self, value_stack_limit, frame_stack_limit, actual_function_type, function_code, locals)?; let mut innner = FunctionContext::new(self, outer.externals, value_stack_limit, frame_stack_limit, actual_function_type, function_code, locals)?;
Interpreter::run_function(&mut innner, function_code) Interpreter::run_function(&mut innner, function_code)
} }
} }
impl<'a> CallerContext<'a> { impl<'a> CallerContext<'a> {
/// Top most args /// Top most args
pub fn topmost(args: &'a mut StackWithLimit<RuntimeValue>) -> Self { pub fn topmost(args: &'a mut StackWithLimit<RuntimeValue>, externals: &'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>) -> Self {
CallerContext { CallerContext {
value_stack_limit: 1024, value_stack_limit: 1024,
frame_stack_limit: 1024, frame_stack_limit: 1024,
value_stack: args, value_stack: args,
externals: externals,
} }
} }
@ -332,12 +377,13 @@ impl<'a> CallerContext<'a> {
CallerContext { CallerContext {
value_stack_limit: outer.value_stack().limit() - outer.value_stack().len(), value_stack_limit: outer.value_stack().limit() - outer.value_stack().len(),
frame_stack_limit: outer.frame_stack().limit() - outer.frame_stack().len(), frame_stack_limit: outer.frame_stack().limit() - outer.frame_stack().len(),
value_stack: outer.value_stack_mut(), value_stack: &mut outer.value_stack,
externals: &outer.externals,
} }
} }
} }
fn prepare_function_locals(function_type: &FunctionType, function_body: &FuncBody, outer: CallerContext) -> Result<Vec<VariableInstance>, Error> { fn prepare_function_locals(function_type: &FunctionType, function_body: &FuncBody, outer: &mut CallerContext) -> Result<Vec<VariableInstance>, Error> {
// locals = function arguments + defined locals // locals = function arguments + defined locals
function_type.params().iter().rev() function_type.params().iter().rev()
.map(|param_type| { .map(|param_type| {
@ -370,7 +416,7 @@ fn get_initializer(expr: &InitExpr, module: &Module, imports: &ModuleImports) ->
.ok_or(Error::Global(format!("trying to initialize with external global with index {} in module without import section", index))) .ok_or(Error::Global(format!("trying to initialize with external global with index {} in module without import section", index)))
.and_then(|s| s.entries().get(index as usize) .and_then(|s| s.entries().get(index as usize)
.ok_or(Error::Global(format!("trying to initialize with external global with index {} in module with {}-entries import section", index, s.entries().len())))) .ok_or(Error::Global(format!("trying to initialize with external global with index {} in module with {}-entries import section", index, s.entries().len()))))
.and_then(|e| imports.global(e)) .and_then(|e| imports.global(None, e))
.map(|g| g.get()) .map(|g| g.get())
}, },
&Opcode::I32Const(val) => Ok(RuntimeValue::I32(val)), &Opcode::I32Const(val) => Ok(RuntimeValue::I32(val)),

View File

@ -1,10 +1,9 @@
use std::sync::Arc; use std::sync::Arc;
use std::collections::HashMap; use std::collections::HashMap;
use std::collections::hash_map::Entry;
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::env::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.
@ -27,24 +26,12 @@ impl ProgramInstance {
}) })
} }
/// Create new program instance with predefined user-defined functions
pub fn with_functions(funcs: env::UserFunctions) -> Result<Self, Error> {
Ok(ProgramInstance {
essence: Arc::new(ProgramInstanceEssence::with_functions(funcs)?),
})
}
/// Instantiate module. /// Instantiate module.
pub fn add_module(&self, name: &str, module: Module) -> Result<Arc<ModuleInstance>, Error> { pub fn add_module(&self, name: &str, module: Module) -> Result<Arc<ModuleInstance>, Error> {
let module_instance = Arc::new(ModuleInstance::new(Arc::downgrade(&self.essence), module)?); let module_instance = Arc::new(ModuleInstance::new(Arc::downgrade(&self.essence), module)?);
let mut modules = self.essence.modules.write(); // replace existing module with the same name with new one
match modules.entry(name.into()) { self.essence.modules.write().insert(name.into(), module_instance.clone());
Entry::Occupied(_) => Err(Error::Program(format!("module {} already instantiated", name))), Ok(module_instance)
Entry::Vacant(entry) => {
entry.insert(module_instance.clone());
Ok(module_instance)
},
}
} }
/// Get one of the modules by name /// Get one of the modules by name
@ -56,13 +43,8 @@ impl ProgramInstance {
impl ProgramInstanceEssence { impl ProgramInstanceEssence {
/// Create new program essence. /// Create new program essence.
pub fn new() -> Result<Self, Error> { pub fn new() -> Result<Self, Error> {
ProgramInstanceEssence::with_functions(HashMap::with_capacity(0))
}
/// Create new program essence with provided user-defined functions
pub fn with_functions(funcs: env::UserFunctions) -> Result<Self, Error> {
let mut modules = HashMap::new(); let mut modules = HashMap::new();
let env_module: Arc<ModuleInstanceInterface> = Arc::new(env_module(funcs)?); let env_module: Arc<ModuleInstanceInterface> = Arc::new(env_module()?);
modules.insert("env".into(), env_module); modules.insert("env".into(), env_module);
Ok(ProgramInstanceEssence { Ok(ProgramInstanceEssence {
modules: RwLock::new(modules), modules: RwLock::new(modules),

View File

@ -1,7 +1,9 @@
use std::mem; use std::mem;
use std::ops; use std::ops;
use std::u32; use std::u32;
use std::sync::Arc;
use std::fmt::Display; use std::fmt::Display;
use std::collections::HashMap;
use elements::{Opcode, BlockType, FunctionType}; use elements::{Opcode, BlockType, FunctionType};
use interpreter::Error; use interpreter::Error;
use interpreter::module::{ModuleInstance, ModuleInstanceInterface, CallerContext, ItemIndex}; use interpreter::module::{ModuleInstance, ModuleInstanceInterface, CallerContext, ItemIndex};
@ -18,17 +20,19 @@ pub struct Interpreter;
/// Function execution context. /// Function execution context.
pub struct FunctionContext<'a> { pub struct FunctionContext<'a> {
/// Module instance. /// Module instance.
module: &'a ModuleInstance, pub module: &'a ModuleInstance,
/// Execution-local external modules.
pub externals: &'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>,
/// Function return type. /// Function return type.
return_type: BlockType, pub return_type: BlockType,
/// Local variables. /// Local variables.
locals: Vec<VariableInstance>, pub locals: Vec<VariableInstance>,
/// Values stack. /// Values stack.
value_stack: StackWithLimit<RuntimeValue>, pub value_stack: StackWithLimit<RuntimeValue>,
/// Blocks frames stack. /// Blocks frames stack.
frame_stack: StackWithLimit<BlockFrame>, pub frame_stack: StackWithLimit<BlockFrame>,
/// Current instruction position. /// Current instruction position.
position: usize, pub position: usize,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -868,9 +872,10 @@ impl Interpreter {
} }
impl<'a> FunctionContext<'a> { impl<'a> FunctionContext<'a> {
pub fn new(module: &'a ModuleInstance, value_stack_limit: usize, frame_stack_limit: usize, function: &FunctionType, body: &[Opcode], args: Vec<VariableInstance>) -> Result<Self, Error> { pub fn new(module: &'a ModuleInstance, externals: &'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>, value_stack_limit: usize, frame_stack_limit: usize, function: &FunctionType, body: &[Opcode], args: Vec<VariableInstance>) -> Result<Self, Error> {
let mut context = FunctionContext { let mut context = FunctionContext {
module: module, module: module,
externals: externals,
return_type: function.return_type().map(|vt| BlockType::Value(vt)).unwrap_or(BlockType::NoResult), return_type: function.return_type().map(|vt| BlockType::Value(vt)).unwrap_or(BlockType::NoResult),
value_stack: StackWithLimit::with_limit(value_stack_limit), value_stack: StackWithLimit::with_limit(value_stack_limit),
frame_stack: StackWithLimit::with_limit(frame_stack_limit), frame_stack: StackWithLimit::with_limit(frame_stack_limit),
@ -888,6 +893,10 @@ impl<'a> FunctionContext<'a> {
self.module self.module
} }
pub fn externals(&self) -> &HashMap<String, Arc<ModuleInstanceInterface + 'a>> {
&self.externals
}
pub fn call_function(&mut self, index: u32) -> Result<Option<RuntimeValue>, Error> { pub fn call_function(&mut self, index: u32) -> Result<Option<RuntimeValue>, Error> {
self.module.call_function(CallerContext::nested(self), ItemIndex::IndexSpace(index)) self.module.call_function(CallerContext::nested(self), ItemIndex::IndexSpace(index))
} }

View File

@ -1,10 +1,13 @@
///! Basic tests for instructions/constructions, missing in wabt tests ///! Basic tests for instructions/constructions, missing in wabt tests
use std::sync::Arc;
use builder::module; use builder::module;
use elements::{ExportEntry, Internal, ImportEntry, External, GlobalEntry, GlobalType, use elements::{ExportEntry, Internal, ImportEntry, External, GlobalEntry, GlobalType,
InitExpr, ValueType, Opcodes, Opcode}; InitExpr, ValueType, Opcodes, Opcode};
use interpreter::Error; use interpreter::Error;
use interpreter::module::{ModuleInstanceInterface, CallerContext}; use interpreter::env_native::{env_native_module, UserFunction, UserFunctions, UserFunctionExecutor};
use interpreter::memory::MemoryInstance;
use interpreter::module::{ModuleInstanceInterface, CallerContext, ItemIndex, ExecutionParams};
use interpreter::program::ProgramInstance; use interpreter::program::ProgramInstance;
use interpreter::value::RuntimeValue; use interpreter::value::RuntimeValue;
@ -38,8 +41,8 @@ fn import_function() {
let external_module = program.add_module("external_module", module1).unwrap(); let external_module = program.add_module("external_module", module1).unwrap();
let main_module = program.add_module("main", module2).unwrap(); let main_module = program.add_module("main", module2).unwrap();
assert_eq!(external_module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::I32(3)); assert_eq!(external_module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(3));
assert_eq!(main_module.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(10)); assert_eq!(main_module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(10));
} }
#[test] #[test]
@ -72,7 +75,7 @@ fn wrong_import() {
let _side_module_instance = program.add_module("side_module", side_module).unwrap(); let _side_module_instance = program.add_module("side_module", side_module).unwrap();
let module_instance = program.add_module("main", module).unwrap(); let module_instance = program.add_module("main", module).unwrap();
assert!(module_instance.execute_index(1, vec![]).is_err()); assert!(module_instance.execute_index(1, vec![].into()).is_err());
} }
#[test] #[test]
@ -115,112 +118,102 @@ fn global_get_set() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::I32(50)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(50));
assert_eq!(module.execute_index(1, vec![]).unwrap_err(), Error::Variable("trying to update immutable variable".into())); assert_eq!(module.execute_index(1, vec![].into()).unwrap_err(), Error::Variable("trying to update immutable variable".into()));
assert_eq!(module.execute_index(2, vec![]).unwrap_err(), Error::Variable("trying to update variable of type I32 with value of type Some(I64)".into())); assert_eq!(module.execute_index(2, vec![].into()).unwrap_err(), Error::Variable("trying to update variable of type I32 with value of type Some(I64)".into()));
} }
#[test] #[test]
fn with_user_functions() { fn single_program_different_modules() {
use interpreter::{UserFunction, UserFunctions, ModuleInstance}; // user function executor
struct FunctionExecutor {
pub memory: Arc<MemoryInstance>,
pub values: Vec<i32>,
}
impl UserFunctionExecutor for FunctionExecutor {
fn execute(&mut self, name: &str, context: CallerContext) -> Result<Option<RuntimeValue>, Error> {
match name {
"add" => {
let memory_value = self.memory.get(0, 1).unwrap()[0];
let fn_argument = context.value_stack.pop_as::<u32>().unwrap() as u8;
let sum = memory_value + fn_argument;
self.memory.set(0, &vec![sum]).unwrap();
self.values.push(sum as i32);
Ok(Some(RuntimeValue::I32(sum as i32)))
},
"sub" => {
let memory_value = self.memory.get(0, 1).unwrap()[0];
let fn_argument = context.value_stack.pop_as::<u32>().unwrap() as u8;
let diff = memory_value - fn_argument;
self.memory.set(0, &vec![diff]).unwrap();
self.values.push(diff as i32);
Ok(Some(RuntimeValue::I32(diff as i32)))
},
_ => Err(Error::Trap("not implemented".into())),
}
}
}
// create new program
let program = ProgramInstance::new().unwrap();
// => env module is created
let env_instance = program.module("env").unwrap();
// => linear memory is created
let env_memory = env_instance.memory(ItemIndex::Internal(0)).unwrap();
let module = module() let module = module()
.with_import(ImportEntry::new("env".into(), "custom_alloc".into(), External::Function(0))) .with_import(ImportEntry::new("env".into(), "add".into(), External::Function(0)))
.with_import(ImportEntry::new("env".into(), "custom_increment".into(), External::Function(0))) .with_import(ImportEntry::new("env".into(), "sub".into(), External::Function(0)))
.function() .function()
.signature().return_type().i32().build() .signature().param().i32().return_type().i32().build()
.body().with_opcodes(Opcodes::new(vec![ .body().with_opcodes(Opcodes::new(vec![
Opcode::I32Const(32), Opcode::GetLocal(0),
Opcode::Call(0), Opcode::Call(0),
Opcode::End, Opcode::End,
])).build() ])).build()
.build() .build()
.function()
.signature().param().i32().return_type().i32().build()
.body().with_opcodes(Opcodes::new(vec![
Opcode::GetLocal(0),
Opcode::Call(1),
Opcode::End,
])).build()
.build()
.build(); .build();
let mut top = 0i32; // load module
let mut user_functions = UserFunctions::new(); let module_instance = program.add_module("main", module).unwrap();
user_functions.insert(
"custom_alloc".to_owned(),
UserFunction {
params: vec![ValueType::I32],
result: Some(ValueType::I32),
closure: Box::new(move |_module: &ModuleInstance, context: CallerContext| {
let prev = top;
top = top + context.value_stack.pop_as::<i32>()?;
Ok(Some(prev.into()))
}),
}
);
let mut rolling = 9999i32; let mut executor = FunctionExecutor {
user_functions.insert( memory: env_memory.clone(),
"custom_increment".to_owned(), values: Vec::new(),
UserFunction { };
params: vec![ValueType::I32], {
result: Some(ValueType::I32), // create native env module with native add && sub implementations
closure: Box::new(move |_module: &ModuleInstance, _context: CallerContext| { let functions: UserFunctions = UserFunctions {
rolling = rolling + 1; executor: &mut executor,
Ok(Some(rolling.into())) functions: vec![UserFunction {
}), name: "add".into(),
} params: vec![ValueType::I32],
); result: Some(ValueType::I32),
}, UserFunction {
name: "sub".into(),
params: vec![ValueType::I32],
result: Some(ValueType::I32),
}],
};
let native_env_instance = Arc::new(env_native_module(env_instance, functions).unwrap());
let program = ProgramInstance::with_functions(user_functions).unwrap(); // execute functions
let module_instance = program.add_module("main", module).unwrap(); let params = ExecutionParams::with_external("env".into(), native_env_instance);
// internal function using first import assert_eq!(module_instance.execute_index(2, params.clone().add_argument(RuntimeValue::I32(7))).unwrap().unwrap(), RuntimeValue::I32(7));
assert_eq!(module_instance.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module_instance.execute_index(2, params.clone().add_argument(RuntimeValue::I32(50))).unwrap().unwrap(), RuntimeValue::I32(57));
assert_eq!(module_instance.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(32)); assert_eq!(module_instance.execute_index(3, params.clone().add_argument(RuntimeValue::I32(15))).unwrap().unwrap(), RuntimeValue::I32(42));
assert_eq!(module_instance.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(64)); }
// second import assert_eq!(executor.memory.get(0, 1).unwrap()[0], 42);
assert_eq!(module_instance.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(10000)); assert_eq!(executor.values, vec![7, 57, 42]);
assert_eq!(module_instance.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(10001));
} }
#[test]
fn with_user_functions_extended() {
use interpreter::{UserFunction, UserFunctions, UserFunctionInterface, ModuleInstance};
struct UserMAlloc {
top: i32,
}
impl UserFunctionInterface for UserMAlloc {
fn call(&mut self, _module: &ModuleInstance, context: CallerContext) -> Result<Option<RuntimeValue>, Error> {
let prev = self.top;
self.top += context.value_stack.pop_as::<i32>()?;
Ok(Some(prev.into()))
}
}
let module = module()
.with_import(ImportEntry::new("env".into(), "_malloc".into(), External::Function(0)))
.function()
.signature().return_type().i32().build()
.body().with_opcodes(Opcodes::new(vec![
Opcode::I32Const(32),
Opcode::Call(0),
Opcode::End,
])).build()
.build()
.build();
let mut user_functions = UserFunctions::new();
user_functions.insert(
"_malloc".to_owned(),
UserFunction {
params: vec![ValueType::I32],
result: Some(ValueType::I32),
closure: Box::new(UserMAlloc { top: 0 }),
}
);
let program = ProgramInstance::with_functions(user_functions).unwrap();
let module_instance = program.add_module("main", module).unwrap();
// internal function using first import
assert_eq!(module_instance.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module_instance.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(32));
assert_eq!(module_instance.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(64));
}

View File

@ -1,6 +1,7 @@
///! Tests from https://github.com/WebAssembly/wabt/tree/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp ///! Tests from https://github.com/WebAssembly/wabt/tree/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp
use std::sync::Weak; use std::sync::Weak;
use std::collections::HashMap;
use builder::module; use builder::module;
use elements::{Module, ValueType, Opcodes, Opcode, BlockType, FunctionType}; use elements::{Module, ValueType, Opcodes, Opcode, BlockType, FunctionType};
use interpreter::Error; use interpreter::Error;
@ -13,7 +14,8 @@ use interpreter::variable::{VariableInstance, VariableType};
fn run_function_i32(body: &Opcodes, arg: i32) -> Result<i32, Error> { fn run_function_i32(body: &Opcodes, arg: i32) -> Result<i32, Error> {
let ftype = FunctionType::new(vec![ValueType::I32], Some(ValueType::I32)); let ftype = FunctionType::new(vec![ValueType::I32], Some(ValueType::I32));
let module = ModuleInstance::new(Weak::default(), Module::default()).unwrap(); let module = ModuleInstance::new(Weak::default(), Module::default()).unwrap();
let mut context = FunctionContext::new(&module, 1024, 1024, &ftype, body.elements(), vec![ let externals = HashMap::new();
let mut context = FunctionContext::new(&module, &externals, 1024, 1024, &ftype, body.elements(), vec![
VariableInstance::new(true, VariableType::I32, RuntimeValue::I32(arg)).unwrap(), // arg VariableInstance::new(true, VariableType::I32, RuntimeValue::I32(arg)).unwrap(), // arg
VariableInstance::new(true, VariableType::I32, RuntimeValue::I32(0)).unwrap(), // local1 VariableInstance::new(true, VariableType::I32, RuntimeValue::I32(0)).unwrap(), // local1
VariableInstance::new(true, VariableType::I32, RuntimeValue::I32(0)).unwrap(), // local2 VariableInstance::new(true, VariableType::I32, RuntimeValue::I32(0)).unwrap(), // local2
@ -522,11 +524,11 @@ fn return_void() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
module.execute_main(vec![RuntimeValue::I32(0)]).unwrap(); module.execute_main(vec![RuntimeValue::I32(0)].into()).unwrap();
let memory = module.memory(ItemIndex::IndexSpace(0)).unwrap(); let memory = module.memory(ItemIndex::IndexSpace(0)).unwrap();
assert_eq!(memory.get(0, 4).unwrap(), vec![0, 0, 0, 0]); assert_eq!(memory.get(0, 4).unwrap(), vec![0, 0, 0, 0]);
module.execute_main(vec![RuntimeValue::I32(1)]).unwrap(); module.execute_main(vec![RuntimeValue::I32(1)].into()).unwrap();
let memory = module.memory(ItemIndex::IndexSpace(0)).unwrap(); let memory = module.memory(ItemIndex::IndexSpace(0)).unwrap();
assert_eq!(memory.get(0, 4).unwrap(), vec![1, 0, 0, 0]); assert_eq!(memory.get(0, 4).unwrap(), vec![1, 0, 0, 0]);
} }
@ -580,7 +582,7 @@ fn call_1() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_main(vec![]).unwrap().unwrap(), RuntimeValue::I32(10)); assert_eq!(module.execute_main(vec![].into()).unwrap().unwrap(), RuntimeValue::I32(10));
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/call.txt#L23 /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/call.txt#L23
@ -629,7 +631,7 @@ fn call_2() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_main(vec![]).unwrap().unwrap(), RuntimeValue::I32(3628800)); assert_eq!(module.execute_main(vec![].into()).unwrap().unwrap(), RuntimeValue::I32(3628800));
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/call-zero-args.txt /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/call-zero-args.txt
@ -674,7 +676,7 @@ fn call_zero_args() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_main(vec![]).unwrap().unwrap(), RuntimeValue::I32(43)); assert_eq!(module.execute_main(vec![].into()).unwrap().unwrap(), RuntimeValue::I32(43));
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/callindirect.txt#L31 /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/callindirect.txt#L31
@ -720,8 +722,8 @@ fn callindirect_1() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_main(vec![RuntimeValue::I32(0)]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_main(vec![RuntimeValue::I32(0)].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_main(vec![RuntimeValue::I32(1)]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_main(vec![RuntimeValue::I32(1)].into()).unwrap().unwrap(), RuntimeValue::I32(1));
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/callindirect.txt#L39 /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/callindirect.txt#L39
@ -793,11 +795,11 @@ fn callindirect_2() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_main(vec![RuntimeValue::I32(10), RuntimeValue::I32(4), RuntimeValue::I32(0)]).unwrap().unwrap(), RuntimeValue::I32(14)); assert_eq!(module.execute_main(vec![RuntimeValue::I32(10), RuntimeValue::I32(4), RuntimeValue::I32(0)].into()).unwrap().unwrap(), RuntimeValue::I32(14));
assert_eq!(module.execute_main(vec![RuntimeValue::I32(10), RuntimeValue::I32(4), RuntimeValue::I32(1)]).unwrap().unwrap(), RuntimeValue::I32(6)); assert_eq!(module.execute_main(vec![RuntimeValue::I32(10), RuntimeValue::I32(4), RuntimeValue::I32(1)].into()).unwrap().unwrap(), RuntimeValue::I32(6));
assert_eq!(module.execute_main(vec![RuntimeValue::I32(10), RuntimeValue::I32(4), RuntimeValue::I32(2)]).unwrap_err(), assert_eq!(module.execute_main(vec![RuntimeValue::I32(10), RuntimeValue::I32(4), RuntimeValue::I32(2)].into()).unwrap_err(),
Error::Function("expected function with signature ([I32, I32]) -> Some(I32) when got with ([I32]) -> Some(I32)".into())); Error::Function("expected function with signature ([I32, I32]) -> Some(I32) when got with ([I32]) -> Some(I32)".into()));
assert_eq!(module.execute_main(vec![RuntimeValue::I32(10), RuntimeValue::I32(4), RuntimeValue::I32(3)]).unwrap_err(), assert_eq!(module.execute_main(vec![RuntimeValue::I32(10), RuntimeValue::I32(4), RuntimeValue::I32(3)].into()).unwrap_err(),
Error::Table("trying to read table item with index 3 when there are only 3 items".into())); Error::Table("trying to read table item with index 3 when there are only 3 items".into()));
} }
@ -861,14 +863,14 @@ fn select() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_index(0, vec![RuntimeValue::I32(0)]).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)]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(0, vec![RuntimeValue::I32(1)].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(1, vec![RuntimeValue::I32(0)]).unwrap().unwrap(), RuntimeValue::I64(2)); assert_eq!(module.execute_index(1, vec![RuntimeValue::I32(0)].into()).unwrap().unwrap(), RuntimeValue::I64(2));
assert_eq!(module.execute_index(1, vec![RuntimeValue::I32(1)]).unwrap().unwrap(), RuntimeValue::I64(1)); assert_eq!(module.execute_index(1, vec![RuntimeValue::I32(1)].into()).unwrap().unwrap(), RuntimeValue::I64(1));
assert_eq!(module.execute_index(2, vec![RuntimeValue::I32(0)]).unwrap().unwrap(), RuntimeValue::F32(2f32)); assert_eq!(module.execute_index(2, vec![RuntimeValue::I32(0)].into()).unwrap().unwrap(), RuntimeValue::F32(2f32));
assert_eq!(module.execute_index(2, vec![RuntimeValue::I32(1)]).unwrap().unwrap(), RuntimeValue::F32(1f32)); assert_eq!(module.execute_index(2, vec![RuntimeValue::I32(1)].into()).unwrap().unwrap(), RuntimeValue::F32(1f32));
assert_eq!(module.execute_index(3, vec![RuntimeValue::I32(0)]).unwrap().unwrap(), RuntimeValue::F64(2f64)); assert_eq!(module.execute_index(3, vec![RuntimeValue::I32(0)].into()).unwrap().unwrap(), RuntimeValue::F64(2f64));
assert_eq!(module.execute_index(3, vec![RuntimeValue::I32(1)]).unwrap().unwrap(), RuntimeValue::F64(1f64)); assert_eq!(module.execute_index(3, vec![RuntimeValue::I32(1)].into()).unwrap().unwrap(), RuntimeValue::F64(1f64));
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/binary.txt#L3 /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/binary.txt#L3
@ -1014,21 +1016,21 @@ fn binary_i32() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_index(0, vec![]).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![]).unwrap().unwrap(), RuntimeValue::I32(16)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(16));
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(21)); assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(21));
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(-2)); // 4294967294 assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-2)); // 4294967294
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I32(2147483646)); assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(2147483646));
assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::I32(-1)); // 4294967295 assert_eq!(module.execute_index(5, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1)); // 4294967295
assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(6, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(7, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(7, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(8, vec![]).unwrap().unwrap(), RuntimeValue::I32(15)); assert_eq!(module.execute_index(8, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(15));
assert_eq!(module.execute_index(9, vec![]).unwrap().unwrap(), RuntimeValue::I32(14)); assert_eq!(module.execute_index(9, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(14));
assert_eq!(module.execute_index(10, vec![]).unwrap().unwrap(), RuntimeValue::I32(-800)); // 4294966496 assert_eq!(module.execute_index(10, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-800)); // 4294966496
assert_eq!(module.execute_index(11, vec![]).unwrap().unwrap(), RuntimeValue::I32(536870899)); assert_eq!(module.execute_index(11, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(536870899));
assert_eq!(module.execute_index(12, vec![]).unwrap().unwrap(), RuntimeValue::I32(-13)); // 4294967283 assert_eq!(module.execute_index(12, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-13)); // 4294967283
assert_eq!(module.execute_index(13, vec![]).unwrap().unwrap(), RuntimeValue::I32(-793)); // 4294966503 assert_eq!(module.execute_index(13, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-793)); // 4294966503
assert_eq!(module.execute_index(14, vec![]).unwrap().unwrap(), RuntimeValue::I32(-1610612749)); // 2684354547 assert_eq!(module.execute_index(14, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1610612749)); // 2684354547
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/binary.txt#L65 /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/binary.txt#L65
@ -1174,21 +1176,21 @@ fn binary_i64() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_index(0, vec![]).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![]).unwrap().unwrap(), RuntimeValue::I64(16)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(16));
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I64(21)); assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(21));
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I64(-2)); // 18446744073709551614 assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-2)); // 18446744073709551614
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I64(9223372036854775806)); assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(9223372036854775806));
assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::I64(-1)); // 18446744073709551615 assert_eq!(module.execute_index(5, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-1)); // 18446744073709551615
assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::I64(1)); assert_eq!(module.execute_index(6, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(1));
assert_eq!(module.execute_index(7, vec![]).unwrap().unwrap(), RuntimeValue::I64(1)); assert_eq!(module.execute_index(7, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(1));
assert_eq!(module.execute_index(8, vec![]).unwrap().unwrap(), RuntimeValue::I64(15)); assert_eq!(module.execute_index(8, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(15));
assert_eq!(module.execute_index(9, vec![]).unwrap().unwrap(), RuntimeValue::I64(14)); assert_eq!(module.execute_index(9, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(14));
assert_eq!(module.execute_index(10, vec![]).unwrap().unwrap(), RuntimeValue::I64(-800)); // 18446744073709550816 assert_eq!(module.execute_index(10, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-800)); // 18446744073709550816
assert_eq!(module.execute_index(11, vec![]).unwrap().unwrap(), RuntimeValue::I64(2305843009213693939)); assert_eq!(module.execute_index(11, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(2305843009213693939));
assert_eq!(module.execute_index(12, vec![]).unwrap().unwrap(), RuntimeValue::I64(-13)); // 18446744073709551603 assert_eq!(module.execute_index(12, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-13)); // 18446744073709551603
assert_eq!(module.execute_index(13, vec![]).unwrap().unwrap(), RuntimeValue::I64(-793)); // 18446744073709550823 assert_eq!(module.execute_index(13, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-793)); // 18446744073709550823
assert_eq!(module.execute_index(14, vec![]).unwrap().unwrap(), RuntimeValue::I64(-6917529027641081869)); // 11529215046068469747 assert_eq!(module.execute_index(14, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-6917529027641081869)); // 11529215046068469747
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/binary.txt#L3 /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/binary.txt#L3
@ -1264,13 +1266,13 @@ fn binary_f32() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_index(0, vec![]).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![]).unwrap().unwrap(), RuntimeValue::F32(-9995.500000)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(-9995.500000));
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::F32(-8487.187500)); assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(-8487.187500));
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::F32(-500000000.000000)); assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(-500000000.000000));
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::F32(0.000000)); assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(0.000000));
assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::F32(0.000000)); assert_eq!(module.execute_index(5, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(0.000000));
assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::F32(0.000000)); assert_eq!(module.execute_index(6, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(0.000000));
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/binary.txt#L157 /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/binary.txt#L157
@ -1346,15 +1348,15 @@ fn binary_f64() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_index(0, vec![]).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![]).unwrap().unwrap(), RuntimeValue::F64(123400000000000007812762268812638756607430593436581896388608.000000)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(123400000000000007812762268812638756607430593436581896388608.000000));
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::F64(-15179717820000.000000)); assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(-15179717820000.000000));
// in wabt result is 99999999999999998083559617243737459057312001403031879309116481015410011220367858297629826861622 // in wabt result is 99999999999999998083559617243737459057312001403031879309116481015410011220367858297629826861622
// but the actual (and correct) result is 1e150 // but the actual (and correct) result is 1e150
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::F64(1e150)); assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(1e150));
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::F64(0.000000)); assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(0.000000));
assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::F64(0.000000)); assert_eq!(module.execute_index(5, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(0.000000));
assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::F64(0.000000)); assert_eq!(module.execute_index(6, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(0.000000));
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/cast.txt /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/cast.txt
@ -1399,10 +1401,10 @@ fn cast() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_index(0, vec![]).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![]).unwrap().unwrap(), RuntimeValue::I32(-1067450368)); // 3227516928 assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1067450368)); // 3227516928
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::F64(125.125000)); assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(125.125000));
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I64(4758506566875873280)); assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(4758506566875873280));
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/compare.txt#L3 /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/compare.txt#L3
@ -1665,34 +1667,34 @@ fn compare_i32() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_index(0, vec![]).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![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(5, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(6, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(7, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(7, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(8, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(8, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(9, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(9, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(10, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(10, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(11, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(11, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(12, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(12, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(13, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(13, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(14, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(14, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(15, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(15, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(16, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(16, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(17, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(17, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(18, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(18, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(19, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(19, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(20, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(20, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(21, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(21, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(22, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(22, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(23, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(23, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(24, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(24, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(25, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(25, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(26, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(26, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(27, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(27, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/compare.txt#L123 /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/compare.txt#L123
@ -1955,34 +1957,34 @@ fn compare_i64() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_index(0, vec![]).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![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(5, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(6, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(7, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(7, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(8, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(8, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(9, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(9, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(10, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(10, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(11, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(11, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(12, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(12, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(13, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(13, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(14, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(14, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(15, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(15, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(16, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(16, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(17, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(17, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(18, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(18, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(19, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(19, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(20, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(20, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(21, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(21, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(22, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(22, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(23, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(23, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(24, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(24, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(25, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(25, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(26, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(26, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(27, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(27, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/compare.txt#L246 /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/compare.txt#L246
@ -2139,22 +2141,22 @@ fn compare_f32() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_index(0, vec![]).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![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(5, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(6, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(7, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(7, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(8, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(8, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(9, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(9, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(10, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(10, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(11, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(11, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(12, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(12, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(13, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(13, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(14, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(14, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(15, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(15, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/compare.txt#L317 /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/compare.txt#L317
@ -2311,22 +2313,22 @@ fn compare_f64() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_index(0, vec![]).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![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(5, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(6, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(7, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(7, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(8, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(8, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(9, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(9, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(10, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(10, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(11, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(11, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(12, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(12, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(13, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); assert_eq!(module.execute_index(13, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
assert_eq!(module.execute_index(14, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(14, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(15, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(15, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/convert.txt#L3 /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/convert.txt#L3
@ -2379,11 +2381,11 @@ fn convert_i32() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_index(0, vec![]).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![]).unwrap().unwrap(), RuntimeValue::I32(-100)); // 4294967196 assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-100)); // 4294967196
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(-1294967296)); // 3000000000 assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1294967296)); // 3000000000
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(-100)); // 4294967196 assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-100)); // 4294967196
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I32(-1294967296)); // 3000000000 assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1294967296)); // 3000000000
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/convert.txt#L21 /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/convert.txt#L21
@ -2452,12 +2454,12 @@ fn convert_i64() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_index(0, vec![]).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![]).unwrap().unwrap(), RuntimeValue::I64(-1)); // 18446744073709551615 assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-1)); // 18446744073709551615
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(5, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/convert.txt#L50 /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/convert.txt#L50
@ -2510,11 +2512,11 @@ fn convert_f32() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_index(0, vec![]).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![]).unwrap().unwrap(), RuntimeValue::F32(4294967296.000000)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(4294967296.000000));
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::F32(12345679.000000)); assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(12345679.000000));
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::F32(0.000000)); assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(0.000000));
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::F32(0.000000)); assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(0.000000));
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/convert.txt#L50 /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/convert.txt#L50
@ -2567,11 +2569,11 @@ fn convert_f64() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_index(0, vec![]).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![]).unwrap().unwrap(), RuntimeValue::F64(4294967295.000000)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(4294967295.000000));
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::F64(12345679.000000)); assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(12345679.000000));
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::F64(0.000000)); assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(0.000000));
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::F64(0.000000)); assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(0.000000));
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/load.txt#L9 /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/load.txt#L9
@ -2627,11 +2629,11 @@ fn load_i32() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_index(0, vec![]).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![]).unwrap().unwrap(), RuntimeValue::I32(-1)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1));
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(-1)); assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1));
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(255)); assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(255));
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I32(65535)); assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(65535));
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/load.txt#L26 /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/load.txt#L26
@ -2703,13 +2705,13 @@ fn load_i64() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_index(0, vec![]).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![]).unwrap().unwrap(), RuntimeValue::I64(-1)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-1));
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I64(-1)); assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-1));
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I64(-1)); assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-1));
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I64(255)); assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(255));
assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::I64(65535)); assert_eq!(module.execute_index(5, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(65535));
assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::I64(4294967295)); assert_eq!(module.execute_index(6, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(4294967295));
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/load.txt#L50 /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/load.txt#L50
@ -2733,7 +2735,7 @@ fn load_f32() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::F32(25.750000)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(25.750000));
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/load.txt#L54 /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/load.txt#L54
@ -2757,7 +2759,7 @@ fn load_f64() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::F64(1023.875000)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(1023.875000));
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/store.txt#L5 /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/store.txt#L5
@ -2814,9 +2816,9 @@ fn store_i32() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_index(0, vec![]).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![]).unwrap().unwrap(), RuntimeValue::I32(-859059511)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-859059511));
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(-123456)); assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-123456));
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/store.txt#L38 /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/store.txt#L38
@ -2884,10 +2886,10 @@ fn store_i64() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_index(0, vec![]).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![]).unwrap().unwrap(), RuntimeValue::I64(3435907785)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(3435907785));
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I64(4294843840)); assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(4294843840));
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I64(-4981613551475109875)); assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-4981613551475109875));
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/store.txt#L78 /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/store.txt#L78
@ -2912,7 +2914,7 @@ fn store_f32() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::I32(1069547520)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1069547520));
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/store.txt#L85 /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/store.txt#L85
@ -2937,7 +2939,7 @@ fn store_f64() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::I32(-1064352256)); assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1064352256));
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/unary.txt#L12 /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/unary.txt#L12
@ -2988,11 +2990,11 @@ fn unary_i32() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_index(0, vec![]).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![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(24)); assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(24));
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(7)); assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(7));
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/unary.txt#L29 /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/unary.txt#L29
@ -3043,11 +3045,11 @@ fn unary_i64() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_index(0, vec![]).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![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I64(56)); assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(56));
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I64(7)); assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(7));
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I64(1)); assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(1));
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/unary.txt#L46 /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/unary.txt#L46
@ -3142,15 +3144,15 @@ fn unary_f32() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_index(1, vec![]).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![]).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(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::F32(10.000000)); assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(10.000000));
assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::F32(-0.000000)); assert_eq!(module.execute_index(5, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(-0.000000));
assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::F32(-1.000000)); assert_eq!(module.execute_index(6, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(-1.000000));
assert_eq!(module.execute_index(7, vec![]).unwrap().unwrap(), RuntimeValue::F32(-0.000000)); assert_eq!(module.execute_index(7, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(-0.000000));
assert_eq!(module.execute_index(8, vec![]).unwrap().unwrap(), RuntimeValue::F32(1.000000)); assert_eq!(module.execute_index(8, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(1.000000));
assert_eq!(module.execute_index(9, vec![]).unwrap().unwrap(), RuntimeValue::F32(2.000000)); assert_eq!(module.execute_index(9, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(2.000000));
} }
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/unary.txt#L76 /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/unary.txt#L76
@ -3245,13 +3247,13 @@ fn unary_f64() {
let program = ProgramInstance::new().unwrap(); let program = ProgramInstance::new().unwrap();
let module = program.add_module("main", module).unwrap(); let module = program.add_module("main", module).unwrap();
assert_eq!(module.execute_index(1, vec![]).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![]).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(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::F64(10.000000)); assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(10.000000));
assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::F64(-0.000000)); assert_eq!(module.execute_index(5, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(-0.000000));
assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::F64(-1.000000)); assert_eq!(module.execute_index(6, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(-1.000000));
assert_eq!(module.execute_index(7, vec![]).unwrap().unwrap(), RuntimeValue::F64(-0.000000)); assert_eq!(module.execute_index(7, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(-0.000000));
assert_eq!(module.execute_index(8, vec![]).unwrap().unwrap(), RuntimeValue::F64(1.000000)); assert_eq!(module.execute_index(8, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(1.000000));
assert_eq!(module.execute_index(9, vec![]).unwrap().unwrap(), RuntimeValue::F64(2.000000)); assert_eq!(module.execute_index(9, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(2.000000));
} }