@@ -71,15 +71,15 @@ struct RVEmu {
7171
7272fn riscv_context ( frame : & Frame ) -> Option < RVEmu > {
7373 let interpreter = frame. interpreter ( ) ;
74- if matches ! ( interpreter . bytecode . get ( 0 ) , Some ( 0xFF ) ) {
75- let emu = setup_from_elf ( & interpreter. bytecode [ 1 .. ] , & interpreter . contract . input ) ;
76- Some ( RVEmu {
77- emu ,
78- returned_data_destiny : None ,
79- } )
80- } else {
81- None
82- }
74+
75+ let Some ( ( 0xFF , bytecode ) ) = interpreter. bytecode . split_first ( ) else {
76+ return None ;
77+ } ;
78+ let emu = setup_from_elf ( bytecode , & interpreter . contract . input ) ;
79+ Some ( RVEmu {
80+ emu ,
81+ returned_data_destiny : None ,
82+ } )
8383}
8484
8585pub fn handle_register < EXT , DB : Database > ( handler : & mut EvmHandler < ' _ , EXT , DB > ) {
@@ -133,7 +133,11 @@ fn execute_riscv(
133133 let emu = & mut rvemu. emu ;
134134 let returned_data_destiny = & mut rvemu. returned_data_destiny ;
135135 if let Some ( destiny) = std:: mem:: take ( returned_data_destiny) {
136- let data = emu. cpu . bus . get_dram_slice ( destiny) . unwrap ( ) ;
136+ let data = emu
137+ . cpu
138+ . bus
139+ . get_dram_slice ( destiny)
140+ . unwrap_or_else ( |e| panic ! ( "Unable to get destiny dram slice ({e:?})" ) ) ;
137141 data. copy_from_slice ( shared_memory. slice ( 0 , data. len ( ) ) )
138142 }
139143
@@ -154,18 +158,18 @@ fn execute_riscv(
154158 match run_result {
155159 Err ( Exception :: EnvironmentCallFromMMode ) => {
156160 let t0: u64 = emu. cpu . xregs . read ( 5 ) ;
157- match Syscall :: try_from ( t0 as u8 ) {
158- Ok ( Syscall :: Return ) => {
161+
162+ let Ok ( syscall) = Syscall :: try_from ( t0 as u8 ) else {
163+ println ! ( "Unhandled syscall: {:?}" , t0) ;
164+ return return_revert ( interpreter) ;
165+ } ;
166+
167+ match syscall {
168+ Syscall :: Return => {
159169 let ret_offset: u64 = emu. cpu . xregs . read ( 10 ) ;
160170 let ret_size: u64 = emu. cpu . xregs . read ( 11 ) ;
161- let data_bytes = if ret_size != 0 {
162- emu. cpu
163- . bus
164- . get_dram_slice ( ret_offset..( ret_offset + ret_size) )
165- . unwrap ( )
166- } else {
167- & mut [ ]
168- } ;
171+ let data_bytes = dram_slice ( emu, ret_offset, ret_size) ;
172+
169173 return InterpreterAction :: Return {
170174 result : InterpreterResult {
171175 result : InstructionResult :: Return ,
@@ -174,7 +178,7 @@ fn execute_riscv(
174178 } ,
175179 } ;
176180 }
177- Ok ( Syscall :: SLoad ) => {
181+ Syscall :: SLoad => {
178182 let key: u64 = emu. cpu . xregs . read ( 10 ) ;
179183 match host. sload ( interpreter. contract . target_address , U256 :: from ( key) ) {
180184 Some ( ( value, _is_cold) ) => {
@@ -185,7 +189,7 @@ fn execute_riscv(
185189 }
186190 }
187191 }
188- Ok ( Syscall :: SStore ) => {
192+ Syscall :: SStore => {
189193 let key: u64 = emu. cpu . xregs . read ( 10 ) ;
190194 let value: u64 = emu. cpu . xregs . read ( 11 ) ;
191195 host. sstore (
@@ -194,7 +198,7 @@ fn execute_riscv(
194198 U256 :: from ( value) ,
195199 ) ;
196200 }
197- Ok ( Syscall :: Call ) => {
201+ Syscall :: Call => {
198202 let a0: u64 = emu. cpu . xregs . read ( 10 ) ;
199203 let address =
200204 Address :: from_slice ( emu. cpu . bus . get_dram_slice ( a0..( a0 + 20 ) ) . unwrap ( ) ) ;
@@ -230,7 +234,7 @@ fn execute_riscv(
230234 } ) ,
231235 } ;
232236 }
233- Ok ( Syscall :: Revert ) => {
237+ Syscall :: Revert => {
234238 return InterpreterAction :: Return {
235239 result : InterpreterResult {
236240 result : InstructionResult :: Revert ,
@@ -239,7 +243,7 @@ fn execute_riscv(
239243 } ,
240244 } ;
241245 }
242- Ok ( Syscall :: Caller ) => {
246+ Syscall :: Caller => {
243247 let caller = interpreter. contract . caller ;
244248 // Break address into 3 u64s and write to registers
245249 let caller_bytes = caller. as_slice ( ) ;
@@ -253,15 +257,10 @@ fn execute_riscv(
253257 let third_u64 = u64:: from_be_bytes ( padded_bytes) ;
254258 emu. cpu . xregs . write ( 12 , third_u64) ;
255259 }
256- Ok ( Syscall :: Keccak256 ) => {
257- let offset: u64 = emu. cpu . xregs . read ( 10 ) ;
258- let size: u64 = emu. cpu . xregs . read ( 11 ) ;
259-
260- let data_bytes = if size != 0 {
261- emu. cpu . bus . get_dram_slice ( offset..( offset + size) ) . unwrap ( )
262- } else {
263- & mut [ ]
264- } ;
260+ Syscall :: Keccak256 => {
261+ let ret_offset: u64 = emu. cpu . xregs . read ( 10 ) ;
262+ let ret_size: u64 = emu. cpu . xregs . read ( 11 ) ;
263+ let data_bytes = dram_slice ( emu, ret_offset, ret_size) ;
265264
266265 let mut hasher = Keccak256 :: new ( ) ;
267266 hasher. update ( data_bytes) ;
@@ -281,18 +280,14 @@ fn execute_riscv(
281280 . xregs
282281 . write ( 13 , u64:: from_le_bytes ( hash[ 24 ..32 ] . try_into ( ) . unwrap ( ) ) ) ;
283282 }
284- Ok ( Syscall :: CallValue ) => {
283+ Syscall :: CallValue => {
285284 let value = interpreter. contract . call_value ;
286285 let limbs = value. into_limbs ( ) ;
287286 emu. cpu . xregs . write ( 10 , limbs[ 0 ] ) ;
288287 emu. cpu . xregs . write ( 11 , limbs[ 1 ] ) ;
289288 emu. cpu . xregs . write ( 12 , limbs[ 2 ] ) ;
290289 emu. cpu . xregs . write ( 13 , limbs[ 3 ] ) ;
291290 }
292- _ => {
293- println ! ( "Unhandled syscall: {:?}" , t0) ;
294- return return_revert ( interpreter) ;
295- }
296291 }
297292 }
298293 _ => {
@@ -301,3 +296,15 @@ fn execute_riscv(
301296 }
302297 }
303298}
299+
300+ /// Returns RISC-V DRAM slice in a given size range, starts with a given offset
301+ fn dram_slice ( emu : & mut Emulator , ret_offset : u64 , ret_size : u64 ) -> & mut [ u8 ] {
302+ if ret_size != 0 {
303+ emu. cpu
304+ . bus
305+ . get_dram_slice ( ret_offset..( ret_offset + ret_size) )
306+ . unwrap ( )
307+ } else {
308+ & mut [ ]
309+ }
310+ }
0 commit comments