@@ -981,34 +981,61 @@ impl<F: Field> ExecutionGadget<F> for CallOpGadget<F> {
981
981
output_rws,
982
982
return_rws,
983
983
) = if is_precompiled ( & callee_address. to_address ( ) ) {
984
- let input_bytes_begin = cd_offset. as_usize ( ) ;
985
- let input_bytes_end = cd_offset. as_usize ( ) + cd_length. as_usize ( ) ;
986
- let input_bytes_begin_slot = input_bytes_begin - input_bytes_begin % 32 ;
987
- let input_bytes_end_slot = input_bytes_end - input_bytes_end % 32 ;
988
- let input_bytes_word_count = ( input_bytes_end_slot - input_bytes_begin_slot + 32 ) / 32 ;
989
- // input may not be aligned to 32 bytes. actual input is [start_offset..end_offset]
990
- let input_bytes_start_offset = input_bytes_begin - input_bytes_begin_slot;
991
- let input_bytes_end_offset = input_bytes_end - input_bytes_begin_slot;
992
-
993
- let output_bytes_end = precompile_return_length. as_usize ( ) ;
994
- let output_bytes_end_slot = output_bytes_end - output_bytes_end % 32 ;
995
- let output_bytes_word_count = ( output_bytes_end_slot + 32 ) / 32 ;
996
-
997
- let return_bytes_length = min ( rd_length. as_usize ( ) , output_bytes_end) ;
998
- let callee_memory_end_slot = return_bytes_length - return_bytes_length % 32 ;
999
- let return_bytes_begin = rd_offset. as_usize ( ) ;
1000
- let return_bytes_end = return_bytes_begin + return_bytes_length;
1001
- let return_bytes_begin_slot = return_bytes_begin - return_bytes_begin % 32 ;
1002
- let return_bytes_end_slot = return_bytes_end - return_bytes_end % 32 ;
1003
- let return_bytes_slot_count = max (
1004
- callee_memory_end_slot,
1005
- return_bytes_end_slot - return_bytes_begin_slot,
1006
- ) ;
1007
- let return_bytes_word_count = return_bytes_slot_count / 32 + 1 ;
1008
- // return data may not be aligned to 32 bytes. actual return data is
1009
- // [start_offset..end_offset]
1010
- let return_bytes_start_offset = return_bytes_begin - return_bytes_begin_slot;
1011
- let return_bytes_end_offset = return_bytes_end - return_bytes_begin_slot;
984
+ let [ input_bytes_start_offset, input_bytes_end_offset, input_bytes_word_count] =
985
+ // Correspond to this check in bus-mapping.
986
+ // <https://github.com/scroll-tech/zkevm-circuits/blob/25dd32aa316ec842ffe79bb8efe9f05f86edc33e/bus-mapping/src/evm/opcodes/callop.rs#L349>
987
+ if cd_length. is_zero ( ) {
988
+ [ 0 ; 3 ]
989
+ } else {
990
+ let begin = cd_offset. as_usize ( ) ;
991
+ let end = cd_offset. as_usize ( ) + cd_length. as_usize ( ) ;
992
+ let begin_slot = begin - begin % 32 ;
993
+ let end_slot = end - end % 32 ;
994
+
995
+ // input may not be aligned to 32 bytes. actual input is
996
+ // [start_offset..end_offset]
997
+ let start_offset = begin - begin_slot;
998
+ let end_offset = end - begin_slot;
999
+ let word_count = ( end_slot - begin_slot + 32 ) / 32 ;
1000
+
1001
+ [ start_offset, end_offset, word_count]
1002
+ } ;
1003
+
1004
+ let [ output_bytes_end, output_bytes_word_count] =
1005
+ // Correspond to this check in bus-mapping.
1006
+ // <https://github.com/scroll-tech/zkevm-circuits/blob/25dd32aa316ec842ffe79bb8efe9f05f86edc33e/bus-mapping/src/evm/opcodes/callop.rs#L387>
1007
+ if cd_length. is_zero ( ) || precompile_return_length. is_zero ( ) {
1008
+ [ 0 ; 2 ]
1009
+ } else {
1010
+ let end = precompile_return_length. as_usize ( ) ;
1011
+ let end_slot = end - end % 32 ;
1012
+
1013
+ [ end, ( end_slot + 32 ) / 32 ]
1014
+ } ;
1015
+
1016
+ let [ return_bytes_start_offset, return_bytes_end_offset, return_bytes_word_count] =
1017
+ // Correspond to this check in bus-mapping.
1018
+ // <https://github.com/scroll-tech/zkevm-circuits/blob/25dd32aa316ec842ffe79bb8efe9f05f86edc33e/bus-mapping/src/evm/opcodes/callop.rs#L416>
1019
+ if cd_length. is_zero ( ) || precompile_return_length. is_zero ( ) || rd_length. is_zero ( )
1020
+ {
1021
+ [ 0 ; 3 ]
1022
+ } else {
1023
+ let length = min ( rd_length. as_usize ( ) , output_bytes_end) ;
1024
+ let begin = rd_offset. as_usize ( ) ;
1025
+ let end = begin + length;
1026
+
1027
+ let begin_slot = begin - begin % 32 ;
1028
+ let end_slot = end - end % 32 ;
1029
+ let slot_count = max ( length - length % 32 , end_slot - begin_slot) ;
1030
+
1031
+ // return data may not be aligned to 32 bytes. actual return data is
1032
+ // [start_offset..end_offset]
1033
+ let start_offset = begin - begin_slot;
1034
+ let end_offset = end - begin_slot;
1035
+ let word_count = slot_count / 32 + 1 ;
1036
+
1037
+ [ start_offset, end_offset, word_count]
1038
+ } ;
1012
1039
1013
1040
trace ! ( "rw_offset {rw_offset}" ) ;
1014
1041
trace ! (
0 commit comments