mirror of
https://github.com/fluencelabs/parity-wasm
synced 2025-05-18 18:21:31 +00:00
commit
533c3a0c50
@ -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()));
|
||||
}
|
||||
|
@ -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<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,
|
||||
}
|
||||
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<UserFunctionClosure>>;
|
||||
|
||||
pub struct EnvModuleInstance {
|
||||
_params: EnvParams,
|
||||
user_functions: UserFunctionsInternals,
|
||||
instance: ModuleInstance,
|
||||
}
|
||||
|
||||
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)?;
|
||||
|
||||
Ok(EnvModuleInstance {
|
||||
_params: params,
|
||||
user_functions: user_functions,
|
||||
instance: instance,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ModuleInstanceInterface for EnvModuleInstance {
|
||||
fn execute_main(&self, args: Vec<RuntimeValue>) -> Result<Option<RuntimeValue>, Error> {
|
||||
self.instance.execute_main(args)
|
||||
fn execute_main(&self, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> {
|
||||
self.instance.execute_main(params)
|
||||
}
|
||||
|
||||
fn execute_index(&self, index: u32, args: Vec<RuntimeValue>) -> Result<Option<RuntimeValue>, Error> {
|
||||
self.instance.execute_index(index, args)
|
||||
fn execute_index(&self, index: u32, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> {
|
||||
self.instance.execute_index(index, params)
|
||||
}
|
||||
|
||||
fn execute_export(&self, name: &str, args: Vec<RuntimeValue>) -> Result<Option<RuntimeValue>, Error> {
|
||||
self.instance.execute_export(name, args)
|
||||
fn execute_export(&self, name: &str, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> {
|
||||
self.instance.execute_export(name, params)
|
||||
}
|
||||
|
||||
fn module(&self) -> &Module {
|
||||
self.instance.module()
|
||||
fn export_entry(&self, name: &str) -> Result<Internal, Error> {
|
||||
self.instance.export_entry(name)
|
||||
}
|
||||
|
||||
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> {
|
||||
// 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<EnvModuleInstance, Error> {
|
||||
pub fn env_module() -> Result<EnvModuleInstance, Error> {
|
||||
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<EnvModuleInstance, Er
|
||||
.build()
|
||||
.with_export(ExportEntry::new("getTotalMemory".into(), Internal::Function(INDEX_FUNC_GET_TOTAL_MEMORY)));
|
||||
|
||||
let mut funcs = user_functions;
|
||||
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())
|
||||
EnvModuleInstance::new(env_params, builder.build())
|
||||
}
|
||||
|
||||
impl Default for EnvParams {
|
||||
|
124
src/interpreter/env_native.rs
Normal file
124
src/interpreter/env_native.rs
Normal 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)
|
||||
}
|
@ -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<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
|
||||
.upgrade()
|
||||
.ok_or(Error::Program("program unloaded".into()))
|
||||
@ -102,8 +109,8 @@ impl ModuleImports {
|
||||
}
|
||||
|
||||
/// Get function index.
|
||||
pub fn function(&self, import: &ImportEntry) -> Result<u32, Error> {
|
||||
let (_, export) = self.external_export(import)?;
|
||||
pub fn function<'a>(&self, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>, import: &ImportEntry) -> Result<u32, Error> {
|
||||
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<Arc<TableInstance>, Error> {
|
||||
let (module, export) = self.external_export(import)?;
|
||||
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(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<Arc<MemoryInstance>, Error> {
|
||||
let (module, export) = self.external_export(import)?;
|
||||
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(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<Arc<VariableInstance>, Error> {
|
||||
let (module, export) = self.external_export(import)?;
|
||||
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(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<ModuleInstanceInterface>, 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<String, Arc<ModuleInstanceInterface + 'a>>>, import: &ImportEntry) -> Result<(Arc<ModuleInstanceInterface + 'a>, Internal), Error> {
|
||||
self.module(externals, import.module())
|
||||
.and_then(|m|
|
||||
m.export_entry(import.field())
|
||||
.map(|e| (m, e)))
|
||||
}
|
||||
}
|
||||
|
@ -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<String> 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};
|
||||
pub use self::variable::VariableInstance;
|
||||
pub use self::env_native::{env_native_module, UserFunctions, UserFunction, UserFunctionExecutor};
|
||||
|
@ -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<RuntimeValue>,
|
||||
/// Execution-local external modules.
|
||||
pub externals: HashMap<String, Arc<ModuleInstanceInterface + 'a>>,
|
||||
}
|
||||
|
||||
/// Module instance API.
|
||||
pub trait ModuleInstanceInterface {
|
||||
/// 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.
|
||||
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.
|
||||
fn execute_export(&self, name: &str, args: Vec<RuntimeValue>) -> Result<Option<RuntimeValue>, Error>;
|
||||
/// Get module description reference.
|
||||
fn module(&self) -> &Module;
|
||||
fn execute_export(&self, name: &str, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error>;
|
||||
/// Get export entry.
|
||||
fn export_entry(&self, name: &str) -> Result<Internal, Error>;
|
||||
/// Get table reference.
|
||||
fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance>, 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<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 {
|
||||
@ -149,19 +188,19 @@ impl 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()))?;
|
||||
self.execute_index(index, args)
|
||||
self.execute_index(index, params)
|
||||
}
|
||||
|
||||
fn execute_index(&self, index: u32, args: Vec<RuntimeValue>) -> Result<Option<RuntimeValue>, 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<Option<RuntimeValue>, 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<RuntimeValue>) -> Result<Option<RuntimeValue>, Error> {
|
||||
fn execute_export(&self, name: &str, params: ExecutionParams) -> Result<Option<RuntimeValue>, 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<Internal, Error> {
|
||||
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> {
|
||||
@ -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<Option<RuntimeValue>, Error> {
|
||||
fn call_internal_function(&self, mut outer: CallerContext, index: u32, function_type: Option<&FunctionType>) -> Result<Option<RuntimeValue>, 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<RuntimeValue>) -> Self {
|
||||
pub fn topmost(args: &'a mut StackWithLimit<RuntimeValue>, externals: &'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>) -> 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<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
|
||||
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)),
|
||||
|
@ -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<Self, Error> {
|
||||
Ok(ProgramInstance {
|
||||
essence: Arc::new(ProgramInstanceEssence::with_functions(funcs)?),
|
||||
})
|
||||
}
|
||||
|
||||
/// Instantiate module.
|
||||
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 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());
|
||||
// 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<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 env_module: Arc<ModuleInstanceInterface> = Arc::new(env_module(funcs)?);
|
||||
let env_module: Arc<ModuleInstanceInterface> = Arc::new(env_module()?);
|
||||
modules.insert("env".into(), env_module);
|
||||
Ok(ProgramInstanceEssence {
|
||||
modules: RwLock::new(modules),
|
||||
|
@ -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<String, Arc<ModuleInstanceInterface + 'a>>,
|
||||
/// Function return type.
|
||||
return_type: BlockType,
|
||||
pub return_type: BlockType,
|
||||
/// Local variables.
|
||||
locals: Vec<VariableInstance>,
|
||||
pub locals: Vec<VariableInstance>,
|
||||
/// Values stack.
|
||||
value_stack: StackWithLimit<RuntimeValue>,
|
||||
pub value_stack: StackWithLimit<RuntimeValue>,
|
||||
/// Blocks frames stack.
|
||||
frame_stack: StackWithLimit<BlockFrame>,
|
||||
pub frame_stack: StackWithLimit<BlockFrame>,
|
||||
/// 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<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 {
|
||||
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<String, Arc<ModuleInstanceInterface + 'a>> {
|
||||
&self.externals
|
||||
}
|
||||
|
||||
pub fn call_function(&mut self, index: u32) -> Result<Option<RuntimeValue>, Error> {
|
||||
self.module.call_function(CallerContext::nested(self), ItemIndex::IndexSpace(index))
|
||||
}
|
||||
|
@ -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<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()
|
||||
.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::<i32>()?;
|
||||
Ok(Some(prev.into()))
|
||||
}),
|
||||
}
|
||||
);
|
||||
|
||||
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 program = ProgramInstance::with_functions(user_functions).unwrap();
|
||||
// load module
|
||||
let module_instance = program.add_module("main", module).unwrap();
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
||||
#[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 {
|
||||
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),
|
||||
closure: Box::new(UserMAlloc { top: 0 }),
|
||||
}, 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());
|
||||
|
||||
// execute functions
|
||||
let params = ExecutionParams::with_external("env".into(), native_env_instance);
|
||||
|
||||
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));
|
||||
}
|
||||
);
|
||||
|
||||
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));
|
||||
assert_eq!(executor.memory.get(0, 1).unwrap()[0], 42);
|
||||
assert_eq!(executor.values, vec![7, 57, 42]);
|
||||
}
|
@ -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<i32, Error> {
|
||||
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));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user