Skip to content

Commit

Permalink
feat: all mem loads
Browse files Browse the repository at this point in the history
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
  • Loading branch information
explodingcamera committed Jan 7, 2024
1 parent f13e225 commit 93f9383
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 25 deletions.
43 changes: 37 additions & 6 deletions crates/tinywasm/src/runtime/executor/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,32 @@
//!
//! These macros are used to generate the actual instruction implementations.
macro_rules! mem_load {
($type:ty, $arg:ident, $stack:ident, $store:ident, $module:ident) => {{
mem_load!($type, $type, $arg, $stack, $store, $module)
}};

($load_type:ty, $target_type:ty, $arg:ident, $stack:ident, $store:ident, $module:ident) => {{
let mem_idx = $module.resolve_mem_addr($arg.mem_addr);
let mem = $store.get_mem(mem_idx as usize)?;

let addr = $stack.values.pop()?.raw_value();

let val: [u8; core::mem::size_of::<$load_type>()] = {
let mem = mem.borrow_mut();
let val = mem.load(
($arg.offset + addr) as usize,
$arg.align as usize,
core::mem::size_of::<$load_type>(),
)?;
val.try_into().expect("slice with incorrect length")
};

let loaded_value = <$load_type>::from_le_bytes(val);
$stack.values.push((loaded_value as $target_type).into());
}};
}

/// Convert the top value on the stack to a specific type
macro_rules! conv_1 {
($from:ty, $to:ty, $stack:ident) => {{
Expand All @@ -10,6 +36,10 @@ macro_rules! conv_1 {
}};
}

/// Doing the actual conversion from float to int is a bit tricky, because
/// we need to check for overflow. This macro generates the min/max values
/// for a specific conversion, which are then used in the actual conversion.
/// Rust sadly doesn't have wrapping casts for floats (yet)
macro_rules! float_min_max {
(f32, i32) => {
(-2147483904.0_f32, 2147483648.0_f32)
Expand All @@ -18,22 +48,22 @@ macro_rules! float_min_max {
(-2147483649.0_f64, 2147483648.0_f64)
};
(f32, u32) => {
(-1.0_f32, 4294967296.0_f32)
(-1.0_f32, 4294967296.0_f32) // 2^32
};
(f64, u32) => {
(-1.0_f64, 4294967296.0_f64)
(-1.0_f64, 4294967296.0_f64) // 2^32
};
(f32, i64) => {
(-9223373136366403584.0_f32, 9223372036854775808.0_f32)
(-9223373136366403584.0_f32, 9223372036854775808.0_f32) // 2^63 + 2^40 | 2^63
};
(f64, i64) => {
(-9223372036854777856.0_f64, 9223372036854775808.0_f64)
(-9223372036854777856.0_f64, 9223372036854775808.0_f64) // 2^63 + 2^40 | 2^63
};
(f32, u64) => {
(-1.0_f32, 18446744073709551616.0_f32)
(-1.0_f32, 18446744073709551616.0_f32) // 2^64
};
(f64, u64) => {
(-1.0_f64, 18446744073709551616.0_f64)
(-1.0_f64, 18446744073709551616.0_f64) // 2^64
};
// other conversions are not allowed
($from:ty, $to:ty) => {
Expand Down Expand Up @@ -212,3 +242,4 @@ pub(super) use comp_zero;
pub(super) use conv_1;
pub(super) use conv_2;
pub(super) use float_min_max;
pub(super) use mem_load;
28 changes: 14 additions & 14 deletions crates/tinywasm/src/runtime/executor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,20 +313,20 @@ fn exec_one(
.store((arg.offset + addr) as usize, arg.align as usize, &val.to_le_bytes())?;
}

I32Load(arg) => {
let mem_idx = module.resolve_mem_addr(arg.mem_addr);
let mem = store.get_mem(mem_idx as usize)?;

let addr = stack.values.pop()?.raw_value();

let val: [u8; 4] = {
let mem = mem.borrow_mut();
let val = mem.load((arg.offset + addr) as usize, arg.align as usize, 4)?;
val.try_into().expect("slice with incorrect length")
};

stack.values.push(i32::from_le_bytes(val).into());
}
I32Load(arg) => mem_load!(i32, arg, stack, store, module),
I64Load(arg) => mem_load!(i64, arg, stack, store, module),
F32Load(arg) => mem_load!(f32, arg, stack, store, module),
F64Load(arg) => mem_load!(f64, arg, stack, store, module),
I32Load8S(arg) => mem_load!(i8, i32, arg, stack, store, module),
I32Load8U(arg) => mem_load!(u8, i32, arg, stack, store, module),
I32Load16S(arg) => mem_load!(i16, i32, arg, stack, store, module),
I32Load16U(arg) => mem_load!(u16, i32, arg, stack, store, module),
I64Load8S(arg) => mem_load!(i8, i64, arg, stack, store, module),
I64Load8U(arg) => mem_load!(u8, i64, arg, stack, store, module),
I64Load16S(arg) => mem_load!(i16, i64, arg, stack, store, module),
I64Load16U(arg) => mem_load!(u16, i64, arg, stack, store, module),
I64Load32S(arg) => mem_load!(i32, i64, arg, stack, store, module),
I64Load32U(arg) => mem_load!(u32, i64, arg, stack, store, module),

I64Eqz => comp_zero!(==, i64, stack),
I32Eqz => comp_zero!(==, i32, stack),
Expand Down
Loading

0 comments on commit 93f9383

Please sign in to comment.