File tree 4 files changed +32
-18
lines changed
4 files changed +32
-18
lines changed Original file line number Diff line number Diff line change @@ -28,17 +28,11 @@ pub fn calldataload(state: &mut Machine) -> Control {
28
28
pop_u256 ! ( state, index) ;
29
29
trace_op ! ( "CallDataLoad: {}" , index) ;
30
30
31
+ let index = as_usize_or_fail ! ( index) ;
32
+ let len = if index > state. data . len ( ) { 0 } else { min ( 32 , state. data . len ( ) - index) } ;
33
+
31
34
let mut load = [ 0u8 ; 32 ] ;
32
- for i in 0 ..32 {
33
- if let Some ( p) = index. checked_add ( U256 :: from ( i) ) {
34
- if p <= U256 :: from ( usize:: max_value ( ) ) {
35
- let p = p. as_usize ( ) ;
36
- if p < state. data . len ( ) {
37
- load[ i] = state. data [ p] ;
38
- }
39
- }
40
- }
41
- }
35
+ load[ 0 ..len] . copy_from_slice ( & state. data [ index..index + len] ) ;
42
36
43
37
push ! ( state, H256 :: from( load) ) ;
44
38
Control :: Continue ( 1 )
@@ -153,7 +147,7 @@ pub fn msize(state: &mut Machine) -> Control {
153
147
154
148
pub fn push ( state : & mut Machine , n : usize , position : usize ) -> Control {
155
149
let end = min ( position + 1 + n, state. code . len ( ) ) ;
156
- let val = U256 :: from ( & state. code [ ( position + 1 ) ..end] ) ;
150
+ let val = U256 :: from_big_endian_fast ( & state. code [ ( position + 1 ) ..end] ) ;
157
151
158
152
push_u256 ! ( state, val) ;
159
153
trace_op ! ( "Push [@{}]: {}" , state. stack. len( ) - 1 , val) ;
Original file line number Diff line number Diff line change @@ -171,4 +171,26 @@ impl<'de> serde::Deserialize<'de> for U256 {
171
171
172
172
deserializer. deserialize_bytes ( Visitor )
173
173
}
174
+ }
175
+
176
+
177
+ impl U256 {
178
+ pub fn into_big_endian_fast ( self , buffer : & mut [ u8 ] ) {
179
+ let data: [ u8 ; 32 ] = unsafe { core:: mem:: transmute ( self ) } ;
180
+
181
+ let buffer = & mut buffer[ 0 ..32 ] ;
182
+ buffer. copy_from_slice ( & data[ ..] ) ;
183
+ buffer. reverse ( ) ;
184
+ }
185
+
186
+ pub fn from_big_endian_fast ( buffer : & [ u8 ] ) -> U256 {
187
+ assert ! ( 32 >= buffer. len( ) ) ;
188
+
189
+ let mut data = [ 0u8 ; 32 ] ;
190
+
191
+ data[ 32 - buffer. len ( ) ..32 ] . copy_from_slice ( buffer) ;
192
+ data. reverse ( ) ;
193
+
194
+ unsafe { core:: mem:: transmute ( data) }
195
+ }
174
196
}
Original file line number Diff line number Diff line change @@ -83,7 +83,7 @@ impl Stack {
83
83
self . data . pop ( )
84
84
. map ( |d| {
85
85
let mut value = H256 :: default ( ) ;
86
- d. to_big_endian ( & mut value[ ..] ) ;
86
+ d. into_big_endian_fast ( & mut value[ ..] ) ;
87
87
value
88
88
} )
89
89
. ok_or ( ExitError :: StackUnderflow )
@@ -95,7 +95,7 @@ impl Stack {
95
95
if self . data . len ( ) + 1 > self . limit {
96
96
return Err ( ExitError :: StackOverflow )
97
97
}
98
- self . data . push ( U256 :: from_big_endian ( & value[ ..] ) ) ;
98
+ self . data . push ( U256 :: from_big_endian_fast ( & value[ ..] ) ) ;
99
99
Ok ( ( ) )
100
100
}
101
101
Original file line number Diff line number Diff line change @@ -21,8 +21,8 @@ macro_rules! pop {
21
21
macro_rules! pop_u256 {
22
22
( $machine: expr, $( $x: ident ) ,* ) => (
23
23
$(
24
- let $x = match $machine. machine. stack_mut( ) . pop ( ) {
25
- Ok ( value) => U256 :: from_big_endian ( & value[ .. ] ) ,
24
+ let $x = match $machine. machine. stack_mut( ) . pop_u256 ( ) {
25
+ Ok ( value) => value,
26
26
Err ( e) => return Control :: Exit ( e. into( ) ) ,
27
27
} ;
28
28
) *
@@ -43,9 +43,7 @@ macro_rules! push {
43
43
macro_rules! push_u256 {
44
44
( $machine: expr, $( $x: expr ) ,* ) => (
45
45
$(
46
- let mut value = H256 :: default ( ) ;
47
- $x. to_big_endian( & mut value[ ..] ) ;
48
- match $machine. machine. stack_mut( ) . push( value) {
46
+ match $machine. machine. stack_mut( ) . push_u256( $x) {
49
47
Ok ( ( ) ) => ( ) ,
50
48
Err ( e) => return Control :: Exit ( e. into( ) ) ,
51
49
}
You can’t perform that action at this time.
0 commit comments