@@ -6,6 +6,7 @@ use midenc_hir::{
6
6
AbiParam , CallConv , Felt , FieldElement , FunctionIdent , Immediate , InstBuilder , Linkage ,
7
7
OperandStack , ProgramBuilder , Signature , SourceSpan , Stack , Type ,
8
8
} ;
9
+ use prop:: test_runner:: { Config , TestRunner } ;
9
10
use proptest:: prelude:: * ;
10
11
use smallvec:: { smallvec, SmallVec } ;
11
12
@@ -208,6 +209,10 @@ impl TestByEmulationHarness {
208
209
pub fn step_over ( & mut self ) -> Result < EmulatorEvent , EmulationError > {
209
210
self . emulator . step_over ( )
210
211
}
212
+
213
+ fn reset ( & mut self ) {
214
+ self . emulator . reset ( ) ;
215
+ }
211
216
}
212
217
213
218
#[ test]
@@ -453,6 +458,69 @@ fn i32_checked_neg() {
453
458
harness. invoke ( neg, & [ min] ) . expect ( "execution failed" ) ;
454
459
}
455
460
461
+ #[ test]
462
+ fn codegen_mem_store_sw_load_sw ( ) {
463
+ const MEMORY_SIZE_BYTES : u32 = 1048576 * 2 ; // Twice the size of the default Rust shadow stack size
464
+ const MEMORY_SIZE_VM_WORDS : u32 = MEMORY_SIZE_BYTES / 16 ;
465
+ let context = TestContext :: default ( ) ;
466
+ let mut builder = ProgramBuilder :: new ( & context. session . diagnostics ) ;
467
+ let mut mb = builder. module ( "test" ) ;
468
+ let id = {
469
+ let mut fb = mb
470
+ . function (
471
+ "store_load_sw" ,
472
+ Signature :: new (
473
+ [ AbiParam :: new ( Type :: U32 ) , AbiParam :: new ( Type :: U32 ) ] ,
474
+ [ AbiParam :: new ( Type :: U32 ) ] ,
475
+ ) ,
476
+ )
477
+ . expect ( "unexpected symbol conflict" ) ;
478
+ let entry = fb. current_block ( ) ;
479
+ let ( ptr_u32, value) = {
480
+ let args = fb. block_params ( entry) ;
481
+ ( args[ 0 ] , args[ 1 ] )
482
+ } ;
483
+ let ptr = fb. ins ( ) . inttoptr ( ptr_u32, Type :: Ptr ( Type :: U32 . into ( ) ) , SourceSpan :: UNKNOWN ) ;
484
+ fb. ins ( ) . store ( ptr, value, SourceSpan :: UNKNOWN ) ;
485
+ let loaded_value = fb. ins ( ) . load ( ptr, SourceSpan :: UNKNOWN ) ;
486
+ fb. ins ( ) . ret ( Some ( loaded_value) , SourceSpan :: UNKNOWN ) ;
487
+ fb. build ( ) . expect ( "unexpected error building function" )
488
+ } ;
489
+
490
+ mb. build ( ) . expect ( "unexpected error constructing test module" ) ;
491
+
492
+ let program = builder. with_entrypoint ( id) . link ( ) . expect ( "failed to link program" ) ;
493
+
494
+ let mut compiler = MasmCompiler :: new ( & context. session ) ;
495
+ let program = compiler. compile ( program) . expect ( "compilation failed" ) . freeze ( ) ;
496
+
497
+ // eprintln!("{}", program);
498
+
499
+ fn test ( program : Arc < Program > , ptr : u32 , value : u32 ) -> u32 {
500
+ eprintln ! ( "---------------------------------" ) ;
501
+ eprintln ! ( "testing store_sw/load_sw ptr: {ptr}, value: {value}" ) ;
502
+ eprintln ! ( "---------------------------------" ) ;
503
+ let mut harness = TestByEmulationHarness :: with_emulator_config (
504
+ MEMORY_SIZE_VM_WORDS as usize ,
505
+ Emulator :: DEFAULT_HEAP_START as usize ,
506
+ Emulator :: DEFAULT_LOCALS_START as usize ,
507
+ true ,
508
+ ) ;
509
+ let mut stack = harness
510
+ . execute_program ( program. clone ( ) , & [ Felt :: new ( ptr as u64 ) , Felt :: new ( value as u64 ) ] )
511
+ . expect ( "execution failed" ) ;
512
+ stack. pop ( ) . unwrap ( ) . as_int ( ) as u32
513
+ }
514
+
515
+ TestRunner :: new ( Config :: with_cases ( 1024 ) )
516
+ . run ( & ( 0u32 ..MEMORY_SIZE_BYTES - 4 , any :: < u32 > ( ) ) , move |( ptr, value) | {
517
+ let out = test ( program. clone ( ) , ptr, value) ;
518
+ prop_assert_eq ! ( out, value) ;
519
+ Ok ( ( ) )
520
+ } )
521
+ . unwrap ( ) ;
522
+ }
523
+
456
524
macro_rules! proptest_unary_numeric_op {
457
525
( $ty_name: ident :: $op: ident, $ty: ty => $ret: ty, $rust_op: ident) => {
458
526
proptest_unary_numeric_op_impl!( $ty_name :: $op, $ty => $ret, $rust_op, 0 ..$ty_name:: MAX ) ;
0 commit comments