@@ -3,10 +3,10 @@ use core::{
33 sync:: atomic:: { AtomicUsize , Ordering } ,
44} ;
55
6- use alloc:: { format, rc:: Rc , vec:: Vec } ;
6+ use alloc:: { format, rc:: Rc , string :: ToString , vec , vec:: Vec } ;
77use tinywasm_types:: {
8- Addr , Data , Element , ElementKind , FuncAddr , Function , Global , GlobalType , Import , Instruction , MemAddr , MemoryType ,
9- ModuleInstanceAddr , TableAddr , TableType , TypeAddr , ValType ,
8+ Addr , Data , Element , ElementKind , FuncAddr , Function , Global , GlobalType , Import , Instruction , MemAddr , MemoryArch ,
9+ MemoryType , ModuleInstanceAddr , TableAddr , TableType , TypeAddr , ValType ,
1010} ;
1111
1212use crate :: {
@@ -84,7 +84,7 @@ impl Default for Store {
8484pub ( crate ) struct StoreData {
8585 pub ( crate ) funcs : Vec < Rc < FunctionInstance > > ,
8686 pub ( crate ) tables : Vec < TableInstance > ,
87- pub ( crate ) mems : Vec < Rc < MemoryInstance > > ,
87+ pub ( crate ) mems : Vec < Rc < RefCell < MemoryInstance > > > ,
8888 pub ( crate ) globals : Vec < Rc < RefCell < GlobalInstance > > > ,
8989 pub ( crate ) elems : Vec < ElemInstance > ,
9090 pub ( crate ) datas : Vec < DataInstance > ,
@@ -130,14 +130,20 @@ impl Store {
130130 }
131131
132132 /// Add memories to the store, returning their addresses in the store
133- pub ( crate ) fn add_mems ( & mut self , mems : Vec < MemoryType > , idx : ModuleInstanceAddr ) -> Vec < MemAddr > {
133+ pub ( crate ) fn add_mems ( & mut self , mems : Vec < MemoryType > , idx : ModuleInstanceAddr ) -> Result < Vec < MemAddr > > {
134134 let mem_count = self . data . mems . len ( ) ;
135135 let mut mem_addrs = Vec :: with_capacity ( mem_count) ;
136136 for ( i, mem) in mems. into_iter ( ) . enumerate ( ) {
137- self . data . mems . push ( Rc :: new ( MemoryInstance :: new ( mem, idx) ) ) ;
137+ if let MemoryArch :: I64 = mem. arch {
138+ return Err ( Error :: UnsupportedFeature ( "64-bit memories" . to_string ( ) ) ) ;
139+ }
140+ self . data
141+ . mems
142+ . push ( Rc :: new ( RefCell :: new ( MemoryInstance :: new ( mem, idx) ) ) ) ;
143+
138144 mem_addrs. push ( ( i + mem_count) as MemAddr ) ;
139145 }
140- mem_addrs
146+ Ok ( mem_addrs)
141147 }
142148
143149 /// Add globals to the store, returning their addresses in the store
@@ -236,6 +242,15 @@ impl Store {
236242 . ok_or_else ( || Error :: Other ( format ! ( "function {} not found" , addr) ) )
237243 }
238244
245+ /// Get the memory at the actual index in the store
246+ pub ( crate ) fn get_mem ( & self , addr : usize ) -> Result < & Rc < RefCell < MemoryInstance > > > {
247+ self . data
248+ . mems
249+ . get ( addr)
250+ . ok_or_else ( || Error :: Other ( format ! ( "memory {} not found" , addr) ) )
251+ }
252+
253+ /// Get the global at the actual index in the store
239254 pub ( crate ) fn get_global_val ( & self , addr : usize ) -> Result < RawWasmValue > {
240255 self . data
241256 . globals
@@ -300,24 +315,51 @@ impl TableInstance {
300315 }
301316}
302317
318+ pub ( crate ) const PAGE_SIZE : usize = 64_000 ;
319+ pub ( crate ) const MAX_PAGES : usize = 65536 ;
320+ pub ( crate ) const MAX_SIZE : usize = PAGE_SIZE * MAX_PAGES ;
321+
303322/// A WebAssembly Memory Instance
304323///
305324/// See <https://webassembly.github.io/spec/core/exec/runtime.html#memory-instances>
306325#[ derive( Debug ) ]
307326pub ( crate ) struct MemoryInstance {
308327 pub ( crate ) kind : MemoryType ,
309328 pub ( crate ) data : Vec < u8 > ,
329+ pub ( crate ) page_count : usize ,
310330 pub ( crate ) owner : ModuleInstanceAddr , // index into store.module_instances
311331}
312332
313333impl MemoryInstance {
314334 pub ( crate ) fn new ( kind : MemoryType , owner : ModuleInstanceAddr ) -> Self {
335+ debug_assert ! ( kind. page_count_initial <= kind. page_count_max. unwrap_or( MAX_PAGES as u64 ) ) ;
336+
315337 Self {
316338 kind,
317- data : Vec :: new ( ) ,
339+ data : vec ! [ 0 ; PAGE_SIZE * kind. page_count_initial as usize ] ,
340+ page_count : kind. page_count_initial as usize ,
318341 owner,
319342 }
320343 }
344+
345+ pub ( crate ) fn size ( & self ) -> i32 {
346+ self . page_count as i32
347+ }
348+
349+ pub ( crate ) fn grow ( & mut self , delta : i32 ) -> Result < i32 > {
350+ let current_pages = self . size ( ) ;
351+ let new_pages = current_pages + delta;
352+ if new_pages < 0 || new_pages > MAX_PAGES as i32 {
353+ return Err ( Error :: Other ( format ! ( "memory size out of bounds: {}" , new_pages) ) ) ;
354+ }
355+ let new_size = new_pages as usize * PAGE_SIZE ;
356+ if new_size > MAX_SIZE {
357+ return Err ( Error :: Other ( format ! ( "memory size out of bounds: {}" , new_size) ) ) ;
358+ }
359+ self . data . resize ( new_size, 0 ) ;
360+ self . page_count = new_pages as usize ;
361+ Ok ( current_pages)
362+ }
321363}
322364
323365/// A WebAssembly Global Instance
0 commit comments