From f121d206aa96d6a53c088fbc7f4cbcfdadad2afe Mon Sep 17 00:00:00 2001 From: Sergey Pepyakin Date: Wed, 31 Jan 2018 19:00:30 +0300 Subject: [PATCH] Make it compile. --- examples/tictactoe.rs | 4 ++-- spec/src/run.rs | 9 ++++++--- src/host.rs | 23 ++++++++++++++--------- src/lib.rs | 13 +++++++++++++ src/tests/host.rs | 23 ++++++++++++----------- 5 files changed, 47 insertions(+), 25 deletions(-) diff --git a/examples/tictactoe.rs b/examples/tictactoe.rs index be0f225..86d7781 100644 --- a/examples/tictactoe.rs +++ b/examples/tictactoe.rs @@ -152,12 +152,12 @@ impl<'a> Externals for Runtime<'a> { ) -> Result, Trap> { match index { SET_FUNC_INDEX => { - let idx: i32 = args.nth(0)?; + let idx: i32 = args.nth(0); self.game.set(idx, self.player)?; Ok(None) } GET_FUNC_INDEX => { - let idx: i32 = args.nth(0)?; + let idx: i32 = args.nth(0); let val: i32 = tictactoe::Player::into_i32(self.game.get(idx)?); Ok(Some(val.into())) } diff --git a/spec/src/run.rs b/spec/src/run.rs index 14afa25..7f56ce7 100644 --- a/spec/src/run.rs +++ b/spec/src/run.rs @@ -13,13 +13,14 @@ use wasmi::{ GlobalInstance, GlobalRef, ImportResolver, ImportsBuilder, MemoryInstance, MemoryRef, ModuleImportResolver, ModuleInstance, ModuleRef, RuntimeValue, TableInstance, TableRef, ValueType, - Module, Signature, MemoryDescriptor, + Module, Signature, MemoryDescriptor, Trap, TableDescriptor, GlobalDescriptor, FuncInstance, RuntimeArgs, }; #[derive(Debug)] enum Error { Load(String), + Start(Trap), Interpreter(InterpreterError), } @@ -58,7 +59,7 @@ impl Externals for SpecModule { &mut self, index: usize, args: RuntimeArgs, - ) -> Result, InterpreterError> { + ) -> Result, Trap> { match index { PRINT_FUNC_INDEX => { println!("print: {:?}", args); @@ -243,7 +244,9 @@ fn try_load( ) -> Result<(), Error> { let module = try_load_module(base_dir, module_path)?; let instance = ModuleInstance::new(&module, &ImportsBuilder::default())?; - instance.run_start(spec_driver.spec_module())?; + instance + .run_start(spec_driver.spec_module()) + .map_err(|trap| Error::Start(trap))?; Ok(()) } diff --git a/src/host.rs b/src/host.rs index 71b3cc0..948de64 100644 --- a/src/host.rs +++ b/src/host.rs @@ -14,18 +14,23 @@ impl<'a> From<&'a [RuntimeValue]> for RuntimeArgs<'a> { impl<'a> RuntimeArgs<'a> { /// Extract argument by index `idx` returning error if cast is invalid or not enough arguments - pub fn nth(&self, idx: usize) -> Result where RuntimeValue: TryInto { - Ok(self.nth_value(idx)?.try_into().map_err(|_| Error::Value("Invalid argument cast".to_owned()))?) + pub fn nth_checked(&self, idx: usize) -> Result where RuntimeValue: TryInto { + Ok(self.nth_value_checked(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 enough arguments - pub fn nth_value(&self, idx: usize) -> Result { + pub fn nth_value_checked(&self, idx: usize) -> Result { if self.0.len() <= idx { return Err(Error::Value("Invalid argument index".to_owned())); } Ok(self.0[idx]) } + pub fn nth(&self, idx: usize) -> T where RuntimeValue: TryInto { + let value = self.nth_value_checked(idx).expect("Invalid argument index"); + value.try_into().expect("Unexpected argument type") + } + /// Total number of arguments pub fn len(&self) -> usize { self.0.len() @@ -104,7 +109,7 @@ impl HostError { /// ```rust /// use wasmi::{ /// Externals, RuntimeValue, RuntimeArgs, Error, ModuleImportResolver, -/// FuncRef, ValueType, Signature, FuncInstance +/// FuncRef, ValueType, Signature, FuncInstance, Trap, /// }; /// /// struct HostExternals { @@ -118,11 +123,11 @@ impl HostError { /// &mut self, /// index: usize, /// args: RuntimeArgs, -/// ) -> Result, Error> { +/// ) -> Result, Trap> { /// match index { /// ADD_FUNC_INDEX => { -/// let a: u32 = args.nth(0).unwrap(); -/// let b: u32 = args.nth(1).unwrap(); +/// let a: u32 = args.nth(0); +/// let b: u32 = args.nth(1); /// let result = a + b; /// /// Ok(Some(RuntimeValue::I32(result as i32))) @@ -201,14 +206,14 @@ mod tests { #[test] fn i32_runtime_args() { let args: RuntimeArgs = (&[RuntimeValue::I32(0)][..]).into(); - let val: i32 = args.nth(0).unwrap(); + let val: i32 = args.nth_checked(0).unwrap(); assert_eq!(val, 0); } #[test] fn i64_invalid_arg_cast() { let args: RuntimeArgs = (&[RuntimeValue::I64(90534534545322)][..]).into(); - assert!(args.nth::(0).is_err()); + assert!(args.nth_checked::(0).is_err()); } // Tests that `HostError` trait is object safe. diff --git a/src/lib.rs b/src/lib.rs index 5d4e249..887a812 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -116,6 +116,7 @@ pub enum Trap { DivisionByZero, InvalidConversionToInt, StackOverflow, + Host(Box), } /// Internal interpreter error. @@ -204,6 +205,18 @@ impl From for Error where U: host::HostError + Sized { } } +impl From for Trap where U: host::HostError + Sized { + fn from(e: U) -> Self { + Trap::Host(Box::new(e)) + } +} + +impl From for Error { + fn from(e: Trap) -> Error { + Error::Trap(e) + } +} + impl From for Error { fn from(e: validation::Error) -> Error { Error::Validation(e.to_string()) diff --git a/src/tests/host.rs b/src/tests/host.rs index eaeb987..02cb86b 100644 --- a/src/tests/host.rs +++ b/src/tests/host.rs @@ -82,20 +82,20 @@ impl Externals for TestHost { ) -> Result, Trap> { match index { SUB_FUNC_INDEX => { - let a: i32 = args.nth(0)?; - let b: i32 = args.nth(1)?; + let a: i32 = args.nth(0); + let b: i32 = args.nth(1); let result: RuntimeValue = (a - b).into(); Ok(Some(result)) } ERR_FUNC_INDEX => { - let error_code: u32 = args.nth(0)?; + let error_code: u32 = args.nth(0); let error = HostErrorWithCode { error_code }; - Err(Error::Host(Box::new(error))) + Err(Trap::Host(Box::new(error))) } INC_MEM_FUNC_INDEX => { - let ptr: u32 = args.nth(0)?; + let ptr: u32 = args.nth(0); let memory = self.memory.as_ref().expect( "Function 'inc_mem' expects attached memory", @@ -108,7 +108,7 @@ impl Externals for TestHost { Ok(None) } GET_MEM_FUNC_INDEX => { - let ptr: u32 = args.nth(0)?; + let ptr: u32 = args.nth(0); let memory = self.memory.as_ref().expect( "Function 'get_mem' expects attached memory", @@ -119,7 +119,7 @@ impl Externals for TestHost { Ok(Some(RuntimeValue::I32(buf[0] as i32))) } RECURSE_FUNC_INDEX => { - let val = args.nth_value(0)?; + let val = args.nth_value_checked(0).expect("Exactly one argument expected"); let instance = self.instance .as_ref() @@ -131,7 +131,7 @@ impl Externals for TestHost { .expect("expected to be Some"); if val.value_type() != result.value_type() { - return Err(Error::Host(Box::new(HostErrorWithCode { error_code: 123 }))); + return Err(Trap::Host(Box::new(HostErrorWithCode { error_code: 123 }))); } Ok(Some(result)) } @@ -263,7 +263,7 @@ fn host_err() { ); let host_error: Box = match error { - Error::Host(err) => err, + Error::Trap(Trap::Host(err)) => err, err => panic!("Unexpected error {:?}", err), }; @@ -467,7 +467,7 @@ fn defer_providing_externals() { ) -> Result, Trap> { match index { INC_FUNC_INDEX => { - let a = args.nth::(0)?; + let a = args.nth::(0); *self.acc += a; Ok(None) } @@ -661,7 +661,8 @@ fn dynamically_add_host_func() { Signature::new(&[][..], Some(ValueType::I32)), host_func_index as usize, ); - self.table.set(table_index, Some(added_func))?; + self.table.set(table_index, Some(added_func)) + .map_err(|_| Trap::TableAccessOutOfBounds)?; Ok(Some(RuntimeValue::I32(table_index as i32))) }