mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 05:49:08 +00:00
wasm_interp: don't panic when unwrapping Value
This commit is contained in:
parent
d49ae6701a
commit
9d912a6cc7
5 changed files with 49 additions and 39 deletions
|
@ -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]);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue