wasm_interp: don't panic when unwrapping Value

This commit is contained in:
Brian Carroll 2022-12-06 20:19:25 +00:00
parent d49ae6701a
commit 9d912a6cc7
No known key found for this signature in database
GPG key ID: 5C7B2EC4101703C0
5 changed files with 49 additions and 39 deletions

View file

@ -712,55 +712,55 @@ impl<'a, I: ImportDispatcher> Instance<'a, I> {
}
I32STORE => {
let (addr, value) = self.get_store_addr_value(module)?;
let unwrapped = value.unwrap_i32();
let unwrapped = value.expect_i32().map_err(Error::from)?;
let target = &mut self.memory[addr..][..4];
target.copy_from_slice(&unwrapped.to_le_bytes());
}
I64STORE => {
let (addr, value) = self.get_store_addr_value(module)?;
let unwrapped = value.unwrap_i64();
let unwrapped = value.expect_i64().map_err(Error::from)?;
let target = &mut self.memory[addr..][..8];
target.copy_from_slice(&unwrapped.to_le_bytes());
}
F32STORE => {
let (addr, value) = self.get_store_addr_value(module)?;
let unwrapped = value.unwrap_f32();
let unwrapped = value.expect_f32().map_err(Error::from)?;
let target = &mut self.memory[addr..][..4];
target.copy_from_slice(&unwrapped.to_le_bytes());
}
F64STORE => {
let (addr, value) = self.get_store_addr_value(module)?;
let unwrapped = value.unwrap_f64();
let unwrapped = value.expect_f64().map_err(Error::from)?;
let target = &mut self.memory[addr..][..8];
target.copy_from_slice(&unwrapped.to_le_bytes());
}
I32STORE8 => {
let (addr, value) = self.get_store_addr_value(module)?;
let unwrapped = value.unwrap_i32();
let unwrapped = value.expect_i32().map_err(Error::from)?;
let target = &mut self.memory[addr..][..1];
target.copy_from_slice(&unwrapped.to_le_bytes()[..1]);
}
I32STORE16 => {
let (addr, value) = self.get_store_addr_value(module)?;
let unwrapped = value.unwrap_i32();
let unwrapped = value.expect_i32().map_err(Error::from)?;
let target = &mut self.memory[addr..][..2];
target.copy_from_slice(&unwrapped.to_le_bytes()[..2]);
}
I64STORE8 => {
let (addr, value) = self.get_store_addr_value(module)?;
let unwrapped = value.unwrap_i64();
let unwrapped = value.expect_i64().map_err(Error::from)?;
let target = &mut self.memory[addr..][..1];
target.copy_from_slice(&unwrapped.to_le_bytes()[..1]);
}
I64STORE16 => {
let (addr, value) = self.get_store_addr_value(module)?;
let unwrapped = value.unwrap_i64();
let unwrapped = value.expect_i64().map_err(Error::from)?;
let target = &mut self.memory[addr..][..2];
target.copy_from_slice(&unwrapped.to_le_bytes()[..2]);
}
I64STORE32 => {
let (addr, value) = self.get_store_addr_value(module)?;
let unwrapped = value.unwrap_i64();
let unwrapped = value.expect_i64().map_err(Error::from)?;
let target = &mut self.memory[addr..][..4];
target.copy_from_slice(&unwrapped.to_le_bytes()[..4]);
}

View file

