@@ -32,7 +32,7 @@ use std::marker::PhantomData;
3232use action_params:: { ActionParams , ActionValue } ;
3333use types:: executed:: CallType ;
3434use evm:: instructions:: { self , Instruction , InstructionInfo } ;
35- use evm:: { self , MessageCallResult , ContractCreateResult , GasLeft , CostType , CreateContractAddress } ;
35+ use evm:: { self , MessageCallResult , ContractCreateResult , GasLeft , CostType , CreateContractAddress , ReturnData } ;
3636use bit_set:: BitSet ;
3737
3838use util:: * ;
@@ -102,6 +102,7 @@ enum InstructionResult<Gas> {
102102pub struct Interpreter < Cost : CostType > {
103103 mem : Vec < u8 > ,
104104 cache : Arc < SharedCache > ,
105+ return_data : ReturnData ,
105106 _type : PhantomData < Cost > ,
106107}
107108
@@ -166,9 +167,10 @@ impl<Cost: CostType> evm::Evm for Interpreter<Cost> {
166167 } ,
167168 InstructionResult :: StopExecutionNeedsReturn { gas, init_off, init_size, apply} => {
168169 informant. done ( ) ;
170+ let mem = mem:: replace ( & mut self . mem , Vec :: new ( ) ) ;
169171 return Ok ( GasLeft :: NeedsReturn {
170172 gas_left : gas. as_u256 ( ) ,
171- data : self . mem . read_slice ( init_off, init_size) ,
173+ data : mem. into_return_data ( usize :: from_u256 ( init_off) ? , usize :: from_u256 ( init_size) ? ) ,
172174 apply_state : apply
173175 } ) ;
174176 } ,
@@ -187,6 +189,7 @@ impl<Cost: CostType> Interpreter<Cost> {
187189 Interpreter {
188190 mem : Vec :: new ( ) ,
189191 cache : cache,
192+ return_data : ReturnData :: empty ( ) ,
190193 _type : PhantomData :: default ( ) ,
191194 }
192195 }
@@ -233,7 +236,7 @@ impl<Cost: CostType> Interpreter<Cost> {
233236 match instruction {
234237 instructions:: MSTORE | instructions:: MLOAD => Some ( ( stack. peek ( 0 ) . low_u64 ( ) as usize , 32 ) ) ,
235238 instructions:: MSTORE8 => Some ( ( stack. peek ( 0 ) . low_u64 ( ) as usize , 1 ) ) ,
236- instructions:: CALLDATACOPY | instructions:: CODECOPY => Some ( ( stack. peek ( 0 ) . low_u64 ( ) as usize , stack. peek ( 2 ) . low_u64 ( ) as usize ) ) ,
239+ instructions:: CALLDATACOPY | instructions:: CODECOPY | instructions :: RETURNDATACOPY => Some ( ( stack. peek ( 0 ) . low_u64 ( ) as usize , stack. peek ( 2 ) . low_u64 ( ) as usize ) ) ,
237240 instructions:: EXTCODECOPY => Some ( ( stack. peek ( 1 ) . low_u64 ( ) as usize , stack. peek ( 3 ) . low_u64 ( ) as usize ) ) ,
238241 instructions:: CALL | instructions:: CALLCODE => Some ( ( stack. peek ( 5 ) . low_u64 ( ) as usize , stack. peek ( 6 ) . low_u64 ( ) as usize ) ) ,
239242 instructions:: DELEGATECALL => Some ( ( stack. peek ( 4 ) . low_u64 ( ) as usize , stack. peek ( 5 ) . low_u64 ( ) as usize ) ) ,
@@ -362,8 +365,9 @@ impl<Cost: CostType> Interpreter<Cost> {
362365 } ;
363366
364367 return match call_result {
365- MessageCallResult :: Success ( gas_left) => {
368+ MessageCallResult :: Success ( gas_left, data ) => {
366369 stack. push ( U256 :: one ( ) ) ;
370+ self . return_data = data;
367371 Ok ( InstructionResult :: UnusedGas ( Cost :: from_u256 ( gas_left) . expect ( "Gas left cannot be greater then current one" ) ) )
368372 } ,
369373 MessageCallResult :: Failed => {
@@ -501,15 +505,18 @@ impl<Cost: CostType> Interpreter<Cost> {
501505 stack. push ( U256 :: from ( len) ) ;
502506 } ,
503507 instructions:: CALLDATACOPY => {
504- self . copy_data_to_memory ( stack, params. data . as_ref ( ) . map_or_else ( || & [ ] as & [ u8 ] , |d| & * d as & [ u8 ] ) ) ;
508+ Self :: copy_data_to_memory ( & mut self . mem , stack, params. data . as_ref ( ) . map_or_else ( || & [ ] as & [ u8 ] , |d| & * d as & [ u8 ] ) ) ;
509+ } ,
510+ instructions:: RETURNDATACOPY => {
511+ Self :: copy_data_to_memory ( & mut self . mem , stack, & * self . return_data ) ;
505512 } ,
506513 instructions:: CODECOPY => {
507- self . copy_data_to_memory ( stack, params. code . as_ref ( ) . map_or_else ( || & [ ] as & [ u8 ] , |c| & * * c as & [ u8 ] ) ) ;
514+ Self :: copy_data_to_memory ( & mut self . mem , stack, params. code . as_ref ( ) . map_or_else ( || & [ ] as & [ u8 ] , |c| & * * c as & [ u8 ] ) ) ;
508515 } ,
509516 instructions:: EXTCODECOPY => {
510517 let address = u256_to_address ( & stack. pop_back ( ) ) ;
511518 let code = ext. extcode ( & address) ?;
512- self . copy_data_to_memory ( stack, & code) ;
519+ Self :: copy_data_to_memory ( & mut self . mem , stack, & code) ;
513520 } ,
514521 instructions:: GASPRICE => {
515522 stack. push ( params. gas_price . clone ( ) ) ;
@@ -541,7 +548,7 @@ impl<Cost: CostType> Interpreter<Cost> {
541548 Ok ( InstructionResult :: Ok )
542549 }
543550
544- fn copy_data_to_memory ( & mut self , stack : & mut Stack < U256 > , source : & [ u8 ] ) {
551+ fn copy_data_to_memory ( mem : & mut Vec < u8 > , stack : & mut Stack < U256 > , source : & [ u8 ] ) {
545552 let dest_offset = stack. pop_back ( ) ;
546553 let source_offset = stack. pop_back ( ) ;
547554 let size = stack. pop_back ( ) ;
@@ -550,9 +557,9 @@ impl<Cost: CostType> Interpreter<Cost> {
550557 let output_end = match source_offset > source_size || size > source_size || source_offset + size > source_size {
551558 true => {
552559 let zero_slice = if source_offset > source_size {
553- self . mem . writeable_slice ( dest_offset, size)
560+ mem. writeable_slice ( dest_offset, size)
554561 } else {
555- self . mem . writeable_slice ( dest_offset + source_size - source_offset, source_offset + size - source_size)
562+ mem. writeable_slice ( dest_offset + source_size - source_offset, source_offset + size - source_size)
556563 } ;
557564 for i in zero_slice. iter_mut ( ) {
558565 * i = 0 ;
@@ -564,7 +571,7 @@ impl<Cost: CostType> Interpreter<Cost> {
564571
565572 if source_offset < source_size {
566573 let output_begin = source_offset. low_u64 ( ) as usize ;
567- self . mem . write_slice ( dest_offset, & source[ output_begin..output_end] ) ;
574+ mem. write_slice ( dest_offset, & source[ output_begin..output_end] ) ;
568575 }
569576 }
570577
0 commit comments