1
+ use core:: { cmp:: min, fmt, ops:: Range } ;
1
2
use revm_primitives:: { B256 , U256 } ;
2
-
3
- use core:: {
4
- cmp:: min,
5
- fmt,
6
- ops:: { BitAnd , Not , Range } ,
7
- } ;
8
3
use std:: vec:: Vec ;
9
4
10
5
/// A sequential memory shared between calls, which uses
@@ -128,6 +123,12 @@ impl SharedMemory {
128
123
self . len ( ) == 0
129
124
}
130
125
126
+ /// Returns the gas cost for the current memory expansion.
127
+ #[ inline]
128
+ pub fn current_expansion_cost ( & self ) -> u64 {
129
+ crate :: gas:: memory_gas_for_len ( self . len ( ) )
130
+ }
131
+
131
132
/// Resizes the memory in-place so that `len` is equal to `new_len`.
132
133
#[ inline]
133
134
pub fn resize ( & mut self , new_size : usize ) {
@@ -145,21 +146,18 @@ impl SharedMemory {
145
146
self . slice_range ( offset..offset + size)
146
147
}
147
148
149
+ /// Returns a byte slice of the memory region at the given offset.
150
+ ///
151
+ /// # Panics
152
+ ///
153
+ /// Panics on out of bounds.
148
154
#[ inline]
149
155
#[ cfg_attr( debug_assertions, track_caller) ]
150
- pub fn slice_range ( & self , range : Range < usize > ) -> & [ u8 ] {
151
- let last_checkpoint = self . last_checkpoint ;
152
-
153
- self . buffer
154
- . get ( last_checkpoint + range. start ..last_checkpoint + range. end )
155
- . unwrap_or_else ( || {
156
- debug_unreachable ! (
157
- "slice OOB: {}..{}; len: {}" ,
158
- range. start,
159
- range. end,
160
- self . len( )
161
- )
162
- } )
156
+ pub fn slice_range ( & self , range @ Range { start, end } : Range < usize > ) -> & [ u8 ] {
157
+ match self . context_memory ( ) . get ( range) {
158
+ Some ( slice) => slice,
159
+ None => debug_unreachable ! ( "slice OOB: {start}..{end}; len: {}" , self . len( ) ) ,
160
+ }
163
161
}
164
162
165
163
/// Returns a byte slice of the memory region at the given offset.
@@ -170,13 +168,11 @@ impl SharedMemory {
170
168
#[ inline]
171
169
#[ cfg_attr( debug_assertions, track_caller) ]
172
170
pub fn slice_mut ( & mut self , offset : usize , size : usize ) -> & mut [ u8 ] {
173
- let len = self . len ( ) ;
174
171
let end = offset + size;
175
- let last_checkpoint = self . last_checkpoint ;
176
-
177
- self . buffer
178
- . get_mut ( last_checkpoint + offset..last_checkpoint + offset + size)
179
- . unwrap_or_else ( || debug_unreachable ! ( "slice OOB: {offset}..{end}; len: {}" , len) )
172
+ match self . context_memory_mut ( ) . get_mut ( offset..end) {
173
+ Some ( slice) => slice,
174
+ None => debug_unreachable ! ( "slice OOB: {offset}..{end}" ) ,
175
+ }
180
176
}
181
177
182
178
/// Returns the byte at the given offset.
@@ -312,37 +308,28 @@ impl SharedMemory {
312
308
}
313
309
}
314
310
315
- /// Rounds up `x` to the closest multiple of 32. If `x % 32 == 0` then `x` is returned. Note, if `x`
316
- /// is greater than `usize::MAX - 31` this will return `usize::MAX` which isn't a multiple of 32 .
311
+ /// Returns number of words what would fit to provided number of bytes,
312
+ /// i.e. it rounds up the number bytes to number of words .
317
313
#[ inline]
318
- pub fn next_multiple_of_32 ( x : usize ) -> usize {
319
- let r = x. bitand ( 31 ) . not ( ) . wrapping_add ( 1 ) . bitand ( 31 ) ;
320
- x. saturating_add ( r)
314
+ pub const fn num_words ( len : u64 ) -> u64 {
315
+ len. saturating_add ( 31 ) / 32
321
316
}
322
317
323
318
#[ cfg( test) ]
324
319
mod tests {
325
320
use super :: * ;
326
321
327
322
#[ test]
328
- fn test_next_multiple_of_32 ( ) {
329
- // next_multiple_of_32 returns x when it is a multiple of 32
330
- for i in 0 ..32 {
331
- let x = i * 32 ;
332
- assert_eq ! ( x, next_multiple_of_32( x) ) ;
333
- }
334
-
335
- // next_multiple_of_32 rounds up to the nearest multiple of 32 when `x % 32 != 0`
336
- for x in 0 ..1024 {
337
- if x % 32 == 0 {
338
- continue ;
339
- }
340
- let next_multiple = x + 32 - ( x % 32 ) ;
341
- assert_eq ! ( next_multiple, next_multiple_of_32( x) ) ;
342
- }
343
-
344
- // We expect large values to saturate and not overflow.
345
- assert_eq ! ( usize :: MAX , next_multiple_of_32( usize :: MAX ) ) ;
323
+ fn test_num_words ( ) {
324
+ assert_eq ! ( num_words( 0 ) , 0 ) ;
325
+ assert_eq ! ( num_words( 1 ) , 1 ) ;
326
+ assert_eq ! ( num_words( 31 ) , 1 ) ;
327
+ assert_eq ! ( num_words( 32 ) , 1 ) ;
328
+ assert_eq ! ( num_words( 33 ) , 2 ) ;
329
+ assert_eq ! ( num_words( 63 ) , 2 ) ;
330
+ assert_eq ! ( num_words( 64 ) , 2 ) ;
331
+ assert_eq ! ( num_words( 65 ) , 3 ) ;
332
+ assert_eq ! ( num_words( u64 :: MAX ) , u64 :: MAX / 32 ) ;
346
333
}
347
334
348
335
#[ test]
0 commit comments