@@ -4,10 +4,6 @@ use tinywasm_types::{MemoryType, ModuleInstanceAddr};
44
55use crate :: { cold, log, Error , Result } ;
66
7- const PAGE_SIZE : usize = 65536 ;
8- const MAX_PAGES : usize = 65536 ;
9- const MAX_SIZE : u64 = PAGE_SIZE as u64 * MAX_PAGES as u64 ;
10-
117/// A WebAssembly Memory Instance
128///
139/// See <https://webassembly.github.io/spec/core/exec/runtime.html#memory-instances>
@@ -21,13 +17,13 @@ pub(crate) struct MemoryInstance {
2117
2218impl MemoryInstance {
2319 pub ( crate ) fn new ( kind : MemoryType , owner : ModuleInstanceAddr ) -> Self {
24- assert ! ( kind. page_count_initial <= kind. page_count_max. unwrap_or ( MAX_PAGES as u64 ) ) ;
25- log:: debug!( "initializing memory with {} pages" , kind. page_count_initial) ;
20+ assert ! ( kind. page_count_initial( ) <= kind. page_count_max( ) ) ;
21+ log:: debug!( "initializing memory with {} pages of {} bytes " , kind. page_count_initial( ) , kind . page_size ( ) ) ;
2622
2723 Self {
2824 kind,
29- data : vec ! [ 0 ; PAGE_SIZE * kind. page_count_initial as usize ] ,
30- page_count : kind. page_count_initial as usize ,
25+ data : vec ! [ 0 ; kind. initial_size ( ) as usize ] ,
26+ page_count : kind. page_count_initial ( ) as usize ,
3127 _owner : owner,
3228 }
3329 }
@@ -58,7 +54,7 @@ impl MemoryInstance {
5854 }
5955
6056 pub ( crate ) fn max_pages ( & self ) -> usize {
61- self . kind . page_count_max . unwrap_or ( MAX_PAGES as u64 ) as usize
57+ self . kind . page_count_max ( ) as usize
6258 }
6359
6460 pub ( crate ) fn load ( & self , addr : usize , len : usize ) -> Result < & [ u8 ] > {
@@ -133,12 +129,12 @@ impl MemoryInstance {
133129 let new_pages = current_pages as i64 + pages_delta as i64 ;
134130 debug_assert ! ( new_pages <= i32 :: MAX as i64 , "page count should never be greater than i32::MAX" ) ;
135131
136- if new_pages < 0 || new_pages > MAX_PAGES as i64 || new_pages as usize > self . max_pages ( ) {
132+ if new_pages < 0 || new_pages as usize > self . max_pages ( ) {
137133 return None ;
138134 }
139135
140- let new_size = new_pages as usize * PAGE_SIZE ;
141- if new_size as u64 > MAX_SIZE {
136+ let new_size = ( new_pages as u64 * self . kind . page_size ( ) ) as usize ;
137+ if new_size as u64 > self . kind . max_size ( ) {
142138 return None ;
143139 }
144140
@@ -190,7 +186,7 @@ mod memory_instance_tests {
190186 use tinywasm_types:: MemoryArch ;
191187
192188 fn create_test_memory ( ) -> MemoryInstance {
193- let kind = MemoryType { arch : MemoryArch :: I32 , page_count_initial : 1 , page_count_max : Some ( 2 ) } ;
189+ let kind = MemoryType :: new ( MemoryArch :: I32 , 1 , Some ( 2 ) , None ) ;
194190 let owner = ModuleInstanceAddr :: default ( ) ;
195191 MemoryInstance :: new ( kind, owner)
196192 }
@@ -249,7 +245,7 @@ mod memory_instance_tests {
249245 #[ test]
250246 fn test_memory_grow_out_of_bounds ( ) {
251247 let mut memory = create_test_memory ( ) ;
252- assert ! ( memory. grow( MAX_PAGES as i32 + 1 ) . is_none( ) ) ;
248+ assert ! ( memory. grow( memory . kind . max_size ( ) as i32 + 1 ) . is_none( ) ) ;
253249 }
254250
255251 #[ test]
@@ -258,4 +254,29 @@ mod memory_instance_tests {
258254 assert_eq ! ( memory. grow( 1 ) , Some ( 1 ) ) ;
259255 assert_eq ! ( memory. grow( 1 ) , None ) ;
260256 }
257+
258+ #[ test]
259+ fn test_memory_custom_page_size_out_of_bounds ( ) {
260+ let kind = MemoryType :: new ( MemoryArch :: I32 , 1 , Some ( 2 ) , Some ( 1 ) ) ;
261+ let owner = ModuleInstanceAddr :: default ( ) ;
262+ let mut memory = MemoryInstance :: new ( kind, owner) ;
263+
264+ let data_to_store = [ 1 , 2 ] ;
265+ assert ! ( memory. store( 0 , data_to_store. len( ) , & data_to_store) . is_err( ) ) ;
266+ }
267+
268+ #[ test]
269+ fn test_memory_custom_page_size_grow ( ) {
270+ let kind = MemoryType :: new ( MemoryArch :: I32 , 1 , Some ( 2 ) , Some ( 1 ) ) ;
271+ let owner = ModuleInstanceAddr :: default ( ) ;
272+ let mut memory = MemoryInstance :: new ( kind, owner) ;
273+
274+ assert_eq ! ( memory. grow( 1 ) , Some ( 1 ) ) ;
275+
276+ let data_to_store = [ 1 , 2 ] ;
277+ assert ! ( memory. store( 0 , data_to_store. len( ) , & data_to_store) . is_ok( ) ) ;
278+
279+ let loaded_data = memory. load ( 0 , data_to_store. len ( ) ) . unwrap ( ) ;
280+ assert_eq ! ( loaded_data, & data_to_store) ;
281+ }
261282}
0 commit comments