rewire everything

This commit is contained in:
NikVolf 2018-01-23 14:26:45 +03:00
parent 559d529ece
commit 4eb8608c1e
5 changed files with 41 additions and 25 deletions

View File

@ -6,8 +6,9 @@ use std::fmt;
use std::fs::File; use std::fs::File;
use wasmi::{ use wasmi::{
Error as InterpreterError, ModuleInstance, ModuleRef, Error as InterpreterError, ModuleInstance, ModuleRef,
Externals, RuntimeValue, FuncRef, TryInto, ModuleImportResolver, Externals, RuntimeValue, FuncRef, ModuleImportResolver,
FuncInstance, HostError, ImportsBuilder, Signature, ValueType, FuncInstance, HostError, ImportsBuilder, Signature, ValueType,
RuntimeArgs,
}; };
#[derive(Debug)] #[derive(Debug)]
@ -147,16 +148,16 @@ impl<'a> Externals for Runtime<'a> {
fn invoke_index( fn invoke_index(
&mut self, &mut self,
index: usize, index: usize,
args: &[RuntimeValue], args: RuntimeArgs,
) -> Result<Option<RuntimeValue>, InterpreterError> { ) -> Result<Option<RuntimeValue>, InterpreterError> {
match index { match index {
SET_FUNC_INDEX => { SET_FUNC_INDEX => {
let idx: i32 = args[0].try_into().unwrap(); let idx: i32 = args.nth(0)?;
self.game.set(idx, self.player)?; self.game.set(idx, self.player)?;
Ok(None) Ok(None)
} }
GET_FUNC_INDEX => { GET_FUNC_INDEX => {
let idx: i32 = args[0].try_into().unwrap(); let idx: i32 = args.nth(0)?;
let val: i32 = tictactoe::Player::into_i32(self.game.get(idx)?); let val: i32 = tictactoe::Player::into_i32(self.game.get(idx)?);
Ok(Some(val.into())) Ok(Some(val.into()))
} }

View File

@ -132,7 +132,7 @@ impl FuncInstance {
let mut interpreter = Interpreter::new(externals); let mut interpreter = Interpreter::new(externals);
interpreter.run_function(ctx) interpreter.run_function(ctx)
} }
InvokeKind::Host(host_func, args) => externals.invoke_index(host_func, args), InvokeKind::Host(host_func, args) => externals.invoke_index(host_func, args.into()),
} }
} }
} }

View File

