@@ -70,14 +70,14 @@ fn load_sw() {
7070 Ok ( ( ) )
7171 } ) ?;
7272
73- prop_assert_eq ! ( output, value) ;
73+ prop_assert_eq ! ( output, value, "expected 0x{:x}; found 0x{:x}" , value , output , ) ;
7474
7575 Ok ( ( ) )
7676 } ) ;
7777
7878 match res {
79- Err ( TestError :: Fail ( _ , value) ) => {
80- panic ! ( "Found minimal(shrinked) failing case: {value:?}" ) ;
79+ Err ( TestError :: Fail ( reason , value) ) => {
80+ panic ! ( "FAILURE: {} \n Minimal failing case: {value:?}" , reason . message ( ) ) ;
8181 }
8282 Ok ( _) => ( ) ,
8383 _ => panic ! ( "Unexpected test result: {res:?}" ) ,
@@ -111,28 +111,35 @@ fn load_dw() {
111111 let config = proptest:: test_runner:: Config :: with_cases ( 10 ) ;
112112 let res = TestRunner :: new ( config) . run ( & any :: < u64 > ( ) , move |value| {
113113 // Write `value` to the start of the 17th page (1 page after the 16 pages reserved for the
114- // Rust stack)
114+ // Rust stack). Felts must be written in little endian order.
115115 let value_felts = value. to_felts ( ) ;
116116 let initializers = [ Initializer :: MemoryFelts {
117117 addr : write_to / 4 ,
118- felts : Cow :: Borrowed ( value_felts. as_slice ( ) ) ,
118+ felts : Cow :: Borrowed ( & [ value_felts[ 1 ] , value_felts [ 0 ] ] ) ,
119119 } ] ;
120120
121121 let args = [ Felt :: new ( write_to as u64 ) ] ;
122122 let output =
123123 eval_package :: < u64 , _ , _ > ( & package, initializers, & args, context. session ( ) , |trace| {
124- let hi =
125- trace. read_memory_element ( write_to / 4 ) . unwrap_or_default ( ) . as_int ( ) as u32 ;
126- let lo = trace. read_memory_element ( ( write_to / 4 ) + 1 ) . unwrap_or_default ( ) . as_int ( )
127- as u32 ;
124+ let lo = trace. read_memory_element ( write_to / 4 ) . unwrap_or_default ( ) . as_int ( ) ;
125+ let hi = trace. read_memory_element ( ( write_to / 4 ) + 1 ) . unwrap_or_default ( ) . as_int ( ) ;
126+
128127 log:: trace!( target: "executor" , "hi = {hi} ({hi:0x})" ) ;
129128 log:: trace!( target: "executor" , "lo = {lo} ({lo:0x})" ) ;
130- let stored = trace. read_from_rust_memory :: < u64 > ( write_to) . ok_or_else ( || {
129+
130+ prop_assert_eq ! ( lo, value & 0xffffffff ) ;
131+ prop_assert_eq ! ( hi, value >> 32 ) ;
132+
133+ let mut stored = trace. read_from_rust_memory :: < u64 > ( write_to) . ok_or_else ( || {
131134 TestCaseError :: fail ( format ! (
132135 "expected {value} to have been written to byte address {write_to}, but \
133136 read from that address failed"
134137 ) )
135138 } ) ?;
139+
140+ // read_from_rust_memory() still reads in big-endian limbs.
141+ stored = ( ( stored >> 32 ) & 0xffffffff ) | ( stored << 32 ) ;
142+
136143 prop_assert_eq ! (
137144 stored,
138145 value,
@@ -145,14 +152,14 @@ fn load_dw() {
145152 Ok ( ( ) )
146153 } ) ?;
147154
148- prop_assert_eq ! ( output, value) ;
155+ prop_assert_eq ! ( output, value, "expected 0x{:x}; found 0x{:x}" , value , output , ) ;
149156
150157 Ok ( ( ) )
151158 } ) ;
152159
153160 match res {
154- Err ( TestError :: Fail ( _ , value) ) => {
155- panic ! ( "Found minimal(shrinked) failing case: {value:?}" ) ;
161+ Err ( TestError :: Fail ( reason , value) ) => {
162+ panic ! ( "FAILURE: {} \n Minimal failing case: {value:?}" , reason . message ( ) ) ;
156163 }
157164 Ok ( _) => ( ) ,
158165 _ => panic ! ( "Unexpected test result: {res:?}" ) ,
@@ -214,14 +221,14 @@ fn load_u8() {
214221 Ok ( ( ) )
215222 } ) ?;
216223
217- prop_assert_eq ! ( output, value) ;
224+ prop_assert_eq ! ( output, value, "expected 0x{:x}; found 0x{:x}" , value , output , ) ;
218225
219226 Ok ( ( ) )
220227 } ) ;
221228
222229 match res {
223- Err ( TestError :: Fail ( _ , value) ) => {
224- panic ! ( "Found minimal(shrinked) failing case: {value:?}" ) ;
230+ Err ( TestError :: Fail ( reason , value) ) => {
231+ panic ! ( "FAILURE: {} \n Minimal failing case: {value:?}" , reason . message ( ) ) ;
225232 }
226233 Ok ( _) => ( ) ,
227234 _ => panic ! ( "Unexpected test result: {res:?}" ) ,
@@ -283,14 +290,14 @@ fn load_u16() {
283290 Ok ( ( ) )
284291 } ) ?;
285292
286- prop_assert_eq ! ( output, value) ;
293+ prop_assert_eq ! ( output, value, "expected 0x{:x}; found 0x{:x}" , value , output , ) ;
287294
288295 Ok ( ( ) )
289296 } ) ;
290297
291298 match res {
292- Err ( TestError :: Fail ( _ , value) ) => {
293- panic ! ( "Found minimal(shrinked) failing case: {value:?}" ) ;
299+ Err ( TestError :: Fail ( reason , value) ) => {
300+ panic ! ( "FAILURE: {} \n Minimal failing case: {value:?}" , reason . message ( ) ) ;
294301 }
295302 Ok ( _) => ( ) ,
296303 _ => panic ! ( "Unexpected test result: {res:?}" ) ,
@@ -358,14 +365,14 @@ fn load_bool() {
358365 } ,
359366 ) ?;
360367
361- prop_assert_eq ! ( output, value) ;
368+ prop_assert_eq ! ( output, value, "expected {}; found {}" , output , value ) ;
362369
363370 Ok ( ( ) )
364371 } ) ;
365372
366373 match res {
367- Err ( TestError :: Fail ( _ , value) ) => {
368- panic ! ( "Found minimal(shrinked) failing case: {value:?}" ) ;
374+ Err ( TestError :: Fail ( reason , value) ) => {
375+ panic ! ( "FAILURE: {} \n Minimal failing case: {value:?}" , reason . message ( ) ) ;
369376 }
370377 Ok ( _) => ( ) ,
371378 _ => panic ! ( "Unexpected test result: {res:?}" ) ,
@@ -502,8 +509,8 @@ fn store_u16() {
502509 ) ;
503510
504511 match res {
505- Err ( TestError :: Fail ( _ , value) ) => {
506- panic ! ( "Found minimal(shrinked) failing case: {value:?}" ) ;
512+ Err ( TestError :: Fail ( reason , value) ) => {
513+ panic ! ( "FAILURE: {} \n Minimal failing case: {value:?}" , reason . message ( ) ) ;
507514 }
508515 Ok ( _) => ( ) ,
509516 _ => panic ! ( "Unexpected test result: {res:?}" ) ,
@@ -724,8 +731,8 @@ fn store_u8() {
724731 ) ;
725732
726733 match res {
727- Err ( TestError :: Fail ( _ , value) ) => {
728- panic ! ( "Found minimal(shrinked) failing case: {value:?}" ) ;
734+ Err ( TestError :: Fail ( reason , value) ) => {
735+ panic ! ( "FAILURE: {} \n Minimal failing case: {value:?}" , reason . message ( ) ) ;
729736 }
730737 Ok ( _) => ( ) ,
731738 _ => panic ! ( "Unexpected test result: {res:?}" ) ,
@@ -821,15 +828,80 @@ fn store_unaligned_u32() {
821828 run_test ( 3 , 0xaa332211 , 0x88ddccbb ) ;
822829}
823830
831+ #[ test]
832+ fn load_unaligned_u64 ( ) {
833+ // Use the start of the 17th page (1 page after the 16 pages reserved for the Rust stack)
834+ let write_to = 17 * 2u32 . pow ( 16 ) ;
835+
836+ // Generate a `test` module with `main` function that loads from `write_to` + a passed offset.
837+ let signature = Signature :: new ( [ AbiParam :: new ( Type :: U32 ) ] , [ AbiParam :: new ( Type :: U64 ) ] ) ;
838+
839+ // Compile once outside the test loop
840+ let ( package, context) = compile_test_module ( signature, |builder| {
841+ let block = builder. current_block ( ) ;
842+
843+ // Get the offset, add it to the base address and load the 64bit value there.
844+ let offs = block. borrow ( ) . arguments ( ) [ 0 ] as ValueRef ;
845+ let base_addr = builder. u32 ( write_to, SourceSpan :: default ( ) ) ;
846+ let read_addr = builder. add ( base_addr, offs, SourceSpan :: default ( ) ) . unwrap ( ) ;
847+ let ptr = builder
848+ . inttoptr ( read_addr, Type :: from ( PointerType :: new ( Type :: U64 ) ) , SourceSpan :: default ( ) )
849+ . unwrap ( ) ;
850+ let loaded = builder. load ( ptr, SourceSpan :: default ( ) ) . unwrap ( ) ;
851+
852+ // Return the value so we can assert that the output of execution matches
853+ builder. ret ( Some ( loaded) , SourceSpan :: default ( ) ) . unwrap ( ) ;
854+ } ) ;
855+
856+ let run_test = |offs : u32 , expected : u64 | {
857+ // Initialise memory with some known bytes.
858+ let initializers = [ Initializer :: MemoryBytes {
859+ addr : write_to,
860+ bytes : & [
861+ 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 , 0x08 , 0x11 , 0x12 , 0x13 , 0x14 , 0x15 , 0x16 ,
862+ 0x17 , 0x18 ,
863+ ] ,
864+ } ] ;
865+
866+ let output = eval_package :: < u64 , _ , _ > (
867+ & package,
868+ initializers,
869+ & [ Felt :: new ( offs as u64 ) ] ,
870+ context. session ( ) ,
871+ |trace| {
872+ //
873+ let stack = trace. outputs ( ) ;
874+ let hi: u64 = stack. get_stack_item ( 0 ) . unwrap ( ) . into ( ) ;
875+ let lo: u64 = stack. get_stack_item ( 1 ) . unwrap ( ) . into ( ) ;
876+
877+ eprintln ! ( "hi limb = 0x{hi:08x}" ) ;
878+ eprintln ! ( "lo limb = 0x{lo:08x}" ) ;
879+
880+ Ok ( ( ) )
881+ } ,
882+ )
883+ . unwrap ( ) ;
884+
885+ assert_eq ! ( output, expected) ;
886+ } ;
887+
888+ run_test ( 0 , 0x0807060504030201_u64 ) ;
889+ run_test ( 1 , 0x1108070605040302_u64 ) ;
890+ run_test ( 2 , 0x1211080706050403_u64 ) ;
891+ run_test ( 3 , 0x1312110807060504_u64 ) ;
892+ run_test ( 4 , 0x1413121108070605_u64 ) ;
893+ run_test ( 5 , 0x1514131211080706_u64 ) ;
894+ run_test ( 6 , 0x1615141312110807_u64 ) ;
895+ run_test ( 7 , 0x1716151413121108_u64 ) ;
896+ }
897+
824898#[ test]
825899fn store_unaligned_u64 ( ) {
826900 // Use the start of the 17th page (1 page after the 16 pages reserved for the Rust stack)
827901 let write_to = 17 * 2u32 . pow ( 16 ) ;
828902
829- // STORE_DW writes the high 32bit word to address and low 32bit word to address+1.
830- // So a .store() of 0xddccbbaa_cdabffee writes 0xddccbbaa to addr and 0xcdabffee to addr+1.
831- // Which in turn will be little-endian bytes [ AA BB CC DD EE FF AB CD ] at addr.
832- let write_val = 0xddccbbaa_cdabffee_u64 ;
903+ // Value which in turn will be little-endian bytes [ AA BB CC DD EE FF AB CD ] at addr.
904+ let write_val = 0xcdabffee_ddccbbaa_u64 ;
833905
834906 // Generate a `test` module with `main` function that stores to a u32 offset.
835907 let signature = Signature :: new (
@@ -917,6 +989,12 @@ fn store_unaligned_u64() {
917989 assert_eq ! ( output, 1 ) ;
918990 } ;
919991
992+ // Overwrite 01 02 03 04 05 06 07 08-11 12 13 14 15 16 17 18
993+ // with bytes aa bb cc dd ee ff ab cd at offset 0:
994+ // Expect aa bb cc dd ee ff ab cd 11 12 13 14 15 16 17 18
995+ // or 0xccbbaa01, 0xabffeedd, 0x141312cd, 0x18171615
996+ run_test ( 0 , 0xddccbbaa , 0xcdabffee , 0x14131211 , 0x18171615 ) ;
997+
920998 // Overwrite 01 02 03 04 05 06 07 08-11 12 13 14 15 16 17 18
921999 // with bytes aa bb cc dd ee ff ab cd at offset 1:
9221000 // Expect 01 aa bb cc dd ee ff ab cd 12 13 14 15 16 17 18
0 commit comments