@ -68,13 +68,23 @@ pub(crate) enum Error {
impl Error {
fn value_stack_type(expected: ValueType, is_float: bool, is_64: bool) -> Self {
let ty = match (is_float, is_64) {
let ty = type_from_flags_f_64(is_float, is_64);
Error::ValueStackType(expected, ty)
}
}
impl From<(ValueType, ValueType)> for Error {
fn from((expected, actual): (ValueType, ValueType)) -> Self {
Error::ValueStackType(expected, actual)
}
}
pub(crate) fn type_from_flags_f_64(is_float: bool, is_64: bool) -> ValueType {
match (is_float, is_64) {
(false, false) => ValueType::I32,
(false, true) => ValueType::I64,
(true, false) => ValueType::F32,
(true, true) => ValueType::F64,
};
Error::ValueStackType(expected, ty)
}
}

View file

@ -472,7 +472,7 @@ impl ImportDispatcher for TestDispatcher {
assert_eq!(module_name, "env");
assert_eq!(function_name, "increment_state");
assert_eq!(arguments.len(), 1);
let val = arguments[0].unwrap_i32();
let val = arguments[0].expect_i32().unwrap();
self.internal_state += val;
dbg!(val, self.internal_state);
Some(Value::I32(self.internal_state))

View file

@ -28,9 +28,9 @@ impl<'a> WasiDispatcher<'a> {
match function_name {
"args_get" => {
// uint8_t ** argv,
let mut ptr_ptr_argv = arguments[0].unwrap_i32() as usize;
let mut ptr_ptr_argv = arguments[0].expect_i32().unwrap() as usize;
// uint8_t * argv_buf
let mut ptr_argv_buf = arguments[1].unwrap_i32() as usize;
let mut ptr_argv_buf = arguments[1].expect_i32().unwrap() as usize;
for arg in self.args {
write_u32(memory, ptr_ptr_argv, ptr_argv_buf as u32);
@ -47,9 +47,9 @@ impl<'a> WasiDispatcher<'a> {
// (i32, i32) -> i32
// number of string arguments
let ptr_argc = arguments[0].unwrap_i32() as usize;
let ptr_argc = arguments[0].expect_i32().unwrap() as usize;
// size of string arguments buffer
let ptr_argv_buf_size = arguments[1].unwrap_i32() as usize;
let ptr_argv_buf_size = arguments[1].expect_i32().unwrap() as usize;
let argc = self.args.len() as u32;
write_u32(memory, ptr_argc, argc);
@ -61,8 +61,8 @@ impl<'a> WasiDispatcher<'a> {
}
"environ_get" => todo!("WASI {}({:?})", function_name, arguments),
"environ_sizes_get" => todo!("WASI {}({:?})", function_name, arguments),
"clock_res_get" => todo!("WASI {}({:?})", function_name, arguments),
"clock_time_get" => todo!("WASI {}({:?})", function_name, arguments),
"clock_res_get" => success_code,
"clock_time_get" => success_code,
"fd_advise" => todo!("WASI {}({:?})", function_name, arguments),
"fd_allocate" => todo!("WASI {}({:?})", function_name, arguments),
"fd_close" => todo!("WASI {}({:?})", function_name, arguments),
@ -85,13 +85,13 @@ impl<'a> WasiDispatcher<'a> {
"fd_tell" => todo!("WASI {}({:?})", function_name, arguments),
"fd_write" => {
// file descriptor
let fd = arguments[0].unwrap_i32();
let fd = arguments[0].expect_i32().unwrap();
// Array of IO vectors
let ptr_iovs = arguments[1].unwrap_i32() as usize;
let ptr_iovs = arguments[1].expect_i32().unwrap() as usize;
// Length of array
let iovs_len = arguments[2].unwrap_i32();
let iovs_len = arguments[2].expect_i32().unwrap();
// Out param: number of bytes written
let ptr_nwritten = arguments[3].unwrap_i32() as usize;
let ptr_nwritten = arguments[3].expect_i32().unwrap() as usize;
let mut write_lock = match fd {
1 => Ok(io::stdout().lock()),
@ -151,7 +151,7 @@ impl<'a> WasiDispatcher<'a> {
"path_unlink_file" => todo!("WASI {}({:?})", function_name, arguments),
"poll_oneoff" => todo!("WASI {}({:?})", function_name, arguments),
"proc_exit" => {
let exit_code = arguments[0].unwrap_i32();
let exit_code = arguments[0].expect_i32().unwrap();
exit(exit_code);
}
"proc_raise" => todo!("WASI {}({:?})", function_name, arguments),

View file

@ -695,28 +695,28 @@ pub enum Value {
}
impl Value {
pub fn unwrap_i32(&self) -> i32 {
pub fn expect_i32(&self) -> Result<i32, (ValueType, ValueType)> {
match self {
Value::I32(x) => *x,
_ => panic!("Expected I32 but found {:?}", self),
Value::I32(x) => Ok(*x),
_ => Err((ValueType::I32, ValueType::from(*self))),
}
}
pub fn unwrap_i64(&self) -> i64 {
pub fn expect_i64(&self) -> Result<i64, (ValueType, ValueType)> {
match self {
Value::I64(x) => *x,
_ => panic!("Expected I64 but found {:?}", self),
Value::I64(x) => Ok(*x),
_ => Err((ValueType::I64, ValueType::from(*self))),
}
}
pub fn unwrap_f32(&self) -> f32 {
pub fn expect_f32(&self) -> Result<f32, (ValueType, ValueType)> {
match self {
Value::F32(x) => *x,
_ => panic!("Expected F32 but found {:?}", self),
Value::F32(x) => Ok(*x),
_ => Err((ValueType::F32, ValueType::from(*self))),
}
}
pub fn unwrap_f64(&self) -> f64 {
pub fn expect_f64(&self) -> Result<f64, (ValueType, ValueType)> {
match self {
Value::F64(x) => *x,
_ => panic!("Expected F64 but found {:?}", self),
Value::F64(x) => Ok(*x),
_ => Err((ValueType::F64, ValueType::from(*self))),
}
}
}