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

Commit 177b325

Browse files
wip: mem64
Signed-off-by: Henry Gressmann <[email protected]>
1 parent 8129c7d commit 177b325

File tree

7 files changed

+45
-23
lines changed

7 files changed

+45
-23
lines changed

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/tinywasm/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ tinywasm-types={version="0.9.0-alpha.0", path="../types", default-features=false
2020
libm={version="0.2", default-features=false}
2121

2222
[dev-dependencies]
23-
wasm-testsuite={version="0.4.4"}
23+
wasm-testsuite={version="0.5.0"}
2424
indexmap="2.7"
2525
wast={workspace=true}
2626
wat={workspace=true}

crates/tinywasm/src/interpreter/executor.rs

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -518,12 +518,21 @@ impl<'store, 'stack> Executor<'store, 'stack> {
518518

519519
fn exec_memory_size(&mut self, addr: u32) {
520520
let mem = self.store.get_mem(self.module.resolve_mem_addr(addr));
521-
self.stack.values.push::<i32>(mem.page_count as i32);
521+
522+
match mem.is_64bit() {
523+
true => self.stack.values.push::<i64>(mem.page_count as i64),
524+
false => self.stack.values.push::<i32>(mem.page_count as i32),
525+
}
522526
}
523527
fn exec_memory_grow(&mut self, addr: u32) {
524528
let mem = self.store.get_mem_mut(self.module.resolve_mem_addr(addr));
525529
let prev_size = mem.page_count as i32;
526-
let pages_delta = self.stack.values.pop::<i32>();
530+
531+
let pages_delta = match mem.is_64bit() {
532+
true => self.stack.values.pop::<i64>(),
533+
false => self.stack.values.pop::<i32>() as i64,
534+
};
535+
527536
self.stack.values.push::<i32>(match mem.grow(pages_delta) {
528537
Some(_) => prev_size,
529538
None => -1,
@@ -605,14 +614,13 @@ impl<'store, 'stack> Executor<'store, 'stack> {
605614
dst as usize,
606615
src as usize,
607616
size as usize,
608-
)?;
617+
)
609618
} else {
610619
// copy between two memories
611620
let (table_from, table_to) =
612621
self.store.get_tables_mut(self.module.resolve_table_addr(from), self.module.resolve_table_addr(to))?;
613-
table_to.copy_from_slice(dst as usize, table_from.load(src as usize, size as usize)?)?;
622+
table_to.copy_from_slice(dst as usize, table_from.load(src as usize, size as usize)?)
614623
}
615-
Ok(())
616624
}
617625

618626
fn exec_mem_load<LOAD: MemLoadable<LOAD_SIZE>, const LOAD_SIZE: usize, TARGET: InternalValue>(
@@ -622,11 +630,16 @@ impl<'store, 'stack> Executor<'store, 'stack> {
622630
cast: fn(LOAD) -> TARGET,
623631
) -> ControlFlow<Option<Error>> {
624632
let mem = self.store.get_mem(self.module.resolve_mem_addr(mem_addr));
625-
let val = self.stack.values.pop::<i32>() as u64;
626-
let Some(Ok(addr)) = offset.checked_add(val).map(TryInto::try_into) else {
633+
634+
let addr = match mem.is_64bit() {
635+
true => self.stack.values.pop::<i64>() as u64,
636+
false => self.stack.values.pop::<i32>() as u32 as u64,
637+
};
638+
639+
let Some(Ok(addr)) = offset.checked_add(addr).map(TryInto::try_into) else {
627640
cold();
628641
return ControlFlow::Break(Some(Error::Trap(Trap::MemoryOutOfBounds {
629-
offset: val as usize,
642+
offset: addr as usize,
630643
len: LOAD_SIZE,
631644
max: 0,
632645
})));
@@ -644,10 +657,16 @@ impl<'store, 'stack> Executor<'store, 'stack> {
644657
let mem = self.store.get_mem_mut(self.module.resolve_mem_addr(mem_addr));
645658
let val = self.stack.values.pop::<T>();
646659
let val = (cast(val)).to_mem_bytes();
647-
let addr = self.stack.values.pop::<i32>() as u64;
660+
661+
let addr = match mem.is_64bit() {
662+
true => self.stack.values.pop::<i64>() as u64,
663+
false => self.stack.values.pop::<i32>() as u32 as u64,
664+
};
665+
648666
if let Err(e) = mem.store((offset + addr) as usize, val.len(), &val) {
649667
return ControlFlow::Break(Some(e));
650668
}
669+
651670
ControlFlow::Continue(())
652671
}
653672

crates/tinywasm/src/reference.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ impl MemoryRefMut<'_> {
5454
}
5555

5656
/// Grow the memory by the given number of pages
57-
pub fn grow(&mut self, delta_pages: i32) -> Option<i32> {
57+
pub fn grow(&mut self, delta_pages: i64) -> Option<i64> {
5858
self.0.grow(delta_pages)
5959
}
6060

crates/tinywasm/src/store/memory.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use alloc::vec;
22
use alloc::vec::Vec;
3-
use tinywasm_types::{MemoryType, ModuleInstanceAddr};
3+
use tinywasm_types::{MemoryArch, MemoryType, ModuleInstanceAddr};
44

55
use crate::{Error, Result, cold, log};
66

@@ -28,6 +28,11 @@ impl MemoryInstance {
2828
}
2929
}
3030

31+
#[inline]
32+
pub fn is_64bit(&self) -> bool {
33+
matches!(self.kind.arch(), MemoryArch::I64)
34+
}
35+
3136
#[inline(always)]
3237
pub(crate) fn len(&self) -> usize {
3338
self.data.len()
@@ -124,15 +129,13 @@ impl MemoryInstance {
124129
}
125130

126131
#[inline]
127-
pub(crate) fn grow(&mut self, pages_delta: i32) -> Option<i32> {
132+
pub(crate) fn grow(&mut self, pages_delta: i64) -> Option<i64> {
128133
let current_pages = self.page_count;
129134
let new_pages = current_pages as i64 + pages_delta as i64;
130-
debug_assert!(new_pages <= i32::MAX as i64, "page count should never be greater than i32::MAX");
131135

132136
if new_pages < 0 || new_pages as usize > self.max_pages() {
133137
log::debug!("memory.grow failed: new_pages={}, max_pages={}", new_pages, self.max_pages());
134138
log::debug!("{} {}", self.kind.page_count_max(), self.kind.page_size());
135-
136139
return None;
137140
}
138141

@@ -145,7 +148,7 @@ impl MemoryInstance {
145148
self.data.reserve_exact(new_size);
146149
self.data.resize_with(new_size, Default::default);
147150
self.page_count = new_pages as usize;
148-
Some(current_pages as i32)
151+
Some(current_pages as i64)
149152
}
150153
}
151154

@@ -241,14 +244,14 @@ mod memory_instance_tests {
241244
fn test_memory_grow() {
242245
let mut memory = create_test_memory();
243246
let original_pages = memory.page_count;
244-
assert_eq!(memory.grow(1), Some(original_pages as i32));
247+
assert_eq!(memory.grow(1), Some(original_pages as i64));
245248
assert_eq!(memory.page_count, original_pages + 1);
246249
}
247250

248251
#[test]
249252
fn test_memory_grow_out_of_bounds() {
250253
let mut memory = create_test_memory();
251-
assert!(memory.grow(memory.kind.max_size() as i32 + 1).is_none());
254+
assert!(memory.grow(memory.kind.max_size() as i64 + 1).is_none());
252255
}
253256

254257
#[test]
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.9.0-alpha.0,32629,2274,[{"name":"address.wast","passed":260,"failed":0},{"name":"address64.wast","passed":4,"failed":238},{"name":"align.wast","passed":161,"failed":0},{"name":"align64.wast","passed":108,"failed":48},{"name":"annotations.wast","passed":74,"failed":0},{"name":"binary-leb128.wast","passed":93,"failed":0},{"name":"binary.wast","passed":126,"failed":0},{"name":"block.wast","passed":223,"failed":0},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":119,"failed":0},{"name":"br_on_non_null.wast","passed":1,"failed":9},{"name":"br_on_null.wast","passed":1,"failed":9},{"name":"br_table.wast","passed":24,"failed":162},{"name":"bulk.wast","passed":117,"failed":0},{"name":"call.wast","passed":91,"failed":0},{"name":"call_indirect.wast","passed":172,"failed":1},{"name":"call_ref.wast","passed":4,"failed":31},{"name":"comments.wast","passed":8,"failed":0},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":619,"failed":0},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":59,"failed":6},{"name":"elem.wast","passed":137,"failed":14},{"name":"endianness.wast","passed":69,"failed":0},{"name":"endianness64.wast","passed":1,"failed":68},{"name":"exports.wast","passed":97,"failed":0},{"name":"f32.wast","passed":2514,"failed":0},{"name":"f32_bitwise.wast","passed":364,"failed":0},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":2514,"failed":0},{"name":"f64_bitwise.wast","passed":364,"failed":0},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":8,"failed":0},{"name":"float_exprs.wast","passed":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_memory64.wast","passed":6,"failed":84},{"name":"float_misc.wast","passed":471,"failed":0},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":175,"failed":0},{"name":"func_ptrs.wast","passed":36,"failed":0},{"name":"global.wast","passed":53,"failed":71},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"id.wast","passed":7,"failed":0},{"name":"if.wast","passed":241,"failed":0},{"name":"imports.wast","passed":169,"failed":90},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"instance.wast","passed":0,"failed":23},{"name":"int_exprs.wast","passed":108,"failed":0},{"name":"int_literals.wast","passed":51,"failed":0},{"name":"labels.wast","passed":29,"failed":0},{"name":"left-to-right.wast","passed":96,"failed":0},{"name":"linking.wast","passed":142,"failed":21},{"name":"load.wast","passed":118,"failed":0},{"name":"load64.wast","passed":60,"failed":37},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_init.wast","passed":10,"failed":0},{"name":"local_set.wast","passed":53,"failed":0},{"name":"local_tee.wast","passed":98,"failed":0},{"name":"loop.wast","passed":120,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":89,"failed":1},{"name":"memory64.wast","passed":23,"failed":46},{"name":"memory_copy.wast","passed":8400,"failed":500},{"name":"memory_fill.wast","passed":175,"failed":25},{"name":"memory_grow.wast","passed":157,"failed":0},{"name":"memory_grow64.wast","passed":4,"failed":45},{"name":"memory_init.wast","passed":333,"failed":147},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_redundancy64.wast","passed":1,"failed":7},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_trap.wast","passed":182,"failed":0},{"name":"memory_trap64.wast","passed":2,"failed":170},{"name":"names.wast","passed":486,"failed":0},{"name":"nop.wast","passed":88,"failed":0},{"name":"obsolete-keywords.wast","passed":11,"failed":0},{"name":"ref.wast","passed":12,"failed":1},{"name":"ref_as_non_null.wast","passed":1,"failed":6},{"name":"ref_func.wast","passed":17,"failed":0},{"name":"ref_is_null.wast","passed":2,"failed":20},{"name":"ref_null.wast","passed":0,"failed":34},{"name":"return.wast","passed":84,"failed":0},{"name":"return_call.wast","passed":45,"failed":0},{"name":"return_call_indirect.wast","passed":76,"failed":0},{"name":"return_call_ref.wast","passed":11,"failed":40},{"name":"select.wast","passed":155,"failed":2},{"name":"skip-stack-guard-page.wast","passed":11,"failed":0},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":20,"failed":0},{"name":"store.wast","passed":111,"failed":0},{"name":"switch.wast","passed":28,"failed":0},{"name":"table-sub.wast","passed":2,"failed":1},{"name":"table.wast","passed":47,"failed":13},{"name":"table_copy.wast","passed":1750,"failed":22},{"name":"table_copy_mixed.wast","passed":4,"failed":0},{"name":"table_fill.wast","passed":45,"failed":35},{"name":"table_get.wast","passed":16,"failed":1},{"name":"table_grow.wast","passed":58,"failed":21},{"name":"table_init.wast","passed":783,"failed":93},{"name":"table_set.wast","passed":26,"failed":2},{"name":"table_size.wast","passed":39,"failed":1},{"name":"tag.wast","passed":1,"failed":8},{"name":"throw.wast","passed":3,"failed":10},{"name":"throw_ref.wast","passed":2,"failed":13},{"name":"token.wast","passed":61,"failed":0},{"name":"traps.wast","passed":36,"failed":0},{"name":"try_table.wast","passed":11,"failed":51},{"name":"type-canon.wast","passed":0,"failed":2},{"name":"type-equivalence.wast","passed":12,"failed":20},{"name":"type-rec.wast","passed":6,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":121,"failed":0},{"name":"unreached-valid.wast","passed":2,"failed":11},{"name":"unwind.wast","passed":50,"failed":0},{"name":"utf8-custom-section-id.wast","passed":176,"failed":0},{"name":"utf8-import-field.wast","passed":176,"failed":0},{"name":"utf8-import-module.wast","passed":176,"failed":0},{"name":"utf8-invalid-encoding.wast","passed":176,"failed":0}]
1+
0.9.0-alpha.0,33660,1243,[{"name":"address.wast","passed":260,"failed":0},{"name":"address64.wast","passed":242,"failed":0},{"name":"align.wast","passed":161,"failed":0},{"name":"align64.wast","passed":156,"failed":0},{"name":"annotations.wast","passed":74,"failed":0},{"name":"binary-leb128.wast","passed":93,"failed":0},{"name":"binary.wast","passed":126,"failed":0},{"name":"block.wast","passed":223,"failed":0},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":119,"failed":0},{"name":"br_on_non_null.wast","passed":1,"failed":9},{"name":"br_on_null.wast","passed":1,"failed":9},{"name":"br_table.wast","passed":24,"failed":162},{"name":"bulk.wast","passed":117,"failed":0},{"name":"call.wast","passed":91,"failed":0},{"name":"call_indirect.wast","passed":172,"failed":1},{"name":"call_ref.wast","passed":4,"failed":31},{"name":"comments.wast","passed":8,"failed":0},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":619,"failed":0},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":59,"failed":6},{"name":"elem.wast","passed":137,"failed":14},{"name":"endianness.wast","passed":69,"failed":0},{"name":"endianness64.wast","passed":69,"failed":0},{"name":"exports.wast","passed":97,"failed":0},{"name":"f32.wast","passed":2514,"failed":0},{"name":"f32_bitwise.wast","passed":364,"failed":0},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":2514,"failed":0},{"name":"f64_bitwise.wast","passed":364,"failed":0},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":8,"failed":0},{"name":"float_exprs.wast","passed":927,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_memory64.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":471,"failed":0},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":175,"failed":0},{"name":"func_ptrs.wast","passed":36,"failed":0},{"name":"global.wast","passed":53,"failed":71},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"id.wast","passed":7,"failed":0},{"name":"if.wast","passed":241,"failed":0},{"name":"imports.wast","passed":169,"failed":90},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"instance.wast","passed":0,"failed":23},{"name":"int_exprs.wast","passed":108,"failed":0},{"name":"int_literals.wast","passed":51,"failed":0},{"name":"labels.wast","passed":29,"failed":0},{"name":"left-to-right.wast","passed":96,"failed":0},{"name":"linking.wast","passed":142,"failed":21},{"name":"load.wast","passed":118,"failed":0},{"name":"load64.wast","passed":96,"failed":1},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_init.wast","passed":10,"failed":0},{"name":"local_set.wast","passed":53,"failed":0},{"name":"local_tee.wast","passed":98,"failed":0},{"name":"loop.wast","passed":120,"failed":0},{"name":"memory-multi.wast","passed":6,"failed":0},{"name":"memory.wast","passed":89,"failed":1},{"name":"memory64.wast","passed":65,"failed":4},{"name":"memory_copy.wast","passed":8628,"failed":272},{"name":"memory_fill.wast","passed":184,"failed":16},{"name":"memory_grow.wast","passed":157,"failed":0},{"name":"memory_grow64.wast","passed":11,"failed":38},{"name":"memory_init.wast","passed":439,"failed":41},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_redundancy64.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":49,"failed":0},{"name":"memory_trap.wast","passed":182,"failed":0},{"name":"memory_trap64.wast","passed":160,"failed":12},{"name":"names.wast","passed":486,"failed":0},{"name":"nop.wast","passed":88,"failed":0},{"name":"obsolete-keywords.wast","passed":11,"failed":0},{"name":"ref.wast","passed":12,"failed":1},{"name":"ref_as_non_null.wast","passed":1,"failed":6},{"name":"ref_func.wast","passed":17,"failed":0},{"name":"ref_is_null.wast","passed":2,"failed":20},{"name":"ref_null.wast","passed":0,"failed":34},{"name":"return.wast","passed":84,"failed":0},{"name":"return_call.wast","passed":45,"failed":0},{"name":"return_call_indirect.wast","passed":76,"failed":0},{"name":"return_call_ref.wast","passed":11,"failed":40},{"name":"select.wast","passed":155,"failed":2},{"name":"skip-stack-guard-page.wast","passed":11,"failed":0},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":20,"failed":0},{"name":"store.wast","passed":111,"failed":0},{"name":"switch.wast","passed":28,"failed":0},{"name":"table-sub.wast","passed":2,"failed":1},{"name":"table.wast","passed":47,"failed":13},{"name":"table_copy.wast","passed":1750,"failed":22},{"name":"table_copy_mixed.wast","passed":4,"failed":0},{"name":"table_fill.wast","passed":45,"failed":35},{"name":"table_get.wast","passed":16,"failed":1},{"name":"table_grow.wast","passed":58,"failed":21},{"name":"table_init.wast","passed":783,"failed":93},{"name":"table_set.wast","passed":26,"failed":2},{"name":"table_size.wast","passed":39,"failed":1},{"name":"tag.wast","passed":1,"failed":8},{"name":"throw.wast","passed":3,"failed":10},{"name":"throw_ref.wast","passed":2,"failed":13},{"name":"token.wast","passed":61,"failed":0},{"name":"traps.wast","passed":36,"failed":0},{"name":"try_table.wast","passed":11,"failed":51},{"name":"type-canon.wast","passed":0,"failed":2},{"name":"type-equivalence.wast","passed":12,"failed":20},{"name":"type-rec.wast","passed":6,"failed":14},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":121,"failed":0},{"name":"unreached-valid.wast","passed":2,"failed":11},{"name":"unwind.wast","passed":50,"failed":0},{"name":"utf8-custom-section-id.wast","passed":176,"failed":0},{"name":"utf8-import-field.wast","passed":176,"failed":0},{"name":"utf8-import-module.wast","passed":176,"failed":0},{"name":"utf8-invalid-encoding.wast","passed":176,"failed":0}]

0 commit comments

Comments
 (0)