@@ -30,102 +30,57 @@ impl<const IS_MSTORE8: bool> Opcode for Mstore<IS_MSTORE8> {
30
30
let value_pos = geth_step. stack . nth_last_filled ( 1 ) ;
31
31
state. stack_read ( & mut exec_step, value_pos, value) ?;
32
32
33
- // First mem write -> 32 MemoryOp generated.
34
- let offset_addr: MemoryAddress = offset. try_into ( ) ?;
35
- // TODO: get two memory words (slot, slot + 32) at address if offset != 0, otherwise get one
36
- // word at slot.
37
-
38
- let mut memory = state. call_ctx_mut ( ) ?. memory . clone ( ) ;
39
- // expand memory size + 64 as slot
40
- let minimal_length = offset_addr. 0
41
- + if IS_MSTORE8 {
42
- 1
43
- } else {
44
- 64 /* 32 */
45
- } ;
46
- println ! (
47
- "minimal_length {} , IS_MSTORE8 {}, memory_length {}, value {}" ,
48
- minimal_length,
49
- IS_MSTORE8 ,
50
- memory. 0 . len( ) ,
51
- value
52
- ) ;
53
-
54
- memory. extend_at_least ( minimal_length) ;
55
-
56
- let offset_u64 = offset. as_u64 ( ) ;
33
+ let offset_u64 = offset. as_u64 ( ) as usize ;
57
34
let shift = offset_u64 % 32 ;
58
35
let slot = offset_u64 - shift;
59
36
println ! ( "shift {}, slot {}" , shift, slot) ;
60
- // reconstruct memory with value
61
- match IS_MSTORE8 {
62
- true => {
63
- //let bytes= *value.to_le_bytes().to_vec();
64
- let val = * value. to_le_bytes ( ) . first ( ) . unwrap ( ) ;
65
- let word_v8 = Word :: from ( val as u64 ) ;
66
- memory. 0 [ offset_u64 as usize ] = val;
67
- }
68
- false => {
69
- let bytes = value. to_be_bytes ( ) ;
70
- memory[ offset_u64 as usize ..offset_u64 as usize + 32 ] . copy_from_slice ( & bytes) ;
71
- }
72
- }
73
37
74
- // after memory construction, we can get slot_Word(left_Word), right_word to fill buss
75
- // mapping.
76
- let mut slot_bytes: [ u8 ; 32 ] = [ 0 ; 32 ] ;
77
- let mut addr_left_Word = Word :: zero ( ) ;
38
+ let ( left_word, right_word) = {
39
+ // Get the memory chunk that contains the word, starting at an aligned slot address.
40
+ let mut slots_content = state. call_ctx ( ) ?. memory . read_chunk ( slot. into ( ) , 64 . into ( ) ) ;
41
+
42
+ // reconstruct memory with value
43
+ match IS_MSTORE8 {
44
+ true => {
45
+ let val = * value. to_le_bytes ( ) . first ( ) . unwrap ( ) ;
46
+ slots_content[ shift] = val;
47
+ }
48
+ false => {
49
+ let bytes = value. to_be_bytes ( ) ;
50
+ slots_content[ shift..shift + 32 ] . copy_from_slice ( & bytes) ;
51
+ }
52
+ }
78
53
79
- if IS_MSTORE8 {
80
- let byte = * value. to_le_bytes ( ) . first ( ) . unwrap ( ) ;
81
- addr_left_Word = Word :: from ( byte as u64 ) ;
82
- } else {
83
- slot_bytes. clone_from_slice ( & memory. 0 [ ( slot as usize ) ..( slot as usize + 32 ) ] ) ;
84
- addr_left_Word = Word :: from_big_endian ( & slot_bytes) ;
85
- }
54
+ // after memory construction, we can get the left and right words to fill bus mapping.
55
+ (
56
+ Word :: from_big_endian ( & slots_content[ ..32 ] ) ,
57
+ Word :: from_big_endian ( & slots_content[ 32 ..64 ] ) ,
58
+ )
59
+ } ;
86
60
87
- // TODO: edge case: if shift = 0, no need to right word
88
- let mut word_right_bytes: [ u8 ; 32 ] = [ 0 ; 32 ] ;
89
- let cur_memory_size = memory. 0 . len ( ) ;
90
- // when is_msotre8, skip word_right as mstore8 only affect one word.
61
+ // memory write left word for mstore8 and mstore.
62
+ state. memory_write_word ( & mut exec_step, slot. into ( ) , left_word) ?;
91
63
92
- // construct right word
93
- let addr_right_Word = Word :: from_big_endian ( & word_right_bytes) ;
64
+ if !IS_MSTORE8 {
65
+ // memory write right word for mstore
66
+ state. memory_write_word ( & mut exec_step, ( slot + 32 ) . into ( ) , right_word) ?;
94
67
95
- // address = 100, slot = 96 shift = 4
96
- // value = address + 32 = 132
97
- // left word = slot ( 96...96+32 bytes) slot = 128...128+32 word(fill 0)
98
- match IS_MSTORE8 {
99
- true => {
100
- // memory write operation for mstore8
101
- state. memory_write_word ( & mut exec_step, slot. into ( ) , addr_left_Word) ?;
102
- }
103
- false => {
104
- // lookup left word
105
- state. memory_write_word ( & mut exec_step, slot. into ( ) , addr_left_Word) ?;
106
- // look up right word
107
- state. memory_write_word ( & mut exec_step, ( slot + 32 ) . into ( ) , addr_right_Word) ?;
108
- }
68
+ // TODO: edge case: if shift = 0, we could skip the right word?
109
69
}
110
70
111
71
// reconstruction
112
- let offset = geth_step. stack . nth_last ( 0 ) ?;
113
- let value = geth_step. stack . nth_last ( 1 ) ?;
114
- let offset_addr: MemoryAddress = offset. try_into ( ) ?;
115
72
116
- let minimal_length = offset_addr . 0 + if IS_MSTORE8 { 1 } else { 32 } ;
73
+ let minimal_length = offset_u64 + if IS_MSTORE8 { 1 } else { 32 } ;
117
74
state. call_ctx_mut ( ) ?. memory . extend_at_least ( minimal_length) ;
118
75
119
- let mem_starts = offset_addr. 0 ;
120
-
121
76
match IS_MSTORE8 {
122
77
true => {
123
78
let val = * value. to_le_bytes ( ) . first ( ) . unwrap ( ) ;
124
- state. call_ctx_mut ( ) ?. memory . 0 [ mem_starts ] = val;
79
+ state. call_ctx_mut ( ) ?. memory . 0 [ offset_u64 ] = val;
125
80
}
126
81
false => {
127
82
let bytes = value. to_be_bytes ( ) ;
128
- state. call_ctx_mut ( ) ?. memory [ mem_starts..mem_starts + 32 ] . copy_from_slice ( & bytes) ;
83
+ state. call_ctx_mut ( ) ?. memory [ offset_u64..offset_u64 + 32 ] . copy_from_slice ( & bytes) ;
129
84
}
130
85
}
131
86
0 commit comments