Skip to content
This repository was archived by the owner on Oct 3, 2025. It is now read-only.

Commit 93f9383

Browse files
feat: all mem loads
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
1 parent f13e225 commit 93f9383

File tree

4 files changed

+56
-25
lines changed

4 files changed

+56
-25
lines changed

crates/tinywasm/src/runtime/executor/macros.rs

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,32 @@
22
//!
33
//! These macros are used to generate the actual instruction implementations.
44
5+
macro_rules! mem_load {
6+
($type:ty, $arg:ident, $stack:ident, $store:ident, $module:ident) => {{
7+
mem_load!($type, $type, $arg, $stack, $store, $module)
8+
}};
9+
10+
($load_type:ty, $target_type:ty, $arg:ident, $stack:ident, $store:ident, $module:ident) => {{
11+
let mem_idx = $module.resolve_mem_addr($arg.mem_addr);
12+
let mem = $store.get_mem(mem_idx as usize)?;
13+
14+
let addr = $stack.values.pop()?.raw_value();
15+
16+
let val: [u8; core::mem::size_of::<$load_type>()] = {
17+
let mem = mem.borrow_mut();
18+
let val = mem.load(
19+
($arg.offset + addr) as usize,
20+
$arg.align as usize,
21+
core::mem::size_of::<$load_type>(),
22+
)?;
23+
val.try_into().expect("slice with incorrect length")
24+
};
25+
26+
let loaded_value = <$load_type>::from_le_bytes(val);
27+
$stack.values.push((loaded_value as $target_type).into());
28+
}};
29+
}
30+
531
/// Convert the top value on the stack to a specific type
632
macro_rules! conv_1 {
733
($from:ty, $to:ty, $stack:ident) => {{
@@ -10,6 +36,10 @@ macro_rules! conv_1 {
1036
}};
1137
}
1238

39+
/// Doing the actual conversion from float to int is a bit tricky, because
40+
/// we need to check for overflow. This macro generates the min/max values
41+
/// for a specific conversion, which are then used in the actual conversion.
42+
/// Rust sadly doesn't have wrapping casts for floats (yet)
1343
macro_rules! float_min_max {
1444
(f32, i32) => {
1545
(-2147483904.0_f32, 2147483648.0_f32)
@@ -18,22 +48,22 @@ macro_rules! float_min_max {
1848
(-2147483649.0_f64, 2147483648.0_f64)
1949
};
2050
(f32, u32) => {
21-
(-1.0_f32, 4294967296.0_f32)
51+
(-1.0_f32, 4294967296.0_f32) // 2^32
2252
};
2353
(f64, u32) => {
24-
(-1.0_f64, 4294967296.0_f64)
54+
(-1.0_f64, 4294967296.0_f64) // 2^32
2555
};
2656
(f32, i64) => {
27-
(-9223373136366403584.0_f32, 9223372036854775808.0_f32)
57+
(-9223373136366403584.0_f32, 9223372036854775808.0_f32) // 2^63 + 2^40 | 2^63
2858
};
2959
(f64, i64) => {
30-
(-9223372036854777856.0_f64, 9223372036854775808.0_f64)
60+
(-9223372036854777856.0_f64, 9223372036854775808.0_f64) // 2^63 + 2^40 | 2^63
3161
};
3262
(f32, u64) => {
33-
(-1.0_f32, 18446744073709551616.0_f32)
63+
(-1.0_f32, 18446744073709551616.0_f32) // 2^64
3464
};
3565
(f64, u64) => {
36-
(-1.0_f64, 18446744073709551616.0_f64)
66+
(-1.0_f64, 18446744073709551616.0_f64) // 2^64
3767
};
3868
// other conversions are not allowed
3969
($from:ty, $to:ty) => {
@@ -212,3 +242,4 @@ pub(super) use comp_zero;
212242
pub(super) use conv_1;
213243
pub(super) use conv_2;
214244
pub(super) use float_min_max;
245+
pub(super) use mem_load;

crates/tinywasm/src/runtime/executor/mod.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -313,20 +313,20 @@ fn exec_one(
313313
.store((arg.offset + addr) as usize, arg.align as usize, &val.to_le_bytes())?;
314314
}
315315

316-
I32Load(arg) => {
317-
let mem_idx = module.resolve_mem_addr(arg.mem_addr);
318-
let mem = store.get_mem(mem_idx as usize)?;
319-
320-
let addr = stack.values.pop()?.raw_value();
321-
322-
let val: [u8; 4] = {
323-
let mem = mem.borrow_mut();
324-
let val = mem.load((arg.offset + addr) as usize, arg.align as usize, 4)?;
325-
val.try_into().expect("slice with incorrect length")
326-
};
327-
328-
stack.values.push(i32::from_le_bytes(val).into());
329-
}
316+
I32Load(arg) => mem_load!(i32, arg, stack, store, module),
317+
I64Load(arg) => mem_load!(i64, arg, stack, store, module),
318+
F32Load(arg) => mem_load!(f32, arg, stack, store, module),
319+
F64Load(arg) => mem_load!(f64, arg, stack, store, module),
320+
I32Load8S(arg) => mem_load!(i8, i32, arg, stack, store, module),
321+
I32Load8U(arg) => mem_load!(u8, i32, arg, stack, store, module),
322+
I32Load16S(arg) => mem_load!(i16, i32, arg, stack, store, module),
323+
I32Load16U(arg) => mem_load!(u16, i32, arg, stack, store, module),
324+
I64Load8S(arg) => mem_load!(i8, i64, arg, stack, store, module),
325+
I64Load8U(arg) => mem_load!(u8, i64, arg, stack, store, module),
326+
I64Load16S(arg) => mem_load!(i16, i64, arg, stack, store, module),
327+
I64Load16U(arg) => mem_load!(u16, i64, arg, stack, store, module),
328+
I64Load32S(arg) => mem_load!(i32, i64, arg, stack, store, module),
329+
I64Load32U(arg) => mem_load!(u32, i64, arg, stack, store, module),
330330

331331
I64Eqz => comp_zero!(==, i64, stack),
332332
I32Eqz => comp_zero!(==, i32, stack),

0 commit comments

Comments
 (0)