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 = parity_wasm::deserialize_file(&args[1]).expect("Failed to load module");
|
||||||
let module = program.add_module("main", module).expect("Failed to initialize module");
|
let module = program.add_module("main", module).expect("Failed to initialize module");
|
||||||
let argument: i32 = args[2].parse().expect("Integer argument required");
|
let argument: i32 = args[2].parse().expect("Integer argument required");
|
||||||
println!("Result: {:?}", module.execute_export("_call", vec![parity_wasm::RuntimeValue::I32(argument)]));
|
println!("Result: {:?}", module.execute_export("_call", vec![parity_wasm::RuntimeValue::I32(argument)].into()));
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use builder::{module, function, export};
|
use builder::module;
|
||||||
use elements::{Module, FunctionType, ExportEntry, Internal, GlobalEntry, GlobalType,
|
use elements::{Module, FunctionType, ExportEntry, Internal, GlobalEntry, GlobalType,
|
||||||
ValueType, InitExpr, Opcode, Opcodes};
|
ValueType, InitExpr, Opcode, Opcodes};
|
||||||
use interpreter::Error;
|
use interpreter::Error;
|
||||||
use interpreter::module::{ModuleInstanceInterface, ModuleInstance, ItemIndex, CallerContext};
|
use interpreter::env_native::NATIVE_INDEX_FUNC_MIN;
|
||||||
|
use interpreter::module::{ModuleInstanceInterface, ModuleInstance, ExecutionParams,
|
||||||
|
ItemIndex, CallerContext};
|
||||||
use interpreter::memory::{MemoryInstance, LINEAR_MEMORY_PAGE_SIZE};
|
use interpreter::memory::{MemoryInstance, LINEAR_MEMORY_PAGE_SIZE};
|
||||||
use interpreter::table::TableInstance;
|
use interpreter::table::TableInstance;
|
||||||
use interpreter::value::{RuntimeValue, TransmuteInto};
|
use interpreter::value::{RuntimeValue, TransmuteInto};
|
||||||
@ -58,44 +59,10 @@ const INDEX_FUNC_ASSERT: u32 = 1;
|
|||||||
const INDEX_FUNC_ENLARGE_MEMORY: u32 = 2;
|
const INDEX_FUNC_ENLARGE_MEMORY: u32 = 2;
|
||||||
/// Index of getTotalMemory function.
|
/// Index of getTotalMemory function.
|
||||||
const INDEX_FUNC_GET_TOTAL_MEMORY: u32 = 3;
|
const INDEX_FUNC_GET_TOTAL_MEMORY: u32 = 3;
|
||||||
/// Index of abortOnCannotGrowMemory function.
|
|
||||||
/*const INDEX_FUNC_ABORT_ON_CANNOT_GROW_MEMORY: u32 = 4;
|
|
||||||
/// Index of invoke_vi function.
|
|
||||||
const INDEX_FUNC_INVOKE_VI: u32 = 5;
|
|
||||||
/// Index of invoke function.
|
|
||||||
const INDEX_FUNC_INVOKE: u32 = 6;*/
|
|
||||||
/// Min index of reserver function.
|
/// Min index of reserver function.
|
||||||
const INDEX_FUNC_MIN_NONUSED: u32 = 7;
|
const INDEX_FUNC_MIN_NONUSED: u32 = 4;
|
||||||
/// Max index of reserved function.
|
/// Max index of reserved function.
|
||||||
const INDEX_FUNC_MAX: u32 = 10000;
|
const INDEX_FUNC_MAX: u32 = NATIVE_INDEX_FUNC_MIN - 1;
|
||||||
|
|
||||||
/// Set of user-defined functions
|
|
||||||
pub type UserFunctions = HashMap<String, UserFunction>;
|
|
||||||
|
|
||||||
/// User function closure
|
|
||||||
pub type UserFunctionClosure = Box<UserFunctionInterface>;
|
|
||||||
|
|
||||||
/// User-defined function execution interface
|
|
||||||
pub trait UserFunctionInterface {
|
|
||||||
/// Handles the user function invocation
|
|
||||||
fn call(&mut self, module: &ModuleInstance, context: CallerContext) -> Result<Option<RuntimeValue>, Error>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> UserFunctionInterface for T where T: FnMut(&ModuleInstance, CallerContext) -> Result<Option<RuntimeValue>, Error> {
|
|
||||||
fn call(&mut self, module: &ModuleInstance, context: CallerContext) -> Result<Option<RuntimeValue>, Error> {
|
|
||||||
(&mut *self)(module, context)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Signature of user-defined env function
|
|
||||||
pub struct UserFunction {
|
|
||||||
/// User function parameters (for signature matching)
|
|
||||||
pub params: Vec<ValueType>,
|
|
||||||
/// User function return type (for signature matching)
|
|
||||||
pub result: Option<ValueType>,
|
|
||||||
/// Executor of the function
|
|
||||||
pub closure: UserFunctionClosure,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Environment parameters.
|
/// Environment parameters.
|
||||||
pub struct EnvParams {
|
pub struct EnvParams {
|
||||||
@ -107,41 +74,37 @@ pub struct EnvParams {
|
|||||||
pub allow_memory_growth: bool,
|
pub allow_memory_growth: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserFunctionsInternals = Vec<::std::cell::RefCell<UserFunctionClosure>>;
|
|
||||||
|
|
||||||
pub struct EnvModuleInstance {
|
pub struct EnvModuleInstance {
|
||||||
_params: EnvParams,
|
_params: EnvParams,
|
||||||
user_functions: UserFunctionsInternals,
|
|
||||||
instance: ModuleInstance,
|
instance: ModuleInstance,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EnvModuleInstance {
|
impl EnvModuleInstance {
|
||||||
pub fn new(params: EnvParams, user_functions: UserFunctionsInternals, module: Module) -> Result<Self, Error> {
|
pub fn new(params: EnvParams, module: Module) -> Result<Self, Error> {
|
||||||
let instance = ModuleInstance::new(Weak::default(), module)?;
|
let instance = ModuleInstance::new(Weak::default(), module)?;
|
||||||
|
|
||||||
Ok(EnvModuleInstance {
|
Ok(EnvModuleInstance {
|
||||||
_params: params,
|
_params: params,
|
||||||
user_functions: user_functions,
|
|
||||||
instance: instance,
|
instance: instance,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModuleInstanceInterface for EnvModuleInstance {
|
impl ModuleInstanceInterface for EnvModuleInstance {
|
||||||
fn execute_main(&self, args: Vec<RuntimeValue>) -> Result<Option<RuntimeValue>, Error> {
|
fn execute_main(&self, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> {
|
||||||
self.instance.execute_main(args)
|
self.instance.execute_main(params)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute_index(&self, index: u32, args: Vec<RuntimeValue>) -> Result<Option<RuntimeValue>, Error> {
|
fn execute_index(&self, index: u32, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> {
|
||||||
self.instance.execute_index(index, args)
|
self.instance.execute_index(index, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute_export(&self, name: &str, args: Vec<RuntimeValue>) -> Result<Option<RuntimeValue>, Error> {
|
fn execute_export(&self, name: &str, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> {
|
||||||
self.instance.execute_export(name, args)
|
self.instance.execute_export(name, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn module(&self) -> &Module {
|
fn export_entry(&self, name: &str) -> Result<Internal, Error> {
|
||||||
self.instance.module()
|
self.instance.export_entry(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance>, Error> {
|
fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance>, Error> {
|
||||||
@ -165,6 +128,7 @@ impl ModuleInstanceInterface for EnvModuleInstance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn call_internal_function(&self, outer: CallerContext, index: u32, _function_type: Option<&FunctionType>) -> Result<Option<RuntimeValue>, Error> {
|
fn call_internal_function(&self, outer: CallerContext, index: u32, _function_type: Option<&FunctionType>) -> Result<Option<RuntimeValue>, Error> {
|
||||||
|
// TODO: check function type
|
||||||
// to make interpreter independent of *SCRIPTEN runtime, just make abort/assert = interpreter Error
|
// to make interpreter independent of *SCRIPTEN runtime, just make abort/assert = interpreter Error
|
||||||
match index {
|
match index {
|
||||||
INDEX_FUNC_ABORT => self.global(ItemIndex::IndexSpace(INDEX_GLOBAL_ABORT))
|
INDEX_FUNC_ABORT => self.global(ItemIndex::IndexSpace(INDEX_GLOBAL_ABORT))
|
||||||
@ -183,26 +147,17 @@ impl ModuleInstanceInterface for EnvModuleInstance {
|
|||||||
.map(|g| g.get())
|
.map(|g| g.get())
|
||||||
.map(Some),
|
.map(Some),
|
||||||
INDEX_FUNC_MIN_NONUSED ... INDEX_FUNC_MAX => Err(Error::Trap("unimplemented".into())),
|
INDEX_FUNC_MIN_NONUSED ... INDEX_FUNC_MAX => Err(Error::Trap("unimplemented".into())),
|
||||||
idx if idx > INDEX_FUNC_MAX && idx <= INDEX_FUNC_MAX + self.user_functions.len() as u32 => {
|
|
||||||
// user-defined function
|
|
||||||
let user_index = idx - (INDEX_FUNC_MAX+1);
|
|
||||||
let func = self.user_functions.get(user_index as usize).ok_or(Error::Trap(format!("Trying to invoke user-defined function {}", user_index)))?;
|
|
||||||
func.borrow_mut().call(&self.instance, outer)
|
|
||||||
},
|
|
||||||
// idx @ _ if idx == INDEX_FUNC_MAX + 1 => outer.value_stack.pop().map(|_| None), // TODO: `gas(i32) -> None` function
|
|
||||||
// idx @ _ if idx == INDEX_FUNC_MAX + 2 => Ok(Some(RuntimeValue::I32(0))), // TODO: `_storage_size() -> i32` function
|
|
||||||
// idx @ _ if idx == INDEX_FUNC_MAX + 3 => outer.value_stack.pop_triple().map(|_| Some(RuntimeValue::I32(0))), // TODO: `_storage_size(i32,i32,i32) -> i32` function
|
|
||||||
_ => Err(Error::Trap(format!("trying to call function with index {} in env module", index))),
|
_ => Err(Error::Trap(format!("trying to call function with index {} in env module", index))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn env_module(user_functions: UserFunctions) -> Result<EnvModuleInstance, Error> {
|
pub fn env_module() -> Result<EnvModuleInstance, Error> {
|
||||||
let env_params = EnvParams::default();
|
let env_params = EnvParams::default();
|
||||||
debug_assert!(env_params.total_stack < env_params.total_memory);
|
debug_assert!(env_params.total_stack < env_params.total_memory);
|
||||||
debug_assert!((env_params.total_stack % LINEAR_MEMORY_PAGE_SIZE) == 0);
|
debug_assert!((env_params.total_stack % LINEAR_MEMORY_PAGE_SIZE) == 0);
|
||||||
debug_assert!((env_params.total_memory % LINEAR_MEMORY_PAGE_SIZE) == 0);
|
debug_assert!((env_params.total_memory % LINEAR_MEMORY_PAGE_SIZE) == 0);
|
||||||
let mut builder = module()
|
let builder = module()
|
||||||
// memory regions
|
// memory regions
|
||||||
.memory()
|
.memory()
|
||||||
.with_min(env_params.total_memory / LINEAR_MEMORY_PAGE_SIZE)
|
.with_min(env_params.total_memory / LINEAR_MEMORY_PAGE_SIZE)
|
||||||
@ -255,29 +210,7 @@ pub fn env_module(user_functions: UserFunctions) -> Result<EnvModuleInstance, Er
|
|||||||
.build()
|
.build()
|
||||||
.with_export(ExportEntry::new("getTotalMemory".into(), Internal::Function(INDEX_FUNC_GET_TOTAL_MEMORY)));
|
.with_export(ExportEntry::new("getTotalMemory".into(), Internal::Function(INDEX_FUNC_GET_TOTAL_MEMORY)));
|
||||||
|
|
||||||
let mut funcs = user_functions;
|
EnvModuleInstance::new(env_params, builder.build())
|
||||||
let mut internals = UserFunctionsInternals::new();
|
|
||||||
let mut index = INDEX_FUNC_MAX + 1;
|
|
||||||
for (func_name, func) in funcs.drain() {
|
|
||||||
let _location = builder.push_function(
|
|
||||||
function()
|
|
||||||
.signature().with_params(func.params).with_return_type(func.result).build()
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
|
|
||||||
let _export_idx = builder.push_export(
|
|
||||||
export()
|
|
||||||
.field(&func_name)
|
|
||||||
.internal().func(index)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
|
|
||||||
internals.push(::std::cell::RefCell::new(func.closure));
|
|
||||||
|
|
||||||
index += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
EnvModuleInstance::new(env_params, internals, builder.build())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for EnvParams {
|
impl Default for EnvParams {
|
||||||
|
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::sync::{Arc, Weak};
|
||||||
|
use std::collections::HashMap;
|
||||||
use elements::{ImportSection, ImportEntry, External, Internal};
|
use elements::{ImportSection, ImportEntry, External, Internal};
|
||||||
use interpreter::Error;
|
use interpreter::Error;
|
||||||
use interpreter::memory::MemoryInstance;
|
use interpreter::memory::MemoryInstance;
|
||||||
@ -94,7 +95,13 @@ impl ModuleImports {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get module reference.
|
/// Get module reference.
|
||||||
pub fn module(&self, name: &str) -> Result<Arc<ModuleInstanceInterface>, Error> {
|
pub fn module<'a>(&self, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>, name: &str) -> Result<Arc<ModuleInstanceInterface + 'a>, Error> {
|
||||||
|
if let Some(externals) = externals {
|
||||||
|
if let Some(module) = externals.get(name).cloned() {
|
||||||
|
return Ok(module);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.program
|
self.program
|
||||||
.upgrade()
|
.upgrade()
|
||||||
.ok_or(Error::Program("program unloaded".into()))
|
.ok_or(Error::Program("program unloaded".into()))
|
||||||
@ -102,8 +109,8 @@ impl ModuleImports {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get function index.
|
/// Get function index.
|
||||||
pub fn function(&self, import: &ImportEntry) -> Result<u32, Error> {
|
pub fn function<'a>(&self, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>, import: &ImportEntry) -> Result<u32, Error> {
|
||||||
let (_, export) = self.external_export(import)?;
|
let (_, export) = self.external_export(externals, import)?;
|
||||||
if let Internal::Function(external_index) = export {
|
if let Internal::Function(external_index) = export {
|
||||||
return Ok(external_index);
|
return Ok(external_index);
|
||||||
}
|
}
|
||||||
@ -112,8 +119,8 @@ impl ModuleImports {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get table reference.
|
/// Get table reference.
|
||||||
pub fn table(&self, import: &ImportEntry) -> Result<Arc<TableInstance>, Error> {
|
pub fn table<'a>(&self, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>, import: &ImportEntry) -> Result<Arc<TableInstance>, Error> {
|
||||||
let (module, export) = self.external_export(import)?;
|
let (module, export) = self.external_export(externals, import)?;
|
||||||
if let Internal::Table(external_index) = export {
|
if let Internal::Table(external_index) = export {
|
||||||
return module.table(ItemIndex::Internal(external_index));
|
return module.table(ItemIndex::Internal(external_index));
|
||||||
}
|
}
|
||||||
@ -122,8 +129,8 @@ impl ModuleImports {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get memory reference.
|
/// Get memory reference.
|
||||||
pub fn memory(&self, import: &ImportEntry) -> Result<Arc<MemoryInstance>, Error> {
|
pub fn memory<'a>(&self, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>, import: &ImportEntry) -> Result<Arc<MemoryInstance>, Error> {
|
||||||
let (module, export) = self.external_export(import)?;
|
let (module, export) = self.external_export(externals, import)?;
|
||||||
if let Internal::Memory(external_index) = export {
|
if let Internal::Memory(external_index) = export {
|
||||||
return module.memory(ItemIndex::Internal(external_index));
|
return module.memory(ItemIndex::Internal(external_index));
|
||||||
}
|
}
|
||||||
@ -132,8 +139,8 @@ impl ModuleImports {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get global reference.
|
/// Get global reference.
|
||||||
pub fn global(&self, import: &ImportEntry) -> Result<Arc<VariableInstance>, Error> {
|
pub fn global<'a>(&self, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>, import: &ImportEntry) -> Result<Arc<VariableInstance>, Error> {
|
||||||
let (module, export) = self.external_export(import)?;
|
let (module, export) = self.external_export(externals, import)?;
|
||||||
if let Internal::Global(external_index) = export {
|
if let Internal::Global(external_index) = export {
|
||||||
return module.global(ItemIndex::Internal(external_index));
|
return module.global(ItemIndex::Internal(external_index));
|
||||||
}
|
}
|
||||||
@ -141,14 +148,10 @@ impl ModuleImports {
|
|||||||
Err(Error::Program(format!("wrong import {} from module {} (expecting global)", import.field(), import.module())))
|
Err(Error::Program(format!("wrong import {} from module {} (expecting global)", import.field(), import.module())))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn external_export(&self, import: &ImportEntry) -> Result<(Arc<ModuleInstanceInterface>, Internal), Error> {
|
fn external_export<'a>(&self, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>, import: &ImportEntry) -> Result<(Arc<ModuleInstanceInterface + 'a>, Internal), Error> {
|
||||||
self.module(import.module())
|
self.module(externals, import.module())
|
||||||
.and_then(|m| m.module().export_section()
|
.and_then(|m|
|
||||||
.ok_or(Error::Program(format!("trying to import from module {} without export section", import.module())))
|
m.export_entry(import.field())
|
||||||
.and_then(|s| s.entries().iter()
|
.map(|e| (m, e)))
|
||||||
.find(|e| e.field() == import.field())
|
|
||||||
.map(|e| e.internal())
|
|
||||||
.ok_or(Error::Program(format!("unresolved import {} from module {}", import.field(), import.module())))
|
|
||||||
.map(|export| (m.clone(), *export))))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,8 @@ pub enum Error {
|
|||||||
Interpreter(String),
|
Interpreter(String),
|
||||||
/// Env module error.
|
/// Env module error.
|
||||||
Env(String),
|
Env(String),
|
||||||
|
/// Native module error.
|
||||||
|
Native(String),
|
||||||
/// Trap.
|
/// Trap.
|
||||||
Trap(String),
|
Trap(String),
|
||||||
}
|
}
|
||||||
@ -46,12 +48,14 @@ impl Into<String> for Error {
|
|||||||
Error::Interpreter(s) => s,
|
Error::Interpreter(s) => s,
|
||||||
Error::Value(s) => s,
|
Error::Value(s) => s,
|
||||||
Error::Env(s) => s,
|
Error::Env(s) => s,
|
||||||
|
Error::Native(s) => s,
|
||||||
Error::Trap(s) => format!("trap: {}", s),
|
Error::Trap(s) => format!("trap: {}", s),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod env;
|
mod env;
|
||||||
|
mod env_native;
|
||||||
mod imports;
|
mod imports;
|
||||||
mod memory;
|
mod memory;
|
||||||
mod module;
|
mod module;
|
||||||
@ -65,7 +69,10 @@ mod variable;
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
pub use self::module::{ModuleInstance, ModuleInstanceInterface, ItemIndex, CallerContext};
|
pub use self::memory::MemoryInstance;
|
||||||
|
pub use self::module::{ModuleInstance, ModuleInstanceInterface, ItemIndex, CallerContext, ExecutionParams};
|
||||||
|
pub use self::table::TableInstance;
|
||||||
pub use self::program::ProgramInstance;
|
pub use self::program::ProgramInstance;
|
||||||
pub use self::value::RuntimeValue;
|
pub use self::value::RuntimeValue;
|
||||||
pub use self::env::{UserFunctions, UserFunction, UserFunctionInterface};
|
pub use self::variable::VariableInstance;
|
||||||
|
pub use self::env_native::{env_native_module, UserFunctions, UserFunction, UserFunctionExecutor};
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
use std::iter::repeat;
|
use std::iter::repeat;
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
use elements::{Module, InitExpr, Opcode, Type, FunctionType, FuncBody, Internal};
|
use elements::{Module, InitExpr, Opcode, Type, FunctionType, FuncBody, Internal};
|
||||||
@ -11,16 +12,25 @@ use interpreter::table::TableInstance;
|
|||||||
use interpreter::value::{RuntimeValue, TryInto, TransmuteInto};
|
use interpreter::value::{RuntimeValue, TryInto, TransmuteInto};
|
||||||
use interpreter::variable::{VariableInstance, VariableType};
|
use interpreter::variable::{VariableInstance, VariableType};
|
||||||
|
|
||||||
|
#[derive(Default, Clone)]
|
||||||
|
/// Execution context.
|
||||||
|
pub struct ExecutionParams<'a> {
|
||||||
|
/// Arguments.
|
||||||
|
pub args: Vec<RuntimeValue>,
|
||||||
|
/// Execution-local external modules.
|
||||||
|
pub externals: HashMap<String, Arc<ModuleInstanceInterface + 'a>>,
|
||||||
|
}
|
||||||
|
|
||||||
/// Module instance API.
|
/// Module instance API.
|
||||||
pub trait ModuleInstanceInterface {
|
pub trait ModuleInstanceInterface {
|
||||||
/// Execute start function of the module.
|
/// Execute start function of the module.
|
||||||
fn execute_main(&self, args: Vec<RuntimeValue>) -> Result<Option<RuntimeValue>, Error>;
|
fn execute_main(&self, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error>;
|
||||||
/// Execute function with the given index.
|
/// Execute function with the given index.
|
||||||
fn execute_index(&self, index: u32, args: Vec<RuntimeValue>) -> Result<Option<RuntimeValue>, Error>;
|
fn execute_index(&self, index: u32, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error>;
|
||||||
/// Execute function with the given export name.
|
/// Execute function with the given export name.
|
||||||
fn execute_export(&self, name: &str, args: Vec<RuntimeValue>) -> Result<Option<RuntimeValue>, Error>;
|
fn execute_export(&self, name: &str, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error>;
|
||||||
/// Get module description reference.
|
/// Get export entry.
|
||||||
fn module(&self) -> &Module;
|
fn export_entry(&self, name: &str) -> Result<Internal, Error>;
|
||||||
/// Get table reference.
|
/// Get table reference.
|
||||||
fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance>, Error>;
|
fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance>, Error>;
|
||||||
/// Get memory reference.
|
/// Get memory reference.
|
||||||
@ -42,7 +52,7 @@ pub enum ItemIndex {
|
|||||||
IndexSpace(u32),
|
IndexSpace(u32),
|
||||||
/// Internal item index (i.e. index of item in items section).
|
/// Internal item index (i.e. index of item in items section).
|
||||||
Internal(u32),
|
Internal(u32),
|
||||||
/// External item index (i.e. index of item in the import section).
|
/// External module item index (i.e. index of item in the import section).
|
||||||
External(u32),
|
External(u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,6 +78,35 @@ pub struct CallerContext<'a> {
|
|||||||
pub frame_stack_limit: usize,
|
pub frame_stack_limit: usize,
|
||||||
/// Stack of the input parameters
|
/// Stack of the input parameters
|
||||||
pub value_stack: &'a mut StackWithLimit<RuntimeValue>,
|
pub value_stack: &'a mut StackWithLimit<RuntimeValue>,
|
||||||
|
/// Execution-local external modules.
|
||||||
|
pub externals: &'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ExecutionParams<'a> {
|
||||||
|
/// Create new execution params with given externa; module override.
|
||||||
|
pub fn with_external(name: String, module: Arc<ModuleInstanceInterface + 'a>) -> Self {
|
||||||
|
let mut externals = HashMap::new();
|
||||||
|
externals.insert(name, module);
|
||||||
|
ExecutionParams {
|
||||||
|
args: Vec::new(),
|
||||||
|
externals: externals,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add argument.
|
||||||
|
pub fn add_argument(mut self, arg: RuntimeValue) -> Self {
|
||||||
|
self.args.push(arg);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<Vec<RuntimeValue>> for ExecutionParams<'a> {
|
||||||
|
fn from(args: Vec<RuntimeValue>) -> ExecutionParams<'a> {
|
||||||
|
ExecutionParams {
|
||||||
|
args: args,
|
||||||
|
externals: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModuleInstance {
|
impl ModuleInstance {
|
||||||
@ -149,19 +188,19 @@ impl ModuleInstance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ModuleInstanceInterface for ModuleInstance {
|
impl ModuleInstanceInterface for ModuleInstance {
|
||||||
fn execute_main(&self, args: Vec<RuntimeValue>) -> Result<Option<RuntimeValue>, Error> {
|
fn execute_main(&self, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> {
|
||||||
let index = self.module.start_section().ok_or(Error::Program("module has no start section".into()))?;
|
let index = self.module.start_section().ok_or(Error::Program("module has no start section".into()))?;
|
||||||
self.execute_index(index, args)
|
self.execute_index(index, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute_index(&self, index: u32, args: Vec<RuntimeValue>) -> Result<Option<RuntimeValue>, Error> {
|
fn execute_index(&self, index: u32, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> {
|
||||||
let args_len = args.len();
|
let args_len = params.args.len();
|
||||||
let mut args = StackWithLimit::with_data(args, args_len);
|
let mut args = StackWithLimit::with_data(params.args, args_len);
|
||||||
let caller_context = CallerContext::topmost(&mut args);
|
let caller_context = CallerContext::topmost(&mut args, ¶ms.externals);
|
||||||
self.call_function(caller_context, ItemIndex::IndexSpace(index))
|
self.call_function(caller_context, ItemIndex::IndexSpace(index))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute_export(&self, name: &str, args: Vec<RuntimeValue>) -> Result<Option<RuntimeValue>, Error> {
|
fn execute_export(&self, name: &str, params: ExecutionParams) -> Result<Option<RuntimeValue>, Error> {
|
||||||
let index = self.module.export_section()
|
let index = self.module.export_section()
|
||||||
.ok_or(Error::Function("missing export section".into()))
|
.ok_or(Error::Function("missing export section".into()))
|
||||||
.and_then(|s| s.entries().iter()
|
.and_then(|s| s.entries().iter()
|
||||||
@ -175,11 +214,16 @@ impl ModuleInstanceInterface for ModuleInstance {
|
|||||||
_ => unreachable!(), // checked couple of lines above
|
_ => unreachable!(), // checked couple of lines above
|
||||||
})
|
})
|
||||||
)?;
|
)?;
|
||||||
self.execute_index(index, args)
|
self.execute_index(index, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn module(&self) -> &Module {
|
fn export_entry(&self, name: &str) -> Result<Internal, Error> {
|
||||||
&self.module
|
self.module.export_section()
|
||||||
|
.ok_or(Error::Program(format!("trying to import {} from module without export section", name)))
|
||||||
|
.and_then(|s| s.entries().iter()
|
||||||
|
.find(|e| e.field() == name)
|
||||||
|
.map(|e| *e.internal())
|
||||||
|
.ok_or(Error::Program(format!("unresolved import {}", name))))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance>, Error> {
|
fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance>, Error> {
|
||||||
@ -191,7 +235,7 @@ impl ModuleInstanceInterface for ModuleInstance {
|
|||||||
.ok_or(Error::Table(format!("trying to access external table with index {} in module without import section", index)))
|
.ok_or(Error::Table(format!("trying to access external table with index {} in module without import section", index)))
|
||||||
.and_then(|s| s.entries().get(index as usize)
|
.and_then(|s| s.entries().get(index as usize)
|
||||||
.ok_or(Error::Table(format!("trying to access external table with index {} in module with {}-entries import section", index, s.entries().len()))))
|
.ok_or(Error::Table(format!("trying to access external table with index {} in module with {}-entries import section", index, s.entries().len()))))
|
||||||
.and_then(|e| self.imports.table(e)),
|
.and_then(|e| self.imports.table(None, e)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,7 +248,7 @@ impl ModuleInstanceInterface for ModuleInstance {
|
|||||||
.ok_or(Error::Memory(format!("trying to access external memory with index {} in module without import section", index)))
|
.ok_or(Error::Memory(format!("trying to access external memory with index {} in module without import section", index)))
|
||||||
.and_then(|s| s.entries().get(index as usize)
|
.and_then(|s| s.entries().get(index as usize)
|
||||||
.ok_or(Error::Memory(format!("trying to access external memory with index {} in module with {}-entries import section", index, s.entries().len()))))
|
.ok_or(Error::Memory(format!("trying to access external memory with index {} in module with {}-entries import section", index, s.entries().len()))))
|
||||||
.and_then(|e| self.imports.memory(e)),
|
.and_then(|e| self.imports.memory(None, e)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,7 +261,7 @@ impl ModuleInstanceInterface for ModuleInstance {
|
|||||||
.ok_or(Error::Global(format!("trying to access external global with index {} in module without import section", index)))
|
.ok_or(Error::Global(format!("trying to access external global with index {} in module without import section", index)))
|
||||||
.and_then(|s| s.entries().get(index as usize)
|
.and_then(|s| s.entries().get(index as usize)
|
||||||
.ok_or(Error::Global(format!("trying to access external global with index {} in module with {}-entries import section", index, s.entries().len()))))
|
.ok_or(Error::Global(format!("trying to access external global with index {} in module with {}-entries import section", index, s.entries().len()))))
|
||||||
.and_then(|e| self.imports.global(e)),
|
.and_then(|e| self.imports.global(None, e)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,7 +274,7 @@ impl ModuleInstanceInterface for ModuleInstance {
|
|||||||
.ok_or(Error::Function(format!("trying to access external function with index {} in module without import section", index)))
|
.ok_or(Error::Function(format!("trying to access external function with index {} in module without import section", index)))
|
||||||
.and_then(|s| s.entries().get(index as usize)
|
.and_then(|s| s.entries().get(index as usize)
|
||||||
.ok_or(Error::Function(format!("trying to access external function with index {} in module with {}-entries import section", index, s.entries().len()))))
|
.ok_or(Error::Function(format!("trying to access external function with index {} in module with {}-entries import section", index, s.entries().len()))))
|
||||||
.and_then(|e| Ok((self.imports.module(e.module())?, self.imports.function(e)?)))
|
.and_then(|e| Ok((self.imports.module(Some(outer.externals), e.module())?, self.imports.function(Some(outer.externals), e)?)))
|
||||||
.and_then(|(m, index)| m.call_internal_function(outer, index, None)),
|
.and_then(|(m, index)| m.call_internal_function(outer, index, None)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -263,13 +307,13 @@ impl ModuleInstanceInterface for ModuleInstance {
|
|||||||
.ok_or(Error::Function(format!("trying to access external table with index {} in module without import section", table_index)))
|
.ok_or(Error::Function(format!("trying to access external table with index {} in module without import section", table_index)))
|
||||||
.and_then(|s| s.entries().get(table_index as usize)
|
.and_then(|s| s.entries().get(table_index as usize)
|
||||||
.ok_or(Error::Function(format!("trying to access external table with index {} in module with {}-entries import section", table_index, s.entries().len()))))
|
.ok_or(Error::Function(format!("trying to access external table with index {} in module with {}-entries import section", table_index, s.entries().len()))))
|
||||||
.and_then(|e| self.imports.module(e.module()))?;
|
.and_then(|e| self.imports.module(Some(outer.externals), e.module()))?;
|
||||||
module.call_internal_function(outer, index, Some(function_type))
|
module.call_internal_function(outer, index, Some(function_type))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call_internal_function(&self, outer: CallerContext, index: u32, function_type: Option<&FunctionType>) -> Result<Option<RuntimeValue>, Error> {
|
fn call_internal_function(&self, mut outer: CallerContext, index: u32, function_type: Option<&FunctionType>) -> Result<Option<RuntimeValue>, Error> {
|
||||||
// TODO: cache
|
// TODO: cache
|
||||||
// internal index = index of function in functions section && index of code in code section
|
// internal index = index of function in functions section && index of code in code section
|
||||||
// get function type index
|
// get function type index
|
||||||
@ -311,19 +355,20 @@ impl ModuleInstanceInterface for ModuleInstance {
|
|||||||
let function_code = function_body.code().elements();
|
let function_code = function_body.code().elements();
|
||||||
let value_stack_limit = outer.value_stack_limit;
|
let value_stack_limit = outer.value_stack_limit;
|
||||||
let frame_stack_limit = outer.frame_stack_limit;
|
let frame_stack_limit = outer.frame_stack_limit;
|
||||||
let locals = prepare_function_locals(actual_function_type, function_body, outer)?;
|
let locals = prepare_function_locals(actual_function_type, function_body, &mut outer)?;
|
||||||
let mut innner = FunctionContext::new(self, value_stack_limit, frame_stack_limit, actual_function_type, function_code, locals)?;
|
let mut innner = FunctionContext::new(self, outer.externals, value_stack_limit, frame_stack_limit, actual_function_type, function_code, locals)?;
|
||||||
Interpreter::run_function(&mut innner, function_code)
|
Interpreter::run_function(&mut innner, function_code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CallerContext<'a> {
|
impl<'a> CallerContext<'a> {
|
||||||
/// Top most args
|
/// Top most args
|
||||||
pub fn topmost(args: &'a mut StackWithLimit<RuntimeValue>) -> Self {
|
pub fn topmost(args: &'a mut StackWithLimit<RuntimeValue>, externals: &'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>) -> Self {
|
||||||
CallerContext {
|
CallerContext {
|
||||||
value_stack_limit: 1024,
|
value_stack_limit: 1024,
|
||||||
frame_stack_limit: 1024,
|
frame_stack_limit: 1024,
|
||||||
value_stack: args,
|
value_stack: args,
|
||||||
|
externals: externals,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,12 +377,13 @@ impl<'a> CallerContext<'a> {
|
|||||||
CallerContext {
|
CallerContext {
|
||||||
value_stack_limit: outer.value_stack().limit() - outer.value_stack().len(),
|
value_stack_limit: outer.value_stack().limit() - outer.value_stack().len(),
|
||||||
frame_stack_limit: outer.frame_stack().limit() - outer.frame_stack().len(),
|
frame_stack_limit: outer.frame_stack().limit() - outer.frame_stack().len(),
|
||||||
value_stack: outer.value_stack_mut(),
|
value_stack: &mut outer.value_stack,
|
||||||
|
externals: &outer.externals,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepare_function_locals(function_type: &FunctionType, function_body: &FuncBody, outer: CallerContext) -> Result<Vec<VariableInstance>, Error> {
|
fn prepare_function_locals(function_type: &FunctionType, function_body: &FuncBody, outer: &mut CallerContext) -> Result<Vec<VariableInstance>, Error> {
|
||||||
// locals = function arguments + defined locals
|
// locals = function arguments + defined locals
|
||||||
function_type.params().iter().rev()
|
function_type.params().iter().rev()
|
||||||
.map(|param_type| {
|
.map(|param_type| {
|
||||||
@ -370,7 +416,7 @@ fn get_initializer(expr: &InitExpr, module: &Module, imports: &ModuleImports) ->
|
|||||||
.ok_or(Error::Global(format!("trying to initialize with external global with index {} in module without import section", index)))
|
.ok_or(Error::Global(format!("trying to initialize with external global with index {} in module without import section", index)))
|
||||||
.and_then(|s| s.entries().get(index as usize)
|
.and_then(|s| s.entries().get(index as usize)
|
||||||
.ok_or(Error::Global(format!("trying to initialize with external global with index {} in module with {}-entries import section", index, s.entries().len()))))
|
.ok_or(Error::Global(format!("trying to initialize with external global with index {} in module with {}-entries import section", index, s.entries().len()))))
|
||||||
.and_then(|e| imports.global(e))
|
.and_then(|e| imports.global(None, e))
|
||||||
.map(|g| g.get())
|
.map(|g| g.get())
|
||||||
},
|
},
|
||||||
&Opcode::I32Const(val) => Ok(RuntimeValue::I32(val)),
|
&Opcode::I32Const(val) => Ok(RuntimeValue::I32(val)),
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::collections::hash_map::Entry;
|
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use elements::Module;
|
use elements::Module;
|
||||||
use interpreter::Error;
|
use interpreter::Error;
|
||||||
use interpreter::env::{self, env_module};
|
use interpreter::env::env_module;
|
||||||
use interpreter::module::{ModuleInstance, ModuleInstanceInterface};
|
use interpreter::module::{ModuleInstance, ModuleInstanceInterface};
|
||||||
|
|
||||||
/// Program instance. Program is a set of instantiated modules.
|
/// Program instance. Program is a set of instantiated modules.
|
||||||
@ -27,24 +26,12 @@ impl ProgramInstance {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create new program instance with predefined user-defined functions
|
|
||||||
pub fn with_functions(funcs: env::UserFunctions) -> Result<Self, Error> {
|
|
||||||
Ok(ProgramInstance {
|
|
||||||
essence: Arc::new(ProgramInstanceEssence::with_functions(funcs)?),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Instantiate module.
|
/// Instantiate module.
|
||||||
pub fn add_module(&self, name: &str, module: Module) -> Result<Arc<ModuleInstance>, Error> {
|
pub fn add_module(&self, name: &str, module: Module) -> Result<Arc<ModuleInstance>, Error> {
|
||||||
let module_instance = Arc::new(ModuleInstance::new(Arc::downgrade(&self.essence), module)?);
|
let module_instance = Arc::new(ModuleInstance::new(Arc::downgrade(&self.essence), module)?);
|
||||||
let mut modules = self.essence.modules.write();
|
// replace existing module with the same name with new one
|
||||||
match modules.entry(name.into()) {
|
self.essence.modules.write().insert(name.into(), module_instance.clone());
|
||||||
Entry::Occupied(_) => Err(Error::Program(format!("module {} already instantiated", name))),
|
Ok(module_instance)
|
||||||
Entry::Vacant(entry) => {
|
|
||||||
entry.insert(module_instance.clone());
|
|
||||||
Ok(module_instance)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get one of the modules by name
|
/// Get one of the modules by name
|
||||||
@ -56,13 +43,8 @@ impl ProgramInstance {
|
|||||||
impl ProgramInstanceEssence {
|
impl ProgramInstanceEssence {
|
||||||
/// Create new program essence.
|
/// Create new program essence.
|
||||||
pub fn new() -> Result<Self, Error> {
|
pub fn new() -> Result<Self, Error> {
|
||||||
ProgramInstanceEssence::with_functions(HashMap::with_capacity(0))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create new program essence with provided user-defined functions
|
|
||||||
pub fn with_functions(funcs: env::UserFunctions) -> Result<Self, Error> {
|
|
||||||
let mut modules = HashMap::new();
|
let mut modules = HashMap::new();
|
||||||
let env_module: Arc<ModuleInstanceInterface> = Arc::new(env_module(funcs)?);
|
let env_module: Arc<ModuleInstanceInterface> = Arc::new(env_module()?);
|
||||||
modules.insert("env".into(), env_module);
|
modules.insert("env".into(), env_module);
|
||||||
Ok(ProgramInstanceEssence {
|
Ok(ProgramInstanceEssence {
|
||||||
modules: RwLock::new(modules),
|
modules: RwLock::new(modules),
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops;
|
use std::ops;
|
||||||
use std::u32;
|
use std::u32;
|
||||||
|
use std::sync::Arc;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
use std::collections::HashMap;
|
||||||
use elements::{Opcode, BlockType, FunctionType};
|
use elements::{Opcode, BlockType, FunctionType};
|
||||||
use interpreter::Error;
|
use interpreter::Error;
|
||||||
use interpreter::module::{ModuleInstance, ModuleInstanceInterface, CallerContext, ItemIndex};
|
use interpreter::module::{ModuleInstance, ModuleInstanceInterface, CallerContext, ItemIndex};
|
||||||
@ -18,17 +20,19 @@ pub struct Interpreter;
|
|||||||
/// Function execution context.
|
/// Function execution context.
|
||||||
pub struct FunctionContext<'a> {
|
pub struct FunctionContext<'a> {
|
||||||
/// Module instance.
|
/// Module instance.
|
||||||
module: &'a ModuleInstance,
|
pub module: &'a ModuleInstance,
|
||||||
|
/// Execution-local external modules.
|
||||||
|
pub externals: &'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>,
|
||||||
/// Function return type.
|
/// Function return type.
|
||||||
return_type: BlockType,
|
pub return_type: BlockType,
|
||||||
/// Local variables.
|
/// Local variables.
|
||||||
locals: Vec<VariableInstance>,
|
pub locals: Vec<VariableInstance>,
|
||||||
/// Values stack.
|
/// Values stack.
|
||||||
value_stack: StackWithLimit<RuntimeValue>,
|
pub value_stack: StackWithLimit<RuntimeValue>,
|
||||||
/// Blocks frames stack.
|
/// Blocks frames stack.
|
||||||
frame_stack: StackWithLimit<BlockFrame>,
|
pub frame_stack: StackWithLimit<BlockFrame>,
|
||||||
/// Current instruction position.
|
/// Current instruction position.
|
||||||
position: usize,
|
pub position: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -868,9 +872,10 @@ impl Interpreter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FunctionContext<'a> {
|
impl<'a> FunctionContext<'a> {
|
||||||
pub fn new(module: &'a ModuleInstance, value_stack_limit: usize, frame_stack_limit: usize, function: &FunctionType, body: &[Opcode], args: Vec<VariableInstance>) -> Result<Self, Error> {
|
pub fn new(module: &'a ModuleInstance, externals: &'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>, value_stack_limit: usize, frame_stack_limit: usize, function: &FunctionType, body: &[Opcode], args: Vec<VariableInstance>) -> Result<Self, Error> {
|
||||||
let mut context = FunctionContext {
|
let mut context = FunctionContext {
|
||||||
module: module,
|
module: module,
|
||||||
|
externals: externals,
|
||||||
return_type: function.return_type().map(|vt| BlockType::Value(vt)).unwrap_or(BlockType::NoResult),
|
return_type: function.return_type().map(|vt| BlockType::Value(vt)).unwrap_or(BlockType::NoResult),
|
||||||
value_stack: StackWithLimit::with_limit(value_stack_limit),
|
value_stack: StackWithLimit::with_limit(value_stack_limit),
|
||||||
frame_stack: StackWithLimit::with_limit(frame_stack_limit),
|
frame_stack: StackWithLimit::with_limit(frame_stack_limit),
|
||||||
@ -888,6 +893,10 @@ impl<'a> FunctionContext<'a> {
|
|||||||
self.module
|
self.module
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn externals(&self) -> &HashMap<String, Arc<ModuleInstanceInterface + 'a>> {
|
||||||
|
&self.externals
|
||||||
|
}
|
||||||
|
|
||||||
pub fn call_function(&mut self, index: u32) -> Result<Option<RuntimeValue>, Error> {
|
pub fn call_function(&mut self, index: u32) -> Result<Option<RuntimeValue>, Error> {
|
||||||
self.module.call_function(CallerContext::nested(self), ItemIndex::IndexSpace(index))
|
self.module.call_function(CallerContext::nested(self), ItemIndex::IndexSpace(index))
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
///! Basic tests for instructions/constructions, missing in wabt tests
|
///! Basic tests for instructions/constructions, missing in wabt tests
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
use builder::module;
|
use builder::module;
|
||||||
use elements::{ExportEntry, Internal, ImportEntry, External, GlobalEntry, GlobalType,
|
use elements::{ExportEntry, Internal, ImportEntry, External, GlobalEntry, GlobalType,
|
||||||
InitExpr, ValueType, Opcodes, Opcode};
|
InitExpr, ValueType, Opcodes, Opcode};
|
||||||
use interpreter::Error;
|
use interpreter::Error;
|
||||||
use interpreter::module::{ModuleInstanceInterface, CallerContext};
|
use interpreter::env_native::{env_native_module, UserFunction, UserFunctions, UserFunctionExecutor};
|
||||||
|
use interpreter::memory::MemoryInstance;
|
||||||
|
use interpreter::module::{ModuleInstanceInterface, CallerContext, ItemIndex, ExecutionParams};
|
||||||
use interpreter::program::ProgramInstance;
|
use interpreter::program::ProgramInstance;
|
||||||
use interpreter::value::RuntimeValue;
|
use interpreter::value::RuntimeValue;
|
||||||
|
|
||||||
@ -38,8 +41,8 @@ fn import_function() {
|
|||||||
let external_module = program.add_module("external_module", module1).unwrap();
|
let external_module = program.add_module("external_module", module1).unwrap();
|
||||||
let main_module = program.add_module("main", module2).unwrap();
|
let main_module = program.add_module("main", module2).unwrap();
|
||||||
|
|
||||||
assert_eq!(external_module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::I32(3));
|
assert_eq!(external_module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(3));
|
||||||
assert_eq!(main_module.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(10));
|
assert_eq!(main_module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(10));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -72,7 +75,7 @@ fn wrong_import() {
|
|||||||
let _side_module_instance = program.add_module("side_module", side_module).unwrap();
|
let _side_module_instance = program.add_module("side_module", side_module).unwrap();
|
||||||
let module_instance = program.add_module("main", module).unwrap();
|
let module_instance = program.add_module("main", module).unwrap();
|
||||||
|
|
||||||
assert!(module_instance.execute_index(1, vec![]).is_err());
|
assert!(module_instance.execute_index(1, vec![].into()).is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -115,112 +118,102 @@ fn global_get_set() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::I32(50));
|
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(50));
|
||||||
assert_eq!(module.execute_index(1, vec![]).unwrap_err(), Error::Variable("trying to update immutable variable".into()));
|
assert_eq!(module.execute_index(1, vec![].into()).unwrap_err(), Error::Variable("trying to update immutable variable".into()));
|
||||||
assert_eq!(module.execute_index(2, vec![]).unwrap_err(), Error::Variable("trying to update variable of type I32 with value of type Some(I64)".into()));
|
assert_eq!(module.execute_index(2, vec![].into()).unwrap_err(), Error::Variable("trying to update variable of type I32 with value of type Some(I64)".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn with_user_functions() {
|
fn single_program_different_modules() {
|
||||||
use interpreter::{UserFunction, UserFunctions, ModuleInstance};
|
// user function executor
|
||||||
|
struct FunctionExecutor {
|
||||||
|
pub memory: Arc<MemoryInstance>,
|
||||||
|
pub values: Vec<i32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UserFunctionExecutor for FunctionExecutor {
|
||||||
|
fn execute(&mut self, name: &str, context: CallerContext) -> Result<Option<RuntimeValue>, Error> {
|
||||||
|
match name {
|
||||||
|
"add" => {
|
||||||
|
let memory_value = self.memory.get(0, 1).unwrap()[0];
|
||||||
|
let fn_argument = context.value_stack.pop_as::<u32>().unwrap() as u8;
|
||||||
|
let sum = memory_value + fn_argument;
|
||||||
|
self.memory.set(0, &vec![sum]).unwrap();
|
||||||
|
self.values.push(sum as i32);
|
||||||
|
Ok(Some(RuntimeValue::I32(sum as i32)))
|
||||||
|
},
|
||||||
|
"sub" => {
|
||||||
|
let memory_value = self.memory.get(0, 1).unwrap()[0];
|
||||||
|
let fn_argument = context.value_stack.pop_as::<u32>().unwrap() as u8;
|
||||||
|
let diff = memory_value - fn_argument;
|
||||||
|
self.memory.set(0, &vec![diff]).unwrap();
|
||||||
|
self.values.push(diff as i32);
|
||||||
|
Ok(Some(RuntimeValue::I32(diff as i32)))
|
||||||
|
},
|
||||||
|
_ => Err(Error::Trap("not implemented".into())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// create new program
|
||||||
|
let program = ProgramInstance::new().unwrap();
|
||||||
|
// => env module is created
|
||||||
|
let env_instance = program.module("env").unwrap();
|
||||||
|
// => linear memory is created
|
||||||
|
let env_memory = env_instance.memory(ItemIndex::Internal(0)).unwrap();
|
||||||
|
|
||||||
let module = module()
|
let module = module()
|
||||||
.with_import(ImportEntry::new("env".into(), "custom_alloc".into(), External::Function(0)))
|
.with_import(ImportEntry::new("env".into(), "add".into(), External::Function(0)))
|
||||||
.with_import(ImportEntry::new("env".into(), "custom_increment".into(), External::Function(0)))
|
.with_import(ImportEntry::new("env".into(), "sub".into(), External::Function(0)))
|
||||||
.function()
|
.function()
|
||||||
.signature().return_type().i32().build()
|
.signature().param().i32().return_type().i32().build()
|
||||||
.body().with_opcodes(Opcodes::new(vec![
|
.body().with_opcodes(Opcodes::new(vec![
|
||||||
Opcode::I32Const(32),
|
Opcode::GetLocal(0),
|
||||||
Opcode::Call(0),
|
Opcode::Call(0),
|
||||||
Opcode::End,
|
Opcode::End,
|
||||||
])).build()
|
])).build()
|
||||||
.build()
|
.build()
|
||||||
|
.function()
|
||||||
|
.signature().param().i32().return_type().i32().build()
|
||||||
|
.body().with_opcodes(Opcodes::new(vec![
|
||||||
|
Opcode::GetLocal(0),
|
||||||
|
Opcode::Call(1),
|
||||||
|
Opcode::End,
|
||||||
|
])).build()
|
||||||
|
.build()
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let mut top = 0i32;
|
// load module
|
||||||
let mut user_functions = UserFunctions::new();
|
let module_instance = program.add_module("main", module).unwrap();
|
||||||
user_functions.insert(
|
|
||||||
"custom_alloc".to_owned(),
|
|
||||||
UserFunction {
|
|
||||||
params: vec![ValueType::I32],
|
|
||||||
result: Some(ValueType::I32),
|
|
||||||
closure: Box::new(move |_module: &ModuleInstance, context: CallerContext| {
|
|
||||||
let prev = top;
|
|
||||||
top = top + context.value_stack.pop_as::<i32>()?;
|
|
||||||
Ok(Some(prev.into()))
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut rolling = 9999i32;
|
let mut executor = FunctionExecutor {
|
||||||
user_functions.insert(
|
memory: env_memory.clone(),
|
||||||
"custom_increment".to_owned(),
|
values: Vec::new(),
|
||||||
UserFunction {
|
};
|
||||||
params: vec![ValueType::I32],
|
{
|
||||||
result: Some(ValueType::I32),
|
// create native env module with native add && sub implementations
|
||||||
closure: Box::new(move |_module: &ModuleInstance, _context: CallerContext| {
|
let functions: UserFunctions = UserFunctions {
|
||||||
rolling = rolling + 1;
|
executor: &mut executor,
|
||||||
Ok(Some(rolling.into()))
|
functions: vec![UserFunction {
|
||||||
}),
|
name: "add".into(),
|
||||||
}
|
params: vec![ValueType::I32],
|
||||||
);
|
result: Some(ValueType::I32),
|
||||||
|
}, UserFunction {
|
||||||
|
name: "sub".into(),
|
||||||
|
params: vec![ValueType::I32],
|
||||||
|
result: Some(ValueType::I32),
|
||||||
|
}],
|
||||||
|
};
|
||||||
|
let native_env_instance = Arc::new(env_native_module(env_instance, functions).unwrap());
|
||||||
|
|
||||||
let program = ProgramInstance::with_functions(user_functions).unwrap();
|
// execute functions
|
||||||
let module_instance = program.add_module("main", module).unwrap();
|
let params = ExecutionParams::with_external("env".into(), native_env_instance);
|
||||||
|
|
||||||
// internal function using first import
|
assert_eq!(module_instance.execute_index(2, params.clone().add_argument(RuntimeValue::I32(7))).unwrap().unwrap(), RuntimeValue::I32(7));
|
||||||
assert_eq!(module_instance.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module_instance.execute_index(2, params.clone().add_argument(RuntimeValue::I32(50))).unwrap().unwrap(), RuntimeValue::I32(57));
|
||||||
assert_eq!(module_instance.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(32));
|
assert_eq!(module_instance.execute_index(3, params.clone().add_argument(RuntimeValue::I32(15))).unwrap().unwrap(), RuntimeValue::I32(42));
|
||||||
assert_eq!(module_instance.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(64));
|
}
|
||||||
|
|
||||||
// second import
|
assert_eq!(executor.memory.get(0, 1).unwrap()[0], 42);
|
||||||
assert_eq!(module_instance.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(10000));
|
assert_eq!(executor.values, vec![7, 57, 42]);
|
||||||
assert_eq!(module_instance.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(10001));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn with_user_functions_extended() {
|
|
||||||
use interpreter::{UserFunction, UserFunctions, UserFunctionInterface, ModuleInstance};
|
|
||||||
|
|
||||||
struct UserMAlloc {
|
|
||||||
top: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UserFunctionInterface for UserMAlloc {
|
|
||||||
fn call(&mut self, _module: &ModuleInstance, context: CallerContext) -> Result<Option<RuntimeValue>, Error> {
|
|
||||||
let prev = self.top;
|
|
||||||
self.top += context.value_stack.pop_as::<i32>()?;
|
|
||||||
Ok(Some(prev.into()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let module = module()
|
|
||||||
.with_import(ImportEntry::new("env".into(), "_malloc".into(), External::Function(0)))
|
|
||||||
.function()
|
|
||||||
.signature().return_type().i32().build()
|
|
||||||
.body().with_opcodes(Opcodes::new(vec![
|
|
||||||
Opcode::I32Const(32),
|
|
||||||
Opcode::Call(0),
|
|
||||||
Opcode::End,
|
|
||||||
])).build()
|
|
||||||
.build()
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let mut user_functions = UserFunctions::new();
|
|
||||||
user_functions.insert(
|
|
||||||
"_malloc".to_owned(),
|
|
||||||
UserFunction {
|
|
||||||
params: vec![ValueType::I32],
|
|
||||||
result: Some(ValueType::I32),
|
|
||||||
closure: Box::new(UserMAlloc { top: 0 }),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
let program = ProgramInstance::with_functions(user_functions).unwrap();
|
|
||||||
let module_instance = program.add_module("main", module).unwrap();
|
|
||||||
|
|
||||||
// internal function using first import
|
|
||||||
assert_eq!(module_instance.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
|
||||||
assert_eq!(module_instance.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(32));
|
|
||||||
assert_eq!(module_instance.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(64));
|
|
||||||
}
|
|
@ -1,6 +1,7 @@
|
|||||||
///! Tests from https://github.com/WebAssembly/wabt/tree/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp
|
///! Tests from https://github.com/WebAssembly/wabt/tree/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp
|
||||||
|
|
||||||
use std::sync::Weak;
|
use std::sync::Weak;
|
||||||
|
use std::collections::HashMap;
|
||||||
use builder::module;
|
use builder::module;
|
||||||
use elements::{Module, ValueType, Opcodes, Opcode, BlockType, FunctionType};
|
use elements::{Module, ValueType, Opcodes, Opcode, BlockType, FunctionType};
|
||||||
use interpreter::Error;
|
use interpreter::Error;
|
||||||
@ -13,7 +14,8 @@ use interpreter::variable::{VariableInstance, VariableType};
|
|||||||
fn run_function_i32(body: &Opcodes, arg: i32) -> Result<i32, Error> {
|
fn run_function_i32(body: &Opcodes, arg: i32) -> Result<i32, Error> {
|
||||||
let ftype = FunctionType::new(vec![ValueType::I32], Some(ValueType::I32));
|
let ftype = FunctionType::new(vec![ValueType::I32], Some(ValueType::I32));
|
||||||
let module = ModuleInstance::new(Weak::default(), Module::default()).unwrap();
|
let module = ModuleInstance::new(Weak::default(), Module::default()).unwrap();
|
||||||
let mut context = FunctionContext::new(&module, 1024, 1024, &ftype, body.elements(), vec![
|
let externals = HashMap::new();
|
||||||
|
let mut context = FunctionContext::new(&module, &externals, 1024, 1024, &ftype, body.elements(), vec![
|
||||||
VariableInstance::new(true, VariableType::I32, RuntimeValue::I32(arg)).unwrap(), // arg
|
VariableInstance::new(true, VariableType::I32, RuntimeValue::I32(arg)).unwrap(), // arg
|
||||||
VariableInstance::new(true, VariableType::I32, RuntimeValue::I32(0)).unwrap(), // local1
|
VariableInstance::new(true, VariableType::I32, RuntimeValue::I32(0)).unwrap(), // local1
|
||||||
VariableInstance::new(true, VariableType::I32, RuntimeValue::I32(0)).unwrap(), // local2
|
VariableInstance::new(true, VariableType::I32, RuntimeValue::I32(0)).unwrap(), // local2
|
||||||
@ -522,11 +524,11 @@ fn return_void() {
|
|||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
|
|
||||||
module.execute_main(vec![RuntimeValue::I32(0)]).unwrap();
|
module.execute_main(vec![RuntimeValue::I32(0)].into()).unwrap();
|
||||||
let memory = module.memory(ItemIndex::IndexSpace(0)).unwrap();
|
let memory = module.memory(ItemIndex::IndexSpace(0)).unwrap();
|
||||||
assert_eq!(memory.get(0, 4).unwrap(), vec![0, 0, 0, 0]);
|
assert_eq!(memory.get(0, 4).unwrap(), vec![0, 0, 0, 0]);
|
||||||
|
|
||||||
module.execute_main(vec![RuntimeValue::I32(1)]).unwrap();
|
module.execute_main(vec![RuntimeValue::I32(1)].into()).unwrap();
|
||||||
let memory = module.memory(ItemIndex::IndexSpace(0)).unwrap();
|
let memory = module.memory(ItemIndex::IndexSpace(0)).unwrap();
|
||||||
assert_eq!(memory.get(0, 4).unwrap(), vec![1, 0, 0, 0]);
|
assert_eq!(memory.get(0, 4).unwrap(), vec![1, 0, 0, 0]);
|
||||||
}
|
}
|
||||||
@ -580,7 +582,7 @@ fn call_1() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_main(vec![]).unwrap().unwrap(), RuntimeValue::I32(10));
|
assert_eq!(module.execute_main(vec![].into()).unwrap().unwrap(), RuntimeValue::I32(10));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/call.txt#L23
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/call.txt#L23
|
||||||
@ -629,7 +631,7 @@ fn call_2() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_main(vec![]).unwrap().unwrap(), RuntimeValue::I32(3628800));
|
assert_eq!(module.execute_main(vec![].into()).unwrap().unwrap(), RuntimeValue::I32(3628800));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/call-zero-args.txt
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/call-zero-args.txt
|
||||||
@ -674,7 +676,7 @@ fn call_zero_args() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_main(vec![]).unwrap().unwrap(), RuntimeValue::I32(43));
|
assert_eq!(module.execute_main(vec![].into()).unwrap().unwrap(), RuntimeValue::I32(43));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/callindirect.txt#L31
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/callindirect.txt#L31
|
||||||
@ -720,8 +722,8 @@ fn callindirect_1() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_main(vec![RuntimeValue::I32(0)]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_main(vec![RuntimeValue::I32(0)].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_main(vec![RuntimeValue::I32(1)]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_main(vec![RuntimeValue::I32(1)].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/callindirect.txt#L39
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/callindirect.txt#L39
|
||||||
@ -793,11 +795,11 @@ fn callindirect_2() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_main(vec![RuntimeValue::I32(10), RuntimeValue::I32(4), RuntimeValue::I32(0)]).unwrap().unwrap(), RuntimeValue::I32(14));
|
assert_eq!(module.execute_main(vec![RuntimeValue::I32(10), RuntimeValue::I32(4), RuntimeValue::I32(0)].into()).unwrap().unwrap(), RuntimeValue::I32(14));
|
||||||
assert_eq!(module.execute_main(vec![RuntimeValue::I32(10), RuntimeValue::I32(4), RuntimeValue::I32(1)]).unwrap().unwrap(), RuntimeValue::I32(6));
|
assert_eq!(module.execute_main(vec![RuntimeValue::I32(10), RuntimeValue::I32(4), RuntimeValue::I32(1)].into()).unwrap().unwrap(), RuntimeValue::I32(6));
|
||||||
assert_eq!(module.execute_main(vec![RuntimeValue::I32(10), RuntimeValue::I32(4), RuntimeValue::I32(2)]).unwrap_err(),
|
assert_eq!(module.execute_main(vec![RuntimeValue::I32(10), RuntimeValue::I32(4), RuntimeValue::I32(2)].into()).unwrap_err(),
|
||||||
Error::Function("expected function with signature ([I32, I32]) -> Some(I32) when got with ([I32]) -> Some(I32)".into()));
|
Error::Function("expected function with signature ([I32, I32]) -> Some(I32) when got with ([I32]) -> Some(I32)".into()));
|
||||||
assert_eq!(module.execute_main(vec![RuntimeValue::I32(10), RuntimeValue::I32(4), RuntimeValue::I32(3)]).unwrap_err(),
|
assert_eq!(module.execute_main(vec![RuntimeValue::I32(10), RuntimeValue::I32(4), RuntimeValue::I32(3)].into()).unwrap_err(),
|
||||||
Error::Table("trying to read table item with index 3 when there are only 3 items".into()));
|
Error::Table("trying to read table item with index 3 when there are only 3 items".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -861,14 +863,14 @@ fn select() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_index(0, vec![RuntimeValue::I32(0)]).unwrap().unwrap(), RuntimeValue::I32(2));
|
assert_eq!(module.execute_index(0, vec![RuntimeValue::I32(0)].into()).unwrap().unwrap(), RuntimeValue::I32(2));
|
||||||
assert_eq!(module.execute_index(0, vec![RuntimeValue::I32(1)]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(0, vec![RuntimeValue::I32(1)].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(1, vec![RuntimeValue::I32(0)]).unwrap().unwrap(), RuntimeValue::I64(2));
|
assert_eq!(module.execute_index(1, vec![RuntimeValue::I32(0)].into()).unwrap().unwrap(), RuntimeValue::I64(2));
|
||||||
assert_eq!(module.execute_index(1, vec![RuntimeValue::I32(1)]).unwrap().unwrap(), RuntimeValue::I64(1));
|
assert_eq!(module.execute_index(1, vec![RuntimeValue::I32(1)].into()).unwrap().unwrap(), RuntimeValue::I64(1));
|
||||||
assert_eq!(module.execute_index(2, vec![RuntimeValue::I32(0)]).unwrap().unwrap(), RuntimeValue::F32(2f32));
|
assert_eq!(module.execute_index(2, vec![RuntimeValue::I32(0)].into()).unwrap().unwrap(), RuntimeValue::F32(2f32));
|
||||||
assert_eq!(module.execute_index(2, vec![RuntimeValue::I32(1)]).unwrap().unwrap(), RuntimeValue::F32(1f32));
|
assert_eq!(module.execute_index(2, vec![RuntimeValue::I32(1)].into()).unwrap().unwrap(), RuntimeValue::F32(1f32));
|
||||||
assert_eq!(module.execute_index(3, vec![RuntimeValue::I32(0)]).unwrap().unwrap(), RuntimeValue::F64(2f64));
|
assert_eq!(module.execute_index(3, vec![RuntimeValue::I32(0)].into()).unwrap().unwrap(), RuntimeValue::F64(2f64));
|
||||||
assert_eq!(module.execute_index(3, vec![RuntimeValue::I32(1)]).unwrap().unwrap(), RuntimeValue::F64(1f64));
|
assert_eq!(module.execute_index(3, vec![RuntimeValue::I32(1)].into()).unwrap().unwrap(), RuntimeValue::F64(1f64));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/binary.txt#L3
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/binary.txt#L3
|
||||||
@ -1014,21 +1016,21 @@ fn binary_i32() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::I32(3));
|
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(3));
|
||||||
assert_eq!(module.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(16));
|
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(16));
|
||||||
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(21));
|
assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(21));
|
||||||
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(-2)); // 4294967294
|
assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-2)); // 4294967294
|
||||||
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I32(2147483646));
|
assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(2147483646));
|
||||||
assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::I32(-1)); // 4294967295
|
assert_eq!(module.execute_index(5, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1)); // 4294967295
|
||||||
assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(6, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(7, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(7, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(8, vec![]).unwrap().unwrap(), RuntimeValue::I32(15));
|
assert_eq!(module.execute_index(8, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(15));
|
||||||
assert_eq!(module.execute_index(9, vec![]).unwrap().unwrap(), RuntimeValue::I32(14));
|
assert_eq!(module.execute_index(9, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(14));
|
||||||
assert_eq!(module.execute_index(10, vec![]).unwrap().unwrap(), RuntimeValue::I32(-800)); // 4294966496
|
assert_eq!(module.execute_index(10, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-800)); // 4294966496
|
||||||
assert_eq!(module.execute_index(11, vec![]).unwrap().unwrap(), RuntimeValue::I32(536870899));
|
assert_eq!(module.execute_index(11, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(536870899));
|
||||||
assert_eq!(module.execute_index(12, vec![]).unwrap().unwrap(), RuntimeValue::I32(-13)); // 4294967283
|
assert_eq!(module.execute_index(12, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-13)); // 4294967283
|
||||||
assert_eq!(module.execute_index(13, vec![]).unwrap().unwrap(), RuntimeValue::I32(-793)); // 4294966503
|
assert_eq!(module.execute_index(13, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-793)); // 4294966503
|
||||||
assert_eq!(module.execute_index(14, vec![]).unwrap().unwrap(), RuntimeValue::I32(-1610612749)); // 2684354547
|
assert_eq!(module.execute_index(14, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1610612749)); // 2684354547
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/binary.txt#L65
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/binary.txt#L65
|
||||||
@ -1174,21 +1176,21 @@ fn binary_i64() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::I64(3));
|
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(3));
|
||||||
assert_eq!(module.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I64(16));
|
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(16));
|
||||||
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I64(21));
|
assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(21));
|
||||||
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I64(-2)); // 18446744073709551614
|
assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-2)); // 18446744073709551614
|
||||||
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I64(9223372036854775806));
|
assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(9223372036854775806));
|
||||||
assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::I64(-1)); // 18446744073709551615
|
assert_eq!(module.execute_index(5, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-1)); // 18446744073709551615
|
||||||
assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::I64(1));
|
assert_eq!(module.execute_index(6, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(1));
|
||||||
assert_eq!(module.execute_index(7, vec![]).unwrap().unwrap(), RuntimeValue::I64(1));
|
assert_eq!(module.execute_index(7, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(1));
|
||||||
assert_eq!(module.execute_index(8, vec![]).unwrap().unwrap(), RuntimeValue::I64(15));
|
assert_eq!(module.execute_index(8, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(15));
|
||||||
assert_eq!(module.execute_index(9, vec![]).unwrap().unwrap(), RuntimeValue::I64(14));
|
assert_eq!(module.execute_index(9, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(14));
|
||||||
assert_eq!(module.execute_index(10, vec![]).unwrap().unwrap(), RuntimeValue::I64(-800)); // 18446744073709550816
|
assert_eq!(module.execute_index(10, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-800)); // 18446744073709550816
|
||||||
assert_eq!(module.execute_index(11, vec![]).unwrap().unwrap(), RuntimeValue::I64(2305843009213693939));
|
assert_eq!(module.execute_index(11, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(2305843009213693939));
|
||||||
assert_eq!(module.execute_index(12, vec![]).unwrap().unwrap(), RuntimeValue::I64(-13)); // 18446744073709551603
|
assert_eq!(module.execute_index(12, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-13)); // 18446744073709551603
|
||||||
assert_eq!(module.execute_index(13, vec![]).unwrap().unwrap(), RuntimeValue::I64(-793)); // 18446744073709550823
|
assert_eq!(module.execute_index(13, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-793)); // 18446744073709550823
|
||||||
assert_eq!(module.execute_index(14, vec![]).unwrap().unwrap(), RuntimeValue::I64(-6917529027641081869)); // 11529215046068469747
|
assert_eq!(module.execute_index(14, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-6917529027641081869)); // 11529215046068469747
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/binary.txt#L3
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/binary.txt#L3
|
||||||
@ -1264,13 +1266,13 @@ fn binary_f32() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::F32(5.000000));
|
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(5.000000));
|
||||||
assert_eq!(module.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::F32(-9995.500000));
|
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(-9995.500000));
|
||||||
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::F32(-8487.187500));
|
assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(-8487.187500));
|
||||||
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::F32(-500000000.000000));
|
assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(-500000000.000000));
|
||||||
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::F32(0.000000));
|
assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(0.000000));
|
||||||
assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::F32(0.000000));
|
assert_eq!(module.execute_index(5, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(0.000000));
|
||||||
assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::F32(0.000000));
|
assert_eq!(module.execute_index(6, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(0.000000));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/binary.txt#L157
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/binary.txt#L157
|
||||||
@ -1346,15 +1348,15 @@ fn binary_f64() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::F64(1111111110.000000));
|
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(1111111110.000000));
|
||||||
assert_eq!(module.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::F64(123400000000000007812762268812638756607430593436581896388608.000000));
|
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(123400000000000007812762268812638756607430593436581896388608.000000));
|
||||||
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::F64(-15179717820000.000000));
|
assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(-15179717820000.000000));
|
||||||
// in wabt result is 99999999999999998083559617243737459057312001403031879309116481015410011220367858297629826861622
|
// in wabt result is 99999999999999998083559617243737459057312001403031879309116481015410011220367858297629826861622
|
||||||
// but the actual (and correct) result is 1e150
|
// but the actual (and correct) result is 1e150
|
||||||
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::F64(1e150));
|
assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(1e150));
|
||||||
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::F64(0.000000));
|
assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(0.000000));
|
||||||
assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::F64(0.000000));
|
assert_eq!(module.execute_index(5, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(0.000000));
|
||||||
assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::F64(0.000000));
|
assert_eq!(module.execute_index(6, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(0.000000));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/cast.txt
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/cast.txt
|
||||||
@ -1399,10 +1401,10 @@ fn cast() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::F32(4.5));
|
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(4.5));
|
||||||
assert_eq!(module.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(-1067450368)); // 3227516928
|
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1067450368)); // 3227516928
|
||||||
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::F64(125.125000));
|
assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(125.125000));
|
||||||
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I64(4758506566875873280));
|
assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(4758506566875873280));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/compare.txt#L3
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/compare.txt#L3
|
||||||
@ -1665,34 +1667,34 @@ fn compare_i32() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(5, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(6, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(7, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(7, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(8, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(8, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(9, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(9, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(10, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(10, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(11, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(11, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(12, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(12, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(13, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(13, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(14, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(14, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(15, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(15, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(16, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(16, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(17, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(17, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(18, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(18, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(19, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(19, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(20, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(20, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(21, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(21, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(22, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(22, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(23, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(23, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(24, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(24, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(25, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(25, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(26, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(26, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(27, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(27, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/compare.txt#L123
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/compare.txt#L123
|
||||||
@ -1955,34 +1957,34 @@ fn compare_i64() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(5, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(6, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(7, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(7, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(8, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(8, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(9, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(9, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(10, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(10, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(11, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(11, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(12, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(12, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(13, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(13, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(14, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(14, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(15, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(15, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(16, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(16, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(17, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(17, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(18, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(18, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(19, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(19, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(20, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(20, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(21, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(21, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(22, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(22, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(23, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(23, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(24, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(24, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(25, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(25, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(26, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(26, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(27, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(27, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/compare.txt#L246
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/compare.txt#L246
|
||||||
@ -2139,22 +2141,22 @@ fn compare_f32() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(5, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(6, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(7, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(7, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(8, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(8, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(9, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(9, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(10, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(10, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(11, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(11, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(12, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(12, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(13, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(13, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(14, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(14, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(15, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(15, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/compare.txt#L317
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/compare.txt#L317
|
||||||
@ -2311,22 +2313,22 @@ fn compare_f64() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(5, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(6, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(7, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(7, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(8, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(8, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(9, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(9, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(10, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(10, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(11, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(11, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(12, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(12, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(13, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(13, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(14, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(14, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(15, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(15, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/convert.txt#L3
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/convert.txt#L3
|
||||||
@ -2379,11 +2381,11 @@ fn convert_i32() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::I32(-1)); // 4294967295
|
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1)); // 4294967295
|
||||||
assert_eq!(module.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(-100)); // 4294967196
|
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-100)); // 4294967196
|
||||||
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(-1294967296)); // 3000000000
|
assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1294967296)); // 3000000000
|
||||||
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(-100)); // 4294967196
|
assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-100)); // 4294967196
|
||||||
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I32(-1294967296)); // 3000000000
|
assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1294967296)); // 3000000000
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/convert.txt#L21
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/convert.txt#L21
|
||||||
@ -2452,12 +2454,12 @@ fn convert_i64() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::I64(4294967295));
|
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(4294967295));
|
||||||
assert_eq!(module.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I64(-1)); // 18446744073709551615
|
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-1)); // 18446744073709551615
|
||||||
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(5, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/convert.txt#L50
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/convert.txt#L50
|
||||||
@ -2510,11 +2512,11 @@ fn convert_f32() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::F32(-1.000000));
|
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(-1.000000));
|
||||||
assert_eq!(module.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::F32(4294967296.000000));
|
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(4294967296.000000));
|
||||||
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::F32(12345679.000000));
|
assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(12345679.000000));
|
||||||
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::F32(0.000000));
|
assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(0.000000));
|
||||||
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::F32(0.000000));
|
assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(0.000000));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/convert.txt#L50
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/convert.txt#L50
|
||||||
@ -2567,11 +2569,11 @@ fn convert_f64() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::F64(-1.000000));
|
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(-1.000000));
|
||||||
assert_eq!(module.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::F64(4294967295.000000));
|
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(4294967295.000000));
|
||||||
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::F64(12345679.000000));
|
assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(12345679.000000));
|
||||||
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::F64(0.000000));
|
assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(0.000000));
|
||||||
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::F64(0.000000));
|
assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(0.000000));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/load.txt#L9
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/load.txt#L9
|
||||||
@ -2627,11 +2629,11 @@ fn load_i32() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::I32(-1));
|
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1));
|
||||||
assert_eq!(module.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(-1));
|
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1));
|
||||||
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(-1));
|
assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1));
|
||||||
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(255));
|
assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(255));
|
||||||
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I32(65535));
|
assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(65535));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/load.txt#L26
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/load.txt#L26
|
||||||
@ -2703,13 +2705,13 @@ fn load_i64() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::I64(-1));
|
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-1));
|
||||||
assert_eq!(module.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I64(-1));
|
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-1));
|
||||||
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I64(-1));
|
assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-1));
|
||||||
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I64(-1));
|
assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-1));
|
||||||
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I64(255));
|
assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(255));
|
||||||
assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::I64(65535));
|
assert_eq!(module.execute_index(5, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(65535));
|
||||||
assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::I64(4294967295));
|
assert_eq!(module.execute_index(6, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(4294967295));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/load.txt#L50
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/load.txt#L50
|
||||||
@ -2733,7 +2735,7 @@ fn load_f32() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::F32(25.750000));
|
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(25.750000));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/load.txt#L54
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/load.txt#L54
|
||||||
@ -2757,7 +2759,7 @@ fn load_f64() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::F64(1023.875000));
|
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(1023.875000));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/store.txt#L5
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/store.txt#L5
|
||||||
@ -2814,9 +2816,9 @@ fn store_i32() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::I32(-16909061));
|
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-16909061));
|
||||||
assert_eq!(module.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(-859059511));
|
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-859059511));
|
||||||
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(-123456));
|
assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-123456));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/store.txt#L38
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/store.txt#L38
|
||||||
@ -2884,10 +2886,10 @@ fn store_i64() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::I64(4278058235));
|
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(4278058235));
|
||||||
assert_eq!(module.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I64(3435907785));
|
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(3435907785));
|
||||||
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I64(4294843840));
|
assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(4294843840));
|
||||||
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I64(-4981613551475109875));
|
assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(-4981613551475109875));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/store.txt#L78
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/store.txt#L78
|
||||||
@ -2912,7 +2914,7 @@ fn store_f32() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::I32(1069547520));
|
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1069547520));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/store.txt#L85
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/store.txt#L85
|
||||||
@ -2937,7 +2939,7 @@ fn store_f64() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::I32(-1064352256));
|
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(-1064352256));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/unary.txt#L12
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/unary.txt#L12
|
||||||
@ -2988,11 +2990,11 @@ fn unary_i32() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I32(24));
|
assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(24));
|
||||||
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(7));
|
assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(7));
|
||||||
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/unary.txt#L29
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/unary.txt#L29
|
||||||
@ -3043,11 +3045,11 @@ fn unary_i64() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_index(0, vec![]).unwrap().unwrap(), RuntimeValue::I32(0));
|
assert_eq!(module.execute_index(0, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(0));
|
||||||
assert_eq!(module.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::I64(56));
|
assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(56));
|
||||||
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I64(7));
|
assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(7));
|
||||||
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::I64(1));
|
assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::I64(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/unary.txt#L46
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/unary.txt#L46
|
||||||
@ -3142,15 +3144,15 @@ fn unary_f32() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::F32(-100.000000));
|
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(-100.000000));
|
||||||
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::F32(100.000000));
|
assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(100.000000));
|
||||||
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::F32(10.000000));
|
assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(10.000000));
|
||||||
assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::F32(-0.000000));
|
assert_eq!(module.execute_index(5, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(-0.000000));
|
||||||
assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::F32(-1.000000));
|
assert_eq!(module.execute_index(6, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(-1.000000));
|
||||||
assert_eq!(module.execute_index(7, vec![]).unwrap().unwrap(), RuntimeValue::F32(-0.000000));
|
assert_eq!(module.execute_index(7, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(-0.000000));
|
||||||
assert_eq!(module.execute_index(8, vec![]).unwrap().unwrap(), RuntimeValue::F32(1.000000));
|
assert_eq!(module.execute_index(8, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(1.000000));
|
||||||
assert_eq!(module.execute_index(9, vec![]).unwrap().unwrap(), RuntimeValue::F32(2.000000));
|
assert_eq!(module.execute_index(9, vec![].into()).unwrap().unwrap(), RuntimeValue::F32(2.000000));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/unary.txt#L76
|
/// https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/unary.txt#L76
|
||||||
@ -3245,13 +3247,13 @@ fn unary_f64() {
|
|||||||
|
|
||||||
let program = ProgramInstance::new().unwrap();
|
let program = ProgramInstance::new().unwrap();
|
||||||
let module = program.add_module("main", module).unwrap();
|
let module = program.add_module("main", module).unwrap();
|
||||||
assert_eq!(module.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::F64(-100.000000));
|
assert_eq!(module.execute_index(1, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(-100.000000));
|
||||||
assert_eq!(module.execute_index(2, vec![]).unwrap().unwrap(), RuntimeValue::F64(100.000000));
|
assert_eq!(module.execute_index(2, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(100.000000));
|
||||||
assert_eq!(module.execute_index(3, vec![]).unwrap().unwrap(), RuntimeValue::I32(1));
|
assert_eq!(module.execute_index(3, vec![].into()).unwrap().unwrap(), RuntimeValue::I32(1));
|
||||||
assert_eq!(module.execute_index(4, vec![]).unwrap().unwrap(), RuntimeValue::F64(10.000000));
|
assert_eq!(module.execute_index(4, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(10.000000));
|
||||||
assert_eq!(module.execute_index(5, vec![]).unwrap().unwrap(), RuntimeValue::F64(-0.000000));
|
assert_eq!(module.execute_index(5, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(-0.000000));
|
||||||
assert_eq!(module.execute_index(6, vec![]).unwrap().unwrap(), RuntimeValue::F64(-1.000000));
|
assert_eq!(module.execute_index(6, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(-1.000000));
|
||||||
assert_eq!(module.execute_index(7, vec![]).unwrap().unwrap(), RuntimeValue::F64(-0.000000));
|
assert_eq!(module.execute_index(7, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(-0.000000));
|
||||||
assert_eq!(module.execute_index(8, vec![]).unwrap().unwrap(), RuntimeValue::F64(1.000000));
|
assert_eq!(module.execute_index(8, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(1.000000));
|
||||||
assert_eq!(module.execute_index(9, vec![]).unwrap().unwrap(), RuntimeValue::F64(2.000000));
|
assert_eq!(module.execute_index(9, vec![].into()).unwrap().unwrap(), RuntimeValue::F64(2.000000));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user