From 3feb04d2525d33c6881098e7d08abffa4dca25c2 Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Thu, 26 Oct 2023 10:20:55 -0400 Subject: [PATCH] Refactor wcopy syscalls --- evm/src/cpu/kernel/asm/memory/syscalls.asm | 164 +++++++++------------ 1 file changed, 66 insertions(+), 98 deletions(-) diff --git a/evm/src/cpu/kernel/asm/memory/syscalls.asm b/evm/src/cpu/kernel/asm/memory/syscalls.asm index 18200567..ad041c44 100644 --- a/evm/src/cpu/kernel/asm/memory/syscalls.asm +++ b/evm/src/cpu/kernel/asm/memory/syscalls.asm @@ -70,8 +70,33 @@ calldataload_large_offset: %stack (kexit_info, i) -> (kexit_info, 0) EXIT_KERNEL -// Macro for {CALLDATA,CODE,RETURNDATA}COPY (W_copy in Yellow Paper). +// Macro for {CALLDATA, RETURNDATA}COPY (W_copy in Yellow Paper). %macro wcopy(segment, context_metadata_size) + // stack: kexit_info, dest_offset, offset, size + %wcopy_charge_gas + + %stack (kexit_info, dest_offset, offset, size) -> (dest_offset, size, kexit_info, dest_offset, offset, size) + %add_or_fault + // stack: expanded_num_bytes, kexit_info, dest_offset, offset, size, kexit_info + DUP1 %ensure_reasonable_offset + %update_mem_bytes + // stack: kexit_info, dest_offset, offset, size, kexit_info + DUP4 DUP4 %add_or_fault // Overflow check + %mload_context_metadata($context_metadata_size) LT %jumpi(fault_exception) // Data len check + + %mload_context_metadata($context_metadata_size) + // stack: total_size, kexit_info, dest_offset, offset, size + DUP4 + // stack: offset, total_size, kexit_info, dest_offset, offset, size + GT %jumpi(wcopy_large_offset) + + // stack: kexit_info, dest_offset, offset, size + PUSH $segment + PUSH wcopy_within_bounds + JUMP +%endmacro + +%macro wcopy_charge_gas // stack: kexit_info, dest_offset, offset, size PUSH @GAS_VERYLOW DUP5 @@ -79,6 +104,45 @@ calldataload_large_offset: ISZERO %jumpi(wcopy_empty) // stack: Gverylow, kexit_info, dest_offset, offset, size DUP5 %num_bytes_to_num_words %mul_const(@GAS_COPY) ADD %charge_gas +%endmacro + +wcopy_within_bounds: + // stack: segment, kexit_info, dest_offset, offset, size + GET_CONTEXT + %stack (context, segment, kexit_info, dest_offset, offset, size) -> + (context, @SEGMENT_MAIN_MEMORY, dest_offset, context, segment, offset, size, wcopy_after, kexit_info) + %jump(memcpy_bytes) + +wcopy_empty: + // stack: Gverylow, kexit_info, dest_offset, offset, size + %charge_gas + %stack (kexit_info, dest_offset, offset, size) -> (kexit_info) + EXIT_KERNEL + +wcopy_large_offset: + // offset is larger than the size of the {CALLDATA,CODE,RETURNDATA}. So we just have to write zeros. + // stack: kexit_info, dest_offset, offset, size + GET_CONTEXT + %stack (context, kexit_info, dest_offset, offset, size) -> + (context, @SEGMENT_MAIN_MEMORY, dest_offset, size, wcopy_after, kexit_info) + %jump(memset) + +wcopy_after: + // stack: kexit_info + EXIT_KERNEL + +global sys_calldatacopy: + %wcopy(@SEGMENT_CALLDATA, @CTX_METADATA_CALLDATA_SIZE) + +global sys_codecopy: + %codecopy(@SEGMENT_CODE, @CTX_METADATA_CODE_SIZE) + +global sys_returndatacopy: + %wcopy(@SEGMENT_RETURNDATA, @CTX_METADATA_RETURNDATA_SIZE) + +%macro codecopy(segment, context_metadata_size) + // stack: kexit_info, dest_offset, offset, size + %wcopy_charge_gas %stack (kexit_info, dest_offset, offset, size) -> (dest_offset, size, kexit_info, dest_offset, offset, size) %add_or_fault @@ -114,102 +178,6 @@ calldataload_large_offset: GET_CONTEXT %stack (context, new_dest_offset, copy_size, extra_size, segment, kexit_info, dest_offset, offset, size) -> - (context, @SEGMENT_MAIN_MEMORY, dest_offset, context, segment, offset, copy_size, wcopy_over_range, new_dest_offset, extra_size, kexit_info) + (context, @SEGMENT_MAIN_MEMORY, dest_offset, context, segment, offset, copy_size, wcopy_large_offset, kexit_info, new_dest_offset, offset, extra_size) %jump(memcpy_bytes) %endmacro - -wcopy_within_bounds: - // stack: segment, kexit_info, dest_offset, offset, size - GET_CONTEXT - %stack (context, segment, kexit_info, dest_offset, offset, size) -> - (context, @SEGMENT_MAIN_MEMORY, dest_offset, context, segment, offset, size, wcopy_after, kexit_info) - %jump(memcpy_bytes) - - -// Same as wcopy_large_offset, but without `offset` in the stack. -wcopy_over_range: - // stack: dest_offset, size, kexit_info - GET_CONTEXT - %stack (context, dest_offset, size, kexit_info) -> - (context, @SEGMENT_MAIN_MEMORY, dest_offset, size, wcopy_after, kexit_info) - %jump(memset) - -wcopy_empty: - // stack: Gverylow, kexit_info, dest_offset, offset, size - %charge_gas - %stack (kexit_info, dest_offset, offset, size) -> (kexit_info) - EXIT_KERNEL - -wcopy_large_offset: - // offset is larger than the size of the {CALLDATA,CODE,RETURNDATA}. So we just have to write zeros. - // stack: kexit_info, dest_offset, offset, size - GET_CONTEXT - %stack (context, kexit_info, dest_offset, offset, size) -> - (context, @SEGMENT_MAIN_MEMORY, dest_offset, size, wcopy_after, kexit_info) - %jump(memset) - -wcopy_after: - // stack: kexit_info - EXIT_KERNEL - -global sys_calldatacopy: - %wcopy(@SEGMENT_CALLDATA, @CTX_METADATA_CALLDATA_SIZE) - -global sys_codecopy: - %wcopy(@SEGMENT_CODE, @CTX_METADATA_CODE_SIZE) - -// Same as %wcopy but with overflow checks. -global sys_returndatacopy: - // stack: kexit_info, dest_offset, offset, size - PUSH @GAS_VERYLOW - // stack: Gverylow, kexit_info, dest_offset, offset, size - DUP5 %num_bytes_to_num_words %mul_const(@GAS_COPY) ADD %charge_gas - - %stack (kexit_info, dest_offset, offset, size) -> (dest_offset, size, kexit_info, dest_offset, offset, size) - %add_or_fault - // stack: expanded_num_bytes, kexit_info, dest_offset, offset, size, kexit_info - DUP1 %ensure_reasonable_offset - %update_mem_bytes - // stack: kexit_info, dest_offset, offset, size, kexit_info - DUP4 DUP4 %add_or_fault // Overflow check - %mload_context_metadata(@CTX_METADATA_RETURNDATA_SIZE) LT %jumpi(fault_exception) // Data len check - - // stack: kexit_info, dest_offset, offset, size - DUP4 - // stack: size, kexit_info, dest_offset, offset, size - ISZERO %jumpi(returndatacopy_empty) - - %mload_context_metadata(@CTX_METADATA_RETURNDATA_SIZE) - // stack: total_size, kexit_info, dest_offset, offset, size - DUP4 - // stack: offset, total_size, kexit_info, dest_offset, offset, size - GT %jumpi(wcopy_large_offset) - - PUSH @SEGMENT_RETURNDATA - %mload_context_metadata(@CTX_METADATA_RETURNDATA_SIZE) - // stack: total_size, returndata_segment, kexit_info, dest_offset, offset, size - DUP6 DUP6 ADD - // stack: offset + size, total_size, returndata_segment, kexit_info, dest_offset, offset, size - LT %jumpi(wcopy_within_bounds) - - %mload_context_metadata(@CTX_METADATA_RETURNDATA_SIZE) - // stack: total_size, returndata_segment, kexit_info, dest_offset, offset, size - DUP6 DUP6 ADD - // stack: offset + size, total_size, returndata_segment, kexit_info, dest_offset, offset, size - SUB // extra_size = offset + size - total_size - // stack: extra_size, returndata_segment, kexit_info, dest_offset, offset, size - DUP1 DUP7 SUB - // stack: copy_size = size - extra_size, extra_size, returndata_segment, kexit_info, dest_offset, offset, size - - // Compute the new dest_offset after actual copies, at which we will start padding with zeroes. - DUP1 DUP6 ADD - // stack: new_dest_offset, copy_size, extra_size, returndata_segment, kexit_info, dest_offset, offset, size - - GET_CONTEXT - %stack (context, new_dest_offset, copy_size, extra_size, returndata_segment, kexit_info, dest_offset, offset, size) -> - (context, @SEGMENT_MAIN_MEMORY, dest_offset, context, returndata_segment, offset, copy_size, wcopy_over_range, new_dest_offset, extra_size, kexit_info) - %jump(memcpy_bytes) - -returndatacopy_empty: - %stack (kexit_info, dest_offset, offset, size) -> (kexit_info) - EXIT_KERNEL