@@ -131,6 +131,10 @@ impl BasicMemory {
131
131
}
132
132
}
133
133
134
+ fn accessible_aux_size ( & self ) -> u32 {
135
+ cast ( self . accessible_aux_size ) . assert_always_fits_in_u32 ( )
136
+ }
137
+
134
138
fn set_accessible_aux_size ( & mut self , size : u32 ) {
135
139
self . accessible_aux_size = cast ( size) . to_usize ( ) ;
136
140
}
@@ -253,38 +257,43 @@ macro_rules! emit_branch {
253
257
} ;
254
258
}
255
259
256
- fn each_page ( module : & Module , address : u32 , length : u32 , callback : impl FnMut ( u32 , usize , usize , usize ) ) {
260
+ fn each_page < E > (
261
+ module : & Module ,
262
+ address : u32 ,
263
+ length : u32 ,
264
+ callback : impl FnMut ( u32 , usize , usize , usize ) -> Result < ( ) , E > ,
265
+ ) -> Result < ( ) , E > {
257
266
let page_size = module. memory_map ( ) . page_size ( ) ;
258
267
let page_address_lo = module. round_to_page_size_down ( address) ;
259
268
let page_address_hi = module. round_to_page_size_down ( address + ( length - 1 ) ) ;
260
269
each_page_impl ( page_size, page_address_lo, page_address_hi, address, length, callback)
261
270
}
262
271
263
- fn each_page_impl (
272
+ fn each_page_impl < E > (
264
273
page_size : u32 ,
265
274
page_address_lo : u32 ,
266
275
page_address_hi : u32 ,
267
276
address : u32 ,
268
277
length : u32 ,
269
- mut callback : impl FnMut ( u32 , usize , usize , usize ) ,
270
- ) {
278
+ mut callback : impl FnMut ( u32 , usize , usize , usize ) -> Result < ( ) , E > ,
279
+ ) -> Result < ( ) , E > {
271
280
let page_size = cast ( page_size) . to_usize ( ) ;
272
281
let length = cast ( length) . to_usize ( ) ;
273
282
274
283
let initial_page_offset = cast ( address) . to_usize ( ) - cast ( page_address_lo) . to_usize ( ) ;
275
284
let initial_chunk_length = core:: cmp:: min ( length, page_size - initial_page_offset) ;
276
- callback ( page_address_lo, initial_page_offset, 0 , initial_chunk_length) ;
285
+ callback ( page_address_lo, initial_page_offset, 0 , initial_chunk_length) ? ;
277
286
278
287
if page_address_lo == page_address_hi {
279
- return ;
288
+ return Ok ( ( ) ) ;
280
289
}
281
290
282
291
let mut page_address_lo = cast ( page_address_lo) . to_u64 ( ) ;
283
292
let page_address_hi = cast ( page_address_hi) . to_u64 ( ) ;
284
293
page_address_lo += cast ( page_size) . to_u64 ( ) ;
285
294
let mut buffer_offset = initial_chunk_length;
286
295
while page_address_lo < page_address_hi {
287
- callback ( cast ( page_address_lo) . assert_always_fits_in_u32 ( ) , 0 , buffer_offset, page_size) ;
296
+ callback ( cast ( page_address_lo) . assert_always_fits_in_u32 ( ) , 0 , buffer_offset, page_size) ? ;
288
297
buffer_offset += page_size;
289
298
page_address_lo += cast ( page_size) . to_u64 ( ) ;
290
299
}
@@ -304,16 +313,18 @@ fn test_each_page() {
304
313
let page_address_lo = address / page_size * page_size;
305
314
let page_address_hi = ( address + ( length - 1 ) ) / page_size * page_size;
306
315
let mut output = Vec :: new ( ) ;
307
- each_page_impl (
316
+ each_page_impl :: < ( ) > (
308
317
page_size,
309
318
page_address_lo,
310
319
page_address_hi,
311
320
address,
312
321
length,
313
322
|page_address, page_offset, buffer_offset, length| {
314
323
output. push ( ( page_address, page_offset, buffer_offset, length) ) ;
324
+ Ok ( ( ) )
315
325
} ,
316
- ) ;
326
+ )
327
+ . unwrap ( ) ;
317
328
output
318
329
}
319
330
@@ -448,6 +459,11 @@ impl InterpretedInstance {
448
459
self . next_program_counter_changed = true ;
449
460
}
450
461
462
+ pub fn accessible_aux_size ( & self ) -> u32 {
463
+ assert ! ( !self . module. is_dynamic_paging( ) ) ;
464
+ self . basic_memory . accessible_aux_size ( )
465
+ }
466
+
451
467
pub fn set_accessible_aux_size ( & mut self , size : u32 ) {
452
468
assert ! ( !self . module. is_dynamic_paging( ) ) ;
453
469
self . basic_memory . set_accessible_aux_size ( size) ;
@@ -458,6 +474,21 @@ impl InterpretedInstance {
458
474
None
459
475
}
460
476
477
+ pub fn is_memory_accessible ( & self , address : u32 , size : u32 , _is_writable : bool ) -> bool {
478
+ assert ! ( self . module. is_dynamic_paging( ) ) ;
479
+
480
+ // TODO: This is very slow.
481
+ let result = each_page ( & self . module , address, size, |page_address, _, _, _| {
482
+ if !self . dynamic_memory . pages . contains_key ( & page_address) {
483
+ Err ( ( ) )
484
+ } else {
485
+ Ok ( ( ) )
486
+ }
487
+ } ) ;
488
+
489
+ result. is_ok ( )
490
+ }
491
+
461
492
pub fn read_memory_into < ' slice > (
462
493
& self ,
463
494
address : u32 ,
@@ -491,12 +522,16 @@ impl InterpretedInstance {
491
522
if let Some ( page) = page {
492
523
let src = page. as_ptr ( ) . add ( page_offset) ;
493
524
core:: ptr:: copy_nonoverlapping ( src, dst, length) ;
525
+ Ok ( ( ) )
494
526
} else {
495
- core:: ptr:: write_bytes ( dst, 0 , length) ;
527
+ Err ( MemoryAccessError :: OutOfRangeAccess {
528
+ address : page_address + cast ( page_offset) . assert_always_fits_in_u32 ( ) ,
529
+ length : cast ( length) . to_u64 ( ) ,
530
+ } )
496
531
}
497
532
}
498
533
} ,
499
- ) ;
534
+ ) ? ;
500
535
501
536
// SAFETY: The buffer was initialized.
502
537
Ok ( unsafe { slice_assume_init_mut ( buffer) } )
@@ -519,15 +554,17 @@ impl InterpretedInstance {
519
554
} else {
520
555
let dynamic_memory = & mut self . dynamic_memory ;
521
556
let page_size = self . module . memory_map ( ) . page_size ( ) ;
522
- each_page (
557
+ each_page :: < ( ) > (
523
558
& self . module ,
524
559
address,
525
560
cast ( data. len ( ) ) . assert_always_fits_in_u32 ( ) ,
526
561
move |page_address, page_offset, buffer_offset, length| {
527
562
let page = dynamic_memory. pages . entry ( page_address) . or_insert_with ( || empty_page ( page_size) ) ;
528
563
page[ page_offset..page_offset + length] . copy_from_slice ( & data[ buffer_offset..buffer_offset + length] ) ;
564
+ Ok ( ( ) )
529
565
} ,
530
- ) ;
566
+ )
567
+ . unwrap ( ) ;
531
568
}
532
569
533
570
Ok ( ( ) )
@@ -546,20 +583,23 @@ impl InterpretedInstance {
546
583
} else {
547
584
let dynamic_memory = & mut self . dynamic_memory ;
548
585
let page_size = self . module . memory_map ( ) . page_size ( ) ;
549
- each_page (
586
+ each_page :: < ( ) > (
550
587
& self . module ,
551
588
address,
552
589
length,
553
590
move |page_address, page_offset, _, length| match dynamic_memory. pages . entry ( page_address) {
554
591
Entry :: Occupied ( mut entry) => {
555
592
let page = entry. get_mut ( ) ;
556
593
page[ page_offset..page_offset + length] . fill ( 0 ) ;
594
+ Ok ( ( ) )
557
595
}
558
596
Entry :: Vacant ( entry) => {
559
597
entry. insert ( empty_page ( page_size) ) ;
598
+ Ok ( ( ) )
560
599
}
561
600
} ,
562
- ) ;
601
+ )
602
+ . unwrap ( ) ;
563
603
}
564
604
565
605
Ok ( ( ) )
@@ -573,9 +613,11 @@ impl InterpretedInstance {
573
613
todo ! ( )
574
614
} else {
575
615
let dynamic_memory = & mut self . dynamic_memory ;
576
- each_page ( & self . module , address, length, move |page_address, _, _, _| {
616
+ each_page :: < ( ) > ( & self . module , address, length, move |page_address, _, _, _| {
577
617
dynamic_memory. pages . remove ( & page_address) ;
578
- } ) ;
618
+ Ok ( ( ) )
619
+ } )
620
+ . unwrap ( ) ;
579
621
}
580
622
}
581
623
0 commit comments