diff --git a/examples/interpret.rs b/examples/interpret.rs index 7111f36..f43648d 100644 --- a/examples/interpret.rs +++ b/examples/interpret.rs @@ -16,5 +16,5 @@ fn main() { 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 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())); } diff --git a/src/interpreter/env.rs b/src/interpreter/env.rs index 861b06e..9535445 100644 --- a/src/interpreter/env.rs +++ b/src/interpreter/env.rs @@ -1,11 +1,12 @@ 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, ValueType, InitExpr, Opcode, Opcodes}; 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::table::TableInstance; use interpreter::value::{RuntimeValue, TransmuteInto}; @@ -58,44 +59,10 @@ const INDEX_FUNC_ASSERT: u32 = 1; const INDEX_FUNC_ENLARGE_MEMORY: u32 = 2; /// Index of getTotalMemory function. 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. -const INDEX_FUNC_MIN_NONUSED: u32 = 7; +const INDEX_FUNC_MIN_NONUSED: u32 = 4; /// Max index of reserved function. -const INDEX_FUNC_MAX: u32 = 10000; - -/// Set of user-defined functions -pub type UserFunctions = HashMap; - -/// User function closure -pub type UserFunctionClosure = Box; - -/// User-defined function execution interface -pub trait UserFunctionInterface { - /// Handles the user function invocation - fn call(&mut self, module: &ModuleInstance, context: CallerContext) -> Result, Error>; -} - -impl UserFunctionInterface for T where T: FnMut(&ModuleInstance, CallerContext) -> Result, Error> { - fn call(&mut self, module: &ModuleInstance, context: CallerContext) -> Result, Error> { - (&mut *self)(module, context) - } -} - -/// Signature of user-defined env function -pub struct UserFunction { - /// User function parameters (for signature matching) - pub params: Vec, - /// User function return type (for signature matching) - pub result: Option, - /// Executor of the function - pub closure: UserFunctionClosure, -} +const INDEX_FUNC_MAX: u32 = NATIVE_INDEX_FUNC_MIN - 1; /// Environment parameters. pub struct EnvParams { @@ -107,41 +74,37 @@ pub struct EnvParams { pub allow_memory_growth: bool, } -type UserFunctionsInternals = Vec<::std::cell::RefCell>; - pub struct EnvModuleInstance { _params: EnvParams, - user_functions: UserFunctionsInternals, instance: ModuleInstance, } impl EnvModuleInstance { - pub fn new(params: EnvParams, user_functions: UserFunctionsInternals, module: Module) -> Result { + pub fn new(params: EnvParams, module: Module) -> Result { let instance = ModuleInstance::new(Weak::default(), module)?; Ok(EnvModuleInstance { _params: params, - user_functions: user_functions, instance: instance, }) } } impl ModuleInstanceInterface for EnvModuleInstance { - fn execute_main(&self, args: Vec) -> Result, Error> { - self.instance.execute_main(args) + fn execute_main(&self, params: ExecutionParams) -> Result, Error> { + self.instance.execute_main(params) } - fn execute_index(&self, index: u32, args: Vec) -> Result, Error> { - self.instance.execute_index(index, args) + fn execute_index(&self, index: u32, params: ExecutionParams) -> Result, Error> { + self.instance.execute_index(index, params) } - fn execute_export(&self, name: &str, args: Vec) -> Result, Error> { - self.instance.execute_export(name, args) + fn execute_export(&self, name: &str, params: ExecutionParams) -> Result, Error> { + self.instance.execute_export(name, params) } - fn module(&self) -> &Module { - self.instance.module() + fn export_entry(&self, name: &str) -> Result { + self.instance.export_entry(name) } fn table(&self, index: ItemIndex) -> Result, Error> { @@ -165,6 +128,7 @@ impl ModuleInstanceInterface for EnvModuleInstance { } fn call_internal_function(&self, outer: CallerContext, index: u32, _function_type: Option<&FunctionType>) -> Result, Error> { + // TODO: check function type // to make interpreter independent of *SCRIPTEN runtime, just make abort/assert = interpreter Error match index { INDEX_FUNC_ABORT => self.global(ItemIndex::IndexSpace(INDEX_GLOBAL_ABORT)) @@ -183,26 +147,17 @@ impl ModuleInstanceInterface for EnvModuleInstance { .map(|g| g.get()) .map(Some), 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))), } } } -pub fn env_module(user_functions: UserFunctions) -> Result { +pub fn env_module() -> Result { let env_params = EnvParams::default(); 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_memory % LINEAR_MEMORY_PAGE_SIZE) == 0); - let mut builder = module() + let builder = module() // memory regions .memory() .with_min(env_params.total_memory / LINEAR_MEMORY_PAGE_SIZE) @@ -255,29 +210,7 @@ pub fn env_module(user_functions: UserFunctions) -> Result = &'a mut FnMut(context: CallerContext) -> Result, Error>; + +/// User functions executor. +pub trait UserFunctionExecutor { + /// Execute function with given name. + fn execute(&mut self, name: &str, context: CallerContext) -> Result, Error>; +} + +/// User function type. +pub struct UserFunction { + /// User function name. + pub name: String, + /// User function parameters (for signature matching). + pub params: Vec, + /// User function return type (for signature matching). + pub result: Option, +} + +/// Set of user-defined functions +pub struct UserFunctions<'a> { + /// Functions list. + pub functions: Vec, + /// Functions executor. + pub executor: &'a mut UserFunctionExecutor, +} + +/// Native module instance. +pub struct NativeModuleInstance<'a> { + /// Underllying module reference. + env: Arc, + /// User function executor. + executor: RwLock<&'a mut UserFunctionExecutor>, + /// By-name functions index. + by_name: HashMap, + /// User functions list. + functions: Vec, +} + +impl<'a> NativeModuleInstance<'a> { + /// Create new native module + pub fn new(env: Arc, functions: UserFunctions<'a>) -> Result { + 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, Error> { + self.env.execute_main(params) + } + + fn execute_index(&self, index: u32, params: ExecutionParams) -> Result, Error> { + self.env.execute_index(index, params) + } + + fn execute_export(&self, name: &str, params: ExecutionParams) -> Result, Error> { + self.env.execute_export(name, params) + } + + fn export_entry(&self, name: &str) -> Result { + 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, Error> { + self.env.table(index) + } + + fn memory(&self, index: ItemIndex) -> Result, Error> { + self.env.memory(index) + } + + fn global(&self, index: ItemIndex) -> Result, Error> { + self.env.global(index) + } + + fn call_function(&self, outer: CallerContext, index: ItemIndex) -> Result, Error> { + self.env.call_function(outer, index) + } + + fn call_function_indirect(&self, outer: CallerContext, table_index: ItemIndex, type_index: u32, func_index: u32) -> Result, 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, 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, user_functions: UserFunctions) -> Result { + NativeModuleInstance::new(env, user_functions) +} diff --git a/src/interpreter/imports.rs b/src/interpreter/imports.rs index 9cf8574..6588a6b 100644 --- a/src/interpreter/imports.rs +++ b/src/interpreter/imports.rs @@ -1,4 +1,5 @@ use std::sync::{Arc, Weak}; +use std::collections::HashMap; use elements::{ImportSection, ImportEntry, External, Internal}; use interpreter::Error; use interpreter::memory::MemoryInstance; @@ -94,7 +95,13 @@ impl ModuleImports { } /// Get module reference. - pub fn module(&self, name: &str) -> Result, Error> { + pub fn module<'a>(&self, externals: Option<&'a HashMap>>, name: &str) -> Result, Error> { + if let Some(externals) = externals { + if let Some(module) = externals.get(name).cloned() { + return Ok(module); + } + } + self.program .upgrade() .ok_or(Error::Program("program unloaded".into())) @@ -102,8 +109,8 @@ impl ModuleImports { } /// Get function index. - pub fn function(&self, import: &ImportEntry) -> Result { - let (_, export) = self.external_export(import)?; + pub fn function<'a>(&self, externals: Option<&'a HashMap>>, import: &ImportEntry) -> Result { + let (_, export) = self.external_export(externals, import)?; if let Internal::Function(external_index) = export { return Ok(external_index); } @@ -112,8 +119,8 @@ impl ModuleImports { } /// Get table reference. - pub fn table(&self, import: &ImportEntry) -> Result, Error> { - let (module, export) = self.external_export(import)?; + pub fn table<'a>(&self, externals: Option<&'a HashMap>>, import: &ImportEntry) -> Result, Error> { + let (module, export) = self.external_export(externals, import)?; if let Internal::Table(external_index) = export { return module.table(ItemIndex::Internal(external_index)); } @@ -122,8 +129,8 @@ impl ModuleImports { } /// Get memory reference. - pub fn memory(&self, import: &ImportEntry) -> Result, Error> { - let (module, export) = self.external_export(import)?; + pub fn memory<'a>(&self, externals: Option<&'a HashMap>>, import: &ImportEntry) -> Result, Error> { + let (module, export) = self.external_export(externals, import)?; if let Internal::Memory(external_index) = export { return module.memory(ItemIndex::Internal(external_index)); } @@ -132,8 +139,8 @@ impl ModuleImports { } /// Get global reference. - pub fn global(&self, import: &ImportEntry) -> Result, Error> { - let (module, export) = self.external_export(import)?; + pub fn global<'a>(&self, externals: Option<&'a HashMap>>, import: &ImportEntry) -> Result, Error> { + let (module, export) = self.external_export(externals, import)?; if let Internal::Global(external_index) = export { 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()))) } - fn external_export(&self, import: &ImportEntry) -> Result<(Arc, Internal), Error> { - self.module(import.module()) - .and_then(|m| m.module().export_section() - .ok_or(Error::Program(format!("trying to import from module {} without export section", import.module()))) - .and_then(|s| s.entries().iter() - .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)))) + fn external_export<'a>(&self, externals: Option<&'a HashMap>>, import: &ImportEntry) -> Result<(Arc, Internal), Error> { + self.module(externals, import.module()) + .and_then(|m| + m.export_entry(import.field()) + .map(|e| (m, e))) } } diff --git a/src/interpreter/mod.rs b/src/interpreter/mod.rs index 3d8fcc0..d436a3e 100644 --- a/src/interpreter/mod.rs +++ b/src/interpreter/mod.rs @@ -27,6 +27,8 @@ pub enum Error { Interpreter(String), /// Env module error. Env(String), + /// Native module error. + Native(String), /// Trap. Trap(String), } @@ -46,12 +48,14 @@ impl Into for Error { Error::Interpreter(s) => s, Error::Value(s) => s, Error::Env(s) => s, + Error::Native(s) => s, Error::Trap(s) => format!("trap: {}", s), } } } mod env; +mod env_native; mod imports; mod memory; mod module; @@ -65,7 +69,10 @@ mod variable; #[cfg(test)] 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::value::RuntimeValue; -pub use self::env::{UserFunctions, UserFunction, UserFunctionInterface}; \ No newline at end of file +pub use self::variable::VariableInstance; +pub use self::env_native::{env_native_module, UserFunctions, UserFunction, UserFunctionExecutor}; diff --git a/src/interpreter/module.rs b/src/interpreter/module.rs index b195eaf..7e987be 100644 --- a/src/interpreter/module.rs +++ b/src/interpreter/module.rs @@ -1,3 +1,4 @@ +use std::collections::HashMap; use std::iter::repeat; use std::sync::{Arc, Weak}; 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::variable::{VariableInstance, VariableType}; +#[derive(Default, Clone)] +/// Execution context. +pub struct ExecutionParams<'a> { + /// Arguments. + pub args: Vec, + /// Execution-local external modules. + pub externals: HashMap>, +} + /// Module instance API. pub trait ModuleInstanceInterface { /// Execute start function of the module. - fn execute_main(&self, args: Vec) -> Result, Error>; + fn execute_main(&self, params: ExecutionParams) -> Result, Error>; /// Execute function with the given index. - fn execute_index(&self, index: u32, args: Vec) -> Result, Error>; + fn execute_index(&self, index: u32, params: ExecutionParams) -> Result, Error>; /// Execute function with the given export name. - fn execute_export(&self, name: &str, args: Vec) -> Result, Error>; - /// Get module description reference. - fn module(&self) -> &Module; + fn execute_export(&self, name: &str, params: ExecutionParams) -> Result, Error>; + /// Get export entry. + fn export_entry(&self, name: &str) -> Result; /// Get table reference. fn table(&self, index: ItemIndex) -> Result, Error>; /// Get memory reference. @@ -42,7 +52,7 @@ pub enum ItemIndex { IndexSpace(u32), /// Internal item index (i.e. index of item in items section). 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), } @@ -68,6 +78,35 @@ pub struct CallerContext<'a> { pub frame_stack_limit: usize, /// Stack of the input parameters pub value_stack: &'a mut StackWithLimit, + /// Execution-local external modules. + pub externals: &'a HashMap>, +} + +impl<'a> ExecutionParams<'a> { + /// Create new execution params with given externa; module override. + pub fn with_external(name: String, module: Arc) -> 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> for ExecutionParams<'a> { + fn from(args: Vec) -> ExecutionParams<'a> { + ExecutionParams { + args: args, + externals: HashMap::new(), + } + } } impl ModuleInstance { @@ -149,19 +188,19 @@ impl ModuleInstance { } impl ModuleInstanceInterface for ModuleInstance { - fn execute_main(&self, args: Vec) -> Result, Error> { + fn execute_main(&self, params: ExecutionParams) -> Result, Error> { 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) -> Result, Error> { - let args_len = args.len(); - let mut args = StackWithLimit::with_data(args, args_len); - let caller_context = CallerContext::topmost(&mut args); + fn execute_index(&self, index: u32, params: ExecutionParams) -> Result, Error> { + let args_len = params.args.len(); + let mut args = StackWithLimit::with_data(params.args, args_len); + let caller_context = CallerContext::topmost(&mut args, ¶ms.externals); self.call_function(caller_context, ItemIndex::IndexSpace(index)) } - fn execute_export(&self, name: &str, args: Vec) -> Result, Error> { + fn execute_export(&self, name: &str, params: ExecutionParams) -> Result, Error> { let index = self.module.export_section() .ok_or(Error::Function("missing export section".into())) .and_then(|s| s.entries().iter() @@ -175,11 +214,16 @@ impl ModuleInstanceInterface for ModuleInstance { _ => unreachable!(), // checked couple of lines above }) )?; - self.execute_index(index, args) + self.execute_index(index, params) } - fn module(&self) -> &Module { - &self.module + fn export_entry(&self, name: &str) -> Result { + 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, 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))) .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())))) - .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))) .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())))) - .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))) .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())))) - .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))) .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())))) - .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)), } } @@ -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))) .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())))) - .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)) } } } - fn call_internal_function(&self, outer: CallerContext, index: u32, function_type: Option<&FunctionType>) -> Result, Error> { + fn call_internal_function(&self, mut outer: CallerContext, index: u32, function_type: Option<&FunctionType>) -> Result, Error> { // TODO: cache // internal index = index of function in functions section && index of code in code section // get function type index @@ -311,19 +355,20 @@ impl ModuleInstanceInterface for ModuleInstance { let function_code = function_body.code().elements(); let value_stack_limit = outer.value_stack_limit; let frame_stack_limit = outer.frame_stack_limit; - let locals = prepare_function_locals(actual_function_type, function_body, outer)?; - let mut innner = FunctionContext::new(self, value_stack_limit, frame_stack_limit, actual_function_type, function_code, locals)?; + let locals = prepare_function_locals(actual_function_type, function_body, &mut outer)?; + 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) } } impl<'a> CallerContext<'a> { /// Top most args - pub fn topmost(args: &'a mut StackWithLimit) -> Self { + pub fn topmost(args: &'a mut StackWithLimit, externals: &'a HashMap>) -> Self { CallerContext { value_stack_limit: 1024, frame_stack_limit: 1024, value_stack: args, + externals: externals, } } @@ -332,12 +377,13 @@ impl<'a> CallerContext<'a> { CallerContext { value_stack_limit: outer.value_stack().limit() - outer.value_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, Error> { +fn prepare_function_locals(function_type: &FunctionType, function_body: &FuncBody, outer: &mut CallerContext) -> Result, Error> { // locals = function arguments + defined locals function_type.params().iter().rev() .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))) .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())))) - .and_then(|e| imports.global(e)) + .and_then(|e| imports.global(None, e)) .map(|g| g.get()) }, &Opcode::I32Const(val) => Ok(RuntimeValue::I32(val)), diff --git a/src/interpreter/program.rs b/src/interpreter/program.rs index 58bd524..41141f8 100644 --- a/src/interpreter/program.rs +++ b/src/interpreter/program.rs @@ -1,10 +1,9 @@ use std::sync::Arc; use std::collections::HashMap; -use std::collections::hash_map::Entry; use parking_lot::RwLock; use elements::Module; use interpreter::Error; -use interpreter::env::{self, env_module}; +use interpreter::env::env_module; use interpreter::module::{ModuleInstance, ModuleInstanceInterface}; /// 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 { - Ok(ProgramInstance { - essence: Arc::new(ProgramInstanceEssence::with_functions(funcs)?), - }) - } - /// Instantiate module. pub fn add_module(&self, name: &str, module: Module) -> Result, Error> { let module_instance = Arc::new(ModuleInstance::new(Arc::downgrade(&self.essence), module)?); - let mut modules = self.essence.modules.write(); - match modules.entry(name.into()) { - Entry::Occupied(_) => Err(Error::Program(format!("module {} already instantiated", name))), - Entry::Vacant(entry) => { - entry.insert(module_instance.clone()); - Ok(module_instance) - }, - } + // replace existing module with the same name with new one + self.essence.modules.write().insert(name.into(), module_instance.clone()); + Ok(module_instance) } /// Get one of the modules by name @@ -56,13 +43,8 @@ impl ProgramInstance { impl ProgramInstanceEssence { /// Create new program essence. pub fn new() -> Result { - ProgramInstanceEssence::with_functions(HashMap::with_capacity(0)) - } - - /// Create new program essence with provided user-defined functions - pub fn with_functions(funcs: env::UserFunctions) -> Result { let mut modules = HashMap::new(); - let env_module: Arc = Arc::new(env_module(funcs)?); + let env_module: Arc = Arc::new(env_module()?); modules.insert("env".into(), env_module); Ok(ProgramInstanceEssence { modules: RwLock::new(modules), diff --git a/src/interpreter/runner.rs b/src/interpreter/runner.rs index 5069895..e25a17b 100644 --- a/src/interpreter/runner.rs +++ b/src/interpreter/runner.rs @@ -1,7 +1,9 @@ use std::mem; use std::ops; use std::u32; +use std::sync::Arc; use std::fmt::Display; +use std::collections::HashMap; use elements::{Opcode, BlockType, FunctionType}; use interpreter::Error; use interpreter::module::{ModuleInstance, ModuleInstanceInterface, CallerContext, ItemIndex}; @@ -18,17 +20,19 @@ pub struct Interpreter; /// Function execution context. pub struct FunctionContext<'a> { /// Module instance. - module: &'a ModuleInstance, + pub module: &'a ModuleInstance, + /// Execution-local external modules. + pub externals: &'a HashMap>, /// Function return type. - return_type: BlockType, + pub return_type: BlockType, /// Local variables. - locals: Vec, + pub locals: Vec, /// Values stack. - value_stack: StackWithLimit, + pub value_stack: StackWithLimit, /// Blocks frames stack. - frame_stack: StackWithLimit, + pub frame_stack: StackWithLimit, /// Current instruction position. - position: usize, + pub position: usize, } #[derive(Debug, Clone)] @@ -868,9 +872,10 @@ impl Interpreter { } impl<'a> FunctionContext<'a> { - pub fn new(module: &'a ModuleInstance, value_stack_limit: usize, frame_stack_limit: usize, function: &FunctionType, body: &[Opcode], args: Vec) -> Result { + pub fn new(module: &'a ModuleInstance, externals: &'a HashMap>, value_stack_limit: usize, frame_stack_limit: usize, function: &FunctionType, body: &[Opcode], args: Vec) -> Result { let mut context = FunctionContext { module: module, + externals: externals, return_type: function.return_type().map(|vt| BlockType::Value(vt)).unwrap_or(BlockType::NoResult), value_stack: StackWithLimit::with_limit(value_stack_limit), frame_stack: StackWithLimit::with_limit(frame_stack_limit), @@ -888,6 +893,10 @@ impl<'a> FunctionContext<'a> { self.module } + pub fn externals(&self) -> &HashMap> { + &self.externals + } + pub fn call_function(&mut self, index: u32) -> Result, Error> { self.module.call_function(CallerContext::nested(self), ItemIndex::IndexSpace(index)) } diff --git a/src/interpreter/tests/basics.rs b/src/interpreter/tests/basics.rs index f9d8e9a..fee1201 100644 --- a/src/interpreter/tests/basics.rs +++ b/src/interpreter/tests/basics.rs @@ -1,10 +1,13 @@ ///! Basic tests for instructions/constructions, missing in wabt tests +use std::sync::Arc; use builder::module; use elements::{ExportEntry, Internal, ImportEntry, External, GlobalEntry, GlobalType, InitExpr, ValueType, Opcodes, Opcode}; 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::value::RuntimeValue; @@ -38,8 +41,8 @@ fn import_function() { let external_module = program.add_module("external_module", module1).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!(main_module.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(10)); + assert_eq!(external_module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(3)); + assert_eq!(main_module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(10)); } #[test] @@ -72,7 +75,7 @@ fn wrong_import() { let _side_module_instance = program.add_module("side_module", side_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] @@ -115,112 +118,102 @@ fn global_get_set() { let program = ProgramInstance::new().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(1, vec![]).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(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(50)); + 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![].into()).unwrap_err(), Error::Variable("trying to update variable of type I32 with value of type Some(I64)".into())); } #[test] -fn with_user_functions() { - use interpreter::{UserFunction, UserFunctions, ModuleInstance}; +fn single_program_different_modules() { + // user function executor + struct FunctionExecutor { + pub memory: Arc, + pub values: Vec, + } + + impl UserFunctionExecutor for FunctionExecutor { + fn execute(&mut self, name: &str, context: CallerContext) -> Result, Error> { + match name { + "add" => { + let memory_value = self.memory.get(0, 1).unwrap()[0]; + let fn_argument = context.value_stack.pop_as::().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::().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() - .with_import(ImportEntry::new("env".into(), "custom_alloc".into(), External::Function(0))) - .with_import(ImportEntry::new("env".into(), "custom_increment".into(), External::Function(0))) + .with_import(ImportEntry::new("env".into(), "add".into(), External::Function(0))) + .with_import(ImportEntry::new("env".into(), "sub".into(), External::Function(0))) .function() - .signature().return_type().i32().build() + .signature().param().i32().return_type().i32().build() .body().with_opcodes(Opcodes::new(vec![ - Opcode::I32Const(32), + Opcode::GetLocal(0), Opcode::Call(0), Opcode::End, ])).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(); - let mut top = 0i32; - let mut user_functions = UserFunctions::new(); - 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::()?; - Ok(Some(prev.into())) - }), - } - ); + // load module + let module_instance = program.add_module("main", module).unwrap(); - let mut rolling = 9999i32; - user_functions.insert( - "custom_increment".to_owned(), - UserFunction { - params: vec![ValueType::I32], - result: Some(ValueType::I32), - closure: Box::new(move |_module: &ModuleInstance, _context: CallerContext| { - rolling = rolling + 1; - Ok(Some(rolling.into())) - }), - } - ); + let mut executor = FunctionExecutor { + memory: env_memory.clone(), + values: Vec::new(), + }; + { + // create native env module with native add && sub implementations + let functions: UserFunctions = UserFunctions { + executor: &mut executor, + 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(); - let module_instance = program.add_module("main", module).unwrap(); + // execute functions + let params = ExecutionParams::with_external("env".into(), native_env_instance); - // internal function using first import - assert_eq!(module_instance.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module_instance.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(32)); - assert_eq!(module_instance.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(64)); - - // second import - assert_eq!(module_instance.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(10000)); - assert_eq!(module_instance.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(10001)); + 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, params.clone().add_argument(RuntimeValue::I32(50))).unwrap().unwrap(), RuntimeValue::I32(57)); + assert_eq!(module_instance.execute_index(3, params.clone().add_argument(RuntimeValue::I32(15))).unwrap().unwrap(), RuntimeValue::I32(42)); + } + + assert_eq!(executor.memory.get(0, 1).unwrap()[0], 42); + assert_eq!(executor.values, vec![7, 57, 42]); } - -#[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, Error> { - let prev = self.top; - self.top += context.value_stack.pop_as::()?; - 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)); -} \ No newline at end of file diff --git a/src/interpreter/tests/wabt.rs b/src/interpreter/tests/wabt.rs index d069392..a0bfda2 100644 --- a/src/interpreter/tests/wabt.rs +++ b/src/interpreter/tests/wabt.rs @@ -1,6 +1,7 @@ ///! Tests from https://github.com/WebAssembly/wabt/tree/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp use std::sync::Weak; +use std::collections::HashMap; use builder::module; use elements::{Module, ValueType, Opcodes, Opcode, BlockType, FunctionType}; use interpreter::Error; @@ -13,7 +14,8 @@ use interpreter::variable::{VariableInstance, VariableType}; fn run_function_i32(body: &Opcodes, arg: i32) -> Result { let ftype = FunctionType::new(vec![ValueType::I32], Some(ValueType::I32)); 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(0)).unwrap(), // local1 VariableInstance::new(true, VariableType::I32, RuntimeValue::I32(0)).unwrap(), // local2 @@ -522,11 +524,11 @@ fn return_void() { let program = ProgramInstance::new().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(); 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(); 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 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 @@ -629,7 +631,7 @@ fn call_2() { let program = ProgramInstance::new().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 @@ -674,7 +676,7 @@ fn call_zero_args() { let program = ProgramInstance::new().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 @@ -720,8 +722,8 @@ fn callindirect_1() { let program = ProgramInstance::new().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(1)]).unwrap().unwrap(), RuntimeValue::I32(1)); + assert_eq!(module.execute_main(vec![RuntimeValue::I32(0)].into()).unwrap().unwrap(), RuntimeValue::I32(0)); + 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 @@ -793,11 +795,11 @@ fn callindirect_2() { let program = ProgramInstance::new().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(1)]).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(0)].into()).unwrap().unwrap(), RuntimeValue::I32(14)); + 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)].into()).unwrap_err(), 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())); } @@ -861,14 +863,14 @@ fn select() { let program = ProgramInstance::new().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(1)]).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(1)]).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(1)]).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(1)]).unwrap().unwrap(), RuntimeValue::F64(1f64)); + assert_eq!(module.execute_index(0, vec![RuntimeValue::I32(0)].into()).unwrap().unwrap(), RuntimeValue::I32(2)); + assert_eq!(module.execute_index(0, vec![RuntimeValue::I32(1)].into()).unwrap().unwrap(), RuntimeValue::I32(1)); + assert_eq!(module.execute_index(1, vec![RuntimeValue::I32(0)].into()).unwrap().unwrap(), RuntimeValue::I64(2)); + 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)].into()).unwrap().unwrap(), RuntimeValue::F32(2f32)); + 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)].into()).unwrap().unwrap(), RuntimeValue::F64(2f64)); + 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 @@ -1014,21 +1016,21 @@ fn binary_i32() { let program = ProgramInstance::new().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(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(16)); - assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(21)); - assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(-2)); // 4294967294 - assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I32(2147483646)); - assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::I32(-1)); // 4294967295 - assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(7, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(8, vec![]).unwrap().unwrap(), RuntimeValue::I32(15)); - assert_eq!(module.execute_index(9, vec![]).unwrap().unwrap(), RuntimeValue::I32(14)); - assert_eq!(module.execute_index(10, vec![]).unwrap().unwrap(), RuntimeValue::I32(-800)); // 4294966496 - assert_eq!(module.execute_index(11, vec![]).unwrap().unwrap(), RuntimeValue::I32(536870899)); - assert_eq!(module.execute_index(12, vec![]).unwrap().unwrap(), RuntimeValue::I32(-13)); // 4294967283 - assert_eq!(module.execute_index(13, vec![]).unwrap().unwrap(), RuntimeValue::I32(-793)); // 4294966503 - assert_eq!(module.execute_index(14, vec![]).unwrap().unwrap(), RuntimeValue::I32(-1610612749)); // 2684354547 + assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(3)); + assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(16)); + assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(21)); + assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-2)); // 4294967294 + assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(2147483646)); + assert_eq!(module.execute_index(5, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1)); // 4294967295 + assert_eq!(module.execute_index(6, vec![].into()).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![].into()).unwrap().unwrap(), RuntimeValue::I32(15)); + assert_eq!(module.execute_index(9, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(14)); + assert_eq!(module.execute_index(10, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-800)); // 4294966496 + assert_eq!(module.execute_index(11, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(536870899)); + assert_eq!(module.execute_index(12, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-13)); // 4294967283 + assert_eq!(module.execute_index(13, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-793)); // 4294966503 + 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 @@ -1174,21 +1176,21 @@ fn binary_i64() { let program = ProgramInstance::new().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(1, vec![]).unwrap().unwrap(), RuntimeValue::I64(16)); - assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I64(21)); - assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I64(-2)); // 18446744073709551614 - assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I64(9223372036854775806)); - assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::I64(-1)); // 18446744073709551615 - assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::I64(1)); - assert_eq!(module.execute_index(7, vec![]).unwrap().unwrap(), RuntimeValue::I64(1)); - assert_eq!(module.execute_index(8, vec![]).unwrap().unwrap(), RuntimeValue::I64(15)); - assert_eq!(module.execute_index(9, vec![]).unwrap().unwrap(), RuntimeValue::I64(14)); - assert_eq!(module.execute_index(10, vec![]).unwrap().unwrap(), RuntimeValue::I64(-800)); // 18446744073709550816 - assert_eq!(module.execute_index(11, vec![]).unwrap().unwrap(), RuntimeValue::I64(2305843009213693939)); - assert_eq!(module.execute_index(12, vec![]).unwrap().unwrap(), RuntimeValue::I64(-13)); // 18446744073709551603 - assert_eq!(module.execute_index(13, vec![]).unwrap().unwrap(), RuntimeValue::I64(-793)); // 18446744073709550823 - assert_eq!(module.execute_index(14, vec![]).unwrap().unwrap(), RuntimeValue::I64(-6917529027641081869)); // 11529215046068469747 + assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(3)); + assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(16)); + assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(21)); + assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-2)); // 18446744073709551614 + assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(9223372036854775806)); + assert_eq!(module.execute_index(5, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-1)); // 18446744073709551615 + assert_eq!(module.execute_index(6, vec![].into()).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![].into()).unwrap().unwrap(), RuntimeValue::I64(15)); + assert_eq!(module.execute_index(9, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(14)); + assert_eq!(module.execute_index(10, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-800)); // 18446744073709550816 + assert_eq!(module.execute_index(11, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(2305843009213693939)); + assert_eq!(module.execute_index(12, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-13)); // 18446744073709551603 + assert_eq!(module.execute_index(13, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-793)); // 18446744073709550823 + 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 @@ -1264,13 +1266,13 @@ fn binary_f32() { let program = ProgramInstance::new().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(1, vec![]).unwrap().unwrap(), RuntimeValue::F32(-9995.500000)); - assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::F32(-8487.187500)); - assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::F32(-500000000.000000)); - assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::F32(0.000000)); - assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::F32(0.000000)); - assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::F32(0.000000)); + assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(5.000000)); + assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(-9995.500000)); + assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(-8487.187500)); + assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(-500000000.000000)); + assert_eq!(module.execute_index(4, vec![].into()).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![].into()).unwrap().unwrap(), RuntimeValue::F32(0.000000)); } /// 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 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(1, vec![]).unwrap().unwrap(), RuntimeValue::F64(123400000000000007812762268812638756607430593436581896388608.000000)); - assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::F64(-15179717820000.000000)); + assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(1111111110.000000)); + assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(123400000000000007812762268812638756607430593436581896388608.000000)); + assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(-15179717820000.000000)); // in wabt result is 99999999999999998083559617243737459057312001403031879309116481015410011220367858297629826861622 // 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(4, vec![]).unwrap().unwrap(), RuntimeValue::F64(0.000000)); - assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::F64(0.000000)); - assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::F64(0.000000)); + assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(1e150)); + assert_eq!(module.execute_index(4, vec![].into()).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![].into()).unwrap().unwrap(), RuntimeValue::F64(0.000000)); } /// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/cast.txt @@ -1399,10 +1401,10 @@ fn cast() { let program = ProgramInstance::new().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(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(-1067450368)); // 3227516928 - assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::F64(125.125000)); - assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I64(4758506566875873280)); + assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(4.5)); + assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1067450368)); // 3227516928 + assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(125.125000)); + 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 @@ -1665,34 +1667,34 @@ fn compare_i32() { let program = ProgramInstance::new().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(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(7, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(8, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(9, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(10, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(11, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(12, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(13, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(14, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(15, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(16, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(17, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(18, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(19, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(20, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(21, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(22, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(23, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(24, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(25, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(26, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(27, 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![].into()).unwrap().unwrap(), RuntimeValue::I32(0)); + assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1)); + assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0)); + assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1)); + assert_eq!(module.execute_index(5, vec![].into()).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![].into()).unwrap().unwrap(), RuntimeValue::I32(1)); + assert_eq!(module.execute_index(8, vec![].into()).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![].into()).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![].into()).unwrap().unwrap(), RuntimeValue::I32(0)); + assert_eq!(module.execute_index(13, vec![].into()).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![].into()).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![].into()).unwrap().unwrap(), RuntimeValue::I32(0)); + assert_eq!(module.execute_index(18, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1)); + assert_eq!(module.execute_index(19, vec![].into()).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![].into()).unwrap().unwrap(), RuntimeValue::I32(1)); + assert_eq!(module.execute_index(22, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0)); + assert_eq!(module.execute_index(23, vec![].into()).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![].into()).unwrap().unwrap(), RuntimeValue::I32(0)); + assert_eq!(module.execute_index(26, vec![].into()).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 @@ -1955,34 +1957,34 @@ fn compare_i64() { let program = ProgramInstance::new().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(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(7, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(8, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(9, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(10, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(11, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(12, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(13, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(14, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(15, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(16, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(17, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(18, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(19, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(20, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(21, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(22, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(23, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(24, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(25, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(26, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(27, 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![].into()).unwrap().unwrap(), RuntimeValue::I32(0)); + assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1)); + assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0)); + assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1)); + assert_eq!(module.execute_index(5, vec![].into()).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![].into()).unwrap().unwrap(), RuntimeValue::I32(1)); + assert_eq!(module.execute_index(8, vec![].into()).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![].into()).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![].into()).unwrap().unwrap(), RuntimeValue::I32(0)); + assert_eq!(module.execute_index(13, vec![].into()).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![].into()).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![].into()).unwrap().unwrap(), RuntimeValue::I32(0)); + assert_eq!(module.execute_index(18, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1)); + assert_eq!(module.execute_index(19, vec![].into()).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![].into()).unwrap().unwrap(), RuntimeValue::I32(1)); + assert_eq!(module.execute_index(22, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0)); + assert_eq!(module.execute_index(23, vec![].into()).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![].into()).unwrap().unwrap(), RuntimeValue::I32(0)); + assert_eq!(module.execute_index(26, vec![].into()).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 @@ -2139,22 +2141,22 @@ fn compare_f32() { let program = ProgramInstance::new().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(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(7, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(8, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(9, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(10, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(11, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(12, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(13, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(14, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(15, 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![].into()).unwrap().unwrap(), RuntimeValue::I32(0)); + assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1)); + assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0)); + assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1)); + assert_eq!(module.execute_index(5, vec![].into()).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![].into()).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![].into()).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![].into()).unwrap().unwrap(), RuntimeValue::I32(0)); + assert_eq!(module.execute_index(12, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1)); + assert_eq!(module.execute_index(13, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0)); + assert_eq!(module.execute_index(14, vec![].into()).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 @@ -2311,22 +2313,22 @@ fn compare_f64() { let program = ProgramInstance::new().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(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(7, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(8, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(9, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(10, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(11, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(12, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(13, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); - assert_eq!(module.execute_index(14, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(15, 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![].into()).unwrap().unwrap(), RuntimeValue::I32(0)); + assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1)); + assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0)); + assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1)); + assert_eq!(module.execute_index(5, vec![].into()).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![].into()).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![].into()).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![].into()).unwrap().unwrap(), RuntimeValue::I32(0)); + assert_eq!(module.execute_index(12, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1)); + assert_eq!(module.execute_index(13, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0)); + assert_eq!(module.execute_index(14, vec![].into()).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 @@ -2379,11 +2381,11 @@ fn convert_i32() { let program = ProgramInstance::new().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(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(-100)); // 4294967196 - assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(-1294967296)); // 3000000000 - assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(-100)); // 4294967196 - assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I32(-1294967296)); // 3000000000 + assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1)); // 4294967295 + assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-100)); // 4294967196 + assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1294967296)); // 3000000000 + assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-100)); // 4294967196 + 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 @@ -2452,12 +2454,12 @@ fn convert_i64() { let program = ProgramInstance::new().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(1, vec![]).unwrap().unwrap(), RuntimeValue::I64(-1)); // 18446744073709551615 - assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); + assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(4294967295)); + assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-1)); // 18446744073709551615 + assert_eq!(module.execute_index(2, vec![].into()).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![].into()).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 @@ -2510,11 +2512,11 @@ fn convert_f32() { let program = ProgramInstance::new().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(1, vec![]).unwrap().unwrap(), RuntimeValue::F32(4294967296.000000)); - assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::F32(12345679.000000)); - assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::F32(0.000000)); - assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::F32(0.000000)); + assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(-1.000000)); + assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(4294967296.000000)); + assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(12345679.000000)); + assert_eq!(module.execute_index(3, vec![].into()).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 @@ -2567,11 +2569,11 @@ fn convert_f64() { let program = ProgramInstance::new().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(1, vec![]).unwrap().unwrap(), RuntimeValue::F64(4294967295.000000)); - assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::F64(12345679.000000)); - assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::F64(0.000000)); - assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::F64(0.000000)); + assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(-1.000000)); + assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(4294967295.000000)); + assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(12345679.000000)); + assert_eq!(module.execute_index(3, vec![].into()).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 @@ -2627,11 +2629,11 @@ fn load_i32() { let program = ProgramInstance::new().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(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(-1)); - assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(-1)); - assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(255)); - assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I32(65535)); + assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1)); + assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1)); + assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1)); + assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(255)); + 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 @@ -2703,13 +2705,13 @@ fn load_i64() { let program = ProgramInstance::new().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(1, vec![]).unwrap().unwrap(), RuntimeValue::I64(-1)); - assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I64(-1)); - assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I64(-1)); - assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I64(255)); - assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::I64(65535)); - assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::I64(4294967295)); + assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-1)); + assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-1)); + assert_eq!(module.execute_index(2, vec![].into()).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![].into()).unwrap().unwrap(), RuntimeValue::I64(255)); + assert_eq!(module.execute_index(5, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(65535)); + 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 @@ -2733,7 +2735,7 @@ fn load_f32() { let program = ProgramInstance::new().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 @@ -2757,7 +2759,7 @@ fn load_f64() { let program = ProgramInstance::new().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 @@ -2814,9 +2816,9 @@ fn store_i32() { let program = ProgramInstance::new().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(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(-859059511)); - assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(-123456)); + assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-16909061)); + assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-859059511)); + assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-123456)); } /// 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 module = program.add_module("main", module).unwrap(); - assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::I64(4278058235)); - assert_eq!(module.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I64(3435907785)); - assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I64(4294843840)); - assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I64(-4981613551475109875)); + assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(4278058235)); + assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(3435907785)); + assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(4294843840)); + 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 @@ -2912,7 +2914,7 @@ fn store_f32() { let program = ProgramInstance::new().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 @@ -2937,7 +2939,7 @@ fn store_f64() { let program = ProgramInstance::new().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 @@ -2988,11 +2990,11 @@ fn unary_i32() { let program = ProgramInstance::new().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(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(24)); - assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(7)); - assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); + assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0)); + assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1)); + assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(24)); + assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(7)); + 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 @@ -3043,11 +3045,11 @@ fn unary_i64() { let program = ProgramInstance::new().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(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I64(56)); - assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I64(7)); - assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I64(1)); + assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0)); + assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1)); + assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(56)); + assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(7)); + 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 @@ -3142,15 +3144,15 @@ fn unary_f32() { let program = ProgramInstance::new().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(2, vec![]).unwrap().unwrap(), RuntimeValue::F32(100.000000)); - assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::F32(10.000000)); - assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::F32(-0.000000)); - assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::F32(-1.000000)); - assert_eq!(module.execute_index(7, vec![]).unwrap().unwrap(), RuntimeValue::F32(-0.000000)); - assert_eq!(module.execute_index(8, vec![]).unwrap().unwrap(), RuntimeValue::F32(1.000000)); - assert_eq!(module.execute_index(9, vec![]).unwrap().unwrap(), RuntimeValue::F32(2.000000)); + assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(-100.000000)); + assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(100.000000)); + assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1)); + assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(10.000000)); + assert_eq!(module.execute_index(5, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(-0.000000)); + assert_eq!(module.execute_index(6, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(-1.000000)); + assert_eq!(module.execute_index(7, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(-0.000000)); + assert_eq!(module.execute_index(8, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(1.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 @@ -3245,13 +3247,13 @@ fn unary_f64() { let program = ProgramInstance::new().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(2, vec![]).unwrap().unwrap(), RuntimeValue::F64(100.000000)); - assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(1)); - assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::F64(10.000000)); - assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::F64(-0.000000)); - assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::F64(-1.000000)); - assert_eq!(module.execute_index(7, vec![]).unwrap().unwrap(), RuntimeValue::F64(-0.000000)); - assert_eq!(module.execute_index(8, vec![]).unwrap().unwrap(), RuntimeValue::F64(1.000000)); - assert_eq!(module.execute_index(9, vec![]).unwrap().unwrap(), RuntimeValue::F64(2.000000)); + assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(-100.000000)); + assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(100.000000)); + assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1)); + assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(10.000000)); + assert_eq!(module.execute_index(5, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(-0.000000)); + assert_eq!(module.execute_index(6, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(-1.000000)); + assert_eq!(module.execute_index(7, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(-0.000000)); + assert_eq!(module.execute_index(8, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(1.000000)); + assert_eq!(module.execute_index(9, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(2.000000)); }