@ -1,7 +1,8 @@
use std::any::TypeId; use std::any::TypeId;
use value::RuntimeValue; use value::{RuntimeValue, TryInto};
use Error; use Error;
/// Safe wrapper for list of arguments
pub struct RuntimeArgs<'a>(&'a [RuntimeValue]); pub struct RuntimeArgs<'a>(&'a [RuntimeValue]);
impl<'a> From<&'a [RuntimeValue]> for RuntimeArgs<'a> { impl<'a> From<&'a [RuntimeValue]> for RuntimeArgs<'a> {
@ -11,8 +12,23 @@ impl<'a> From<&'a [RuntimeValue]> for RuntimeArgs<'a> {
} }
impl<'a> RuntimeArgs<'a> { impl<'a> RuntimeArgs<'a> {
fn nth<T>(&self, idx: usize) -> Result<T, Error> where RuntimeValue: From<T> {
Err(Error::Value("Invalid cast".to_owned())) /// Extract argument by index `idx` returning error if cast is invalid or not enough arguments
pub fn nth<T>(&self, idx: usize) -> Result<T, Error> where RuntimeValue: TryInto<T, Error> {
Ok(self.nth_value(idx)?.try_into().map_err(|_| Error::Value("Invalid argument cast".to_owned()))?)
}
/// Extract argument as a runtime value by index `idx` returning error is not enougn arguments
pub fn nth_value(&self, idx: usize) -> Result<RuntimeValue, Error> {
if self.0.len() <= idx {
return Err(Error::Value("Invalid argument index".to_owned()));
}
Ok(self.0[idx])
}
/// Total number of arguments
pub fn len(&self) -> usize {
self.0.len()
} }
} }
@ -49,7 +65,7 @@ pub trait Externals {
fn invoke_index( fn invoke_index(
&mut self, &mut self,
index: usize, index: usize,
args: &[RuntimeValue], args: RuntimeArgs,
) -> Result<Option<RuntimeValue>, Error>; ) -> Result<Option<RuntimeValue>, Error>;
} }
@ -59,7 +75,7 @@ impl Externals for NopExternals {
fn invoke_index( fn invoke_index(
&mut self, &mut self,
_index: usize, _index: usize,
_args: &[RuntimeValue], _args: RuntimeArgs,
) -> Result<Option<RuntimeValue>, Error> { ) -> Result<Option<RuntimeValue>, Error> {
Err(Error::Trap("invoke index on no-op externals".into())) Err(Error::Trap("invoke index on no-op externals".into()))
} }

View File

@ -130,7 +130,7 @@ mod tests;
pub use self::memory::{MemoryInstance, MemoryRef}; pub use self::memory::{MemoryInstance, MemoryRef};
pub use self::table::{TableInstance, TableRef}; pub use self::table::{TableInstance, TableRef};
pub use self::value::{RuntimeValue, TryInto}; pub use self::value::{RuntimeValue, TryInto};
pub use self::host::{Externals, NopExternals, HostError}; pub use self::host::{Externals, NopExternals, HostError, RuntimeArgs};
pub use self::imports::{ModuleImportResolver, ImportResolver, ImportsBuilder}; pub use self::imports::{ModuleImportResolver, ImportResolver, ImportsBuilder};
pub use self::module::{ModuleInstance, ModuleRef, ExternVal, NotStartedModuleRef}; pub use self::module::{ModuleInstance, ModuleRef, ExternVal, NotStartedModuleRef};
pub use self::global::{GlobalInstance, GlobalRef}; pub use self::global::{GlobalInstance, GlobalRef};

View File

@ -2,6 +2,7 @@ use {
Error, Signature, Externals, FuncInstance, FuncRef, HostError, ImportsBuilder, Error, Signature, Externals, FuncInstance, FuncRef, HostError, ImportsBuilder,
MemoryInstance, MemoryRef, TableInstance, TableRef, ModuleImportResolver, ModuleInstance, ModuleRef, MemoryInstance, MemoryRef, TableInstance, TableRef, ModuleImportResolver, ModuleInstance, ModuleRef,
RuntimeValue, TryInto, LoadedModule, load_from_buffer, TableDescriptor, MemoryDescriptor, RuntimeValue, TryInto, LoadedModule, load_from_buffer, TableDescriptor, MemoryDescriptor,
RuntimeArgs,
}; };
use types::ValueType; use types::ValueType;
use wabt::wat2wasm; use wabt::wat2wasm;
@ -78,25 +79,24 @@ impl Externals for TestHost {
fn invoke_index( fn invoke_index(
&mut self, &mut self,
index: usize, index: usize,
args: &[RuntimeValue], args: RuntimeArgs,
) -> Result<Option<RuntimeValue>, Error> { ) -> Result<Option<RuntimeValue>, Error> {
let mut args = args.iter().cloned();
match index { match index {
SUB_FUNC_INDEX => { SUB_FUNC_INDEX => {
let a: i32 = args.next().unwrap().try_into().unwrap(); let a: i32 = args.nth(0)?;
let b: i32 = args.next().unwrap().try_into().unwrap(); let b: i32 = args.nth(1)?;
let result: RuntimeValue = (a - b).into(); let result: RuntimeValue = (a - b).into();
Ok(Some(result)) Ok(Some(result))
} }
ERR_FUNC_INDEX => { ERR_FUNC_INDEX => {
let error_code: u32 = args.next().unwrap().try_into().unwrap(); let error_code = args.nth::<i32>(0)? as u32;
let error = HostErrorWithCode { error_code }; let error = HostErrorWithCode { error_code };
Err(Error::Host(Box::new(error))) Err(Error::Host(Box::new(error)))
} }
INC_MEM_FUNC_INDEX => { INC_MEM_FUNC_INDEX => {
let ptr: u32 = args.next().unwrap().try_into().unwrap(); let ptr = args.nth::<i32>(0)? as u32;
let memory = self.memory.as_ref().expect( let memory = self.memory.as_ref().expect(
"Function 'inc_mem' expects attached memory", "Function 'inc_mem' expects attached memory",
@ -109,7 +109,7 @@ impl Externals for TestHost {
Ok(None) Ok(None)
} }
GET_MEM_FUNC_INDEX => { GET_MEM_FUNC_INDEX => {
let ptr: u32 = args.next().unwrap().try_into().unwrap(); let ptr = args.nth::<i32>(0)? as u32;
let memory = self.memory.as_ref().expect( let memory = self.memory.as_ref().expect(
"Function 'get_mem' expects attached memory", "Function 'get_mem' expects attached memory",
@ -120,7 +120,7 @@ impl Externals for TestHost {
Ok(Some(RuntimeValue::I32(buf[0] as i32))) Ok(Some(RuntimeValue::I32(buf[0] as i32)))
} }
RECURSE_FUNC_INDEX => { RECURSE_FUNC_INDEX => {
let val: RuntimeValue = args.next().unwrap(); let val = args.nth_value(0)?;
let instance = self.instance let instance = self.instance
.as_ref() .as_ref()
@ -463,12 +463,11 @@ fn defer_providing_externals() {
fn invoke_index( fn invoke_index(
&mut self, &mut self,
index: usize, index: usize,
args: &[RuntimeValue], args: RuntimeArgs,
) -> Result<Option<RuntimeValue>, Error> { ) -> Result<Option<RuntimeValue>, Error> {
match index { match index {
INC_FUNC_INDEX => { INC_FUNC_INDEX => {
let mut args = args.iter().cloned(); let a = args.nth::<i32>(0)? as u32;
let a: u32 = args.next().unwrap().try_into().unwrap();
*self.acc += a; *self.acc += a;
Ok(None) Ok(None)
} }
@ -528,7 +527,7 @@ fn two_envs_one_externals() {
fn invoke_index( fn invoke_index(
&mut self, &mut self,
index: usize, index: usize,
_args: &[RuntimeValue], _args: RuntimeArgs,
) -> Result<Option<RuntimeValue>, Error> { ) -> Result<Option<RuntimeValue>, Error> {
match index { match index {
PRIVILEGED_FUNC_INDEX => { PRIVILEGED_FUNC_INDEX => {
@ -648,7 +647,7 @@ fn dynamically_add_host_func() {
fn invoke_index( fn invoke_index(
&mut self, &mut self,
index: usize, index: usize,
_args: &[RuntimeValue], _args: RuntimeArgs,
) -> Result<Option<RuntimeValue>, Error> { ) -> Result<Option<RuntimeValue>, Error> {
match index { match index {
ADD_FUNC_FUNC_INDEX => { ADD_FUNC_FUNC_INDEX => {