2022-12-06 23:05:47 -08:00
|
|
|
global sys_mload:
|
2023-03-19 22:35:53 -07:00
|
|
|
// stack: kexit_info, offset
|
|
|
|
|
DUP2 %ensure_reasonable_offset
|
2023-03-19 20:17:30 -07:00
|
|
|
// stack: kexit_info, offset
|
|
|
|
|
%charge_gas_const(@GAS_VERYLOW)
|
|
|
|
|
// stack: kexit_info, offset
|
|
|
|
|
DUP2 %add_const(32)
|
|
|
|
|
// stack: expanded_num_bytes, kexit_info, offset
|
|
|
|
|
%update_mem_bytes
|
2022-12-06 23:05:47 -08:00
|
|
|
// stack: kexit_info, offset
|
2023-09-18 16:02:52 -04:00
|
|
|
%stack(kexit_info, offset) -> (offset, 32, kexit_info)
|
|
|
|
|
PUSH @SEGMENT_MAIN_MEMORY
|
|
|
|
|
GET_CONTEXT
|
|
|
|
|
// stack: addr: 3, len, kexit_info
|
|
|
|
|
MLOAD_32BYTES
|
|
|
|
|
%stack (value, kexit_info) -> (kexit_info, value)
|
2022-12-06 23:05:47 -08:00
|
|
|
EXIT_KERNEL
|
|
|
|
|
|
|
|
|
|
global sys_mstore:
|
2023-03-19 22:35:53 -07:00
|
|
|
// stack: kexit_info, offset, value
|
|
|
|
|
DUP2 %ensure_reasonable_offset
|
2023-03-19 20:17:30 -07:00
|
|
|
// stack: kexit_info, offset, value
|
|
|
|
|
%charge_gas_const(@GAS_VERYLOW)
|
|
|
|
|
// stack: kexit_info, offset, value
|
|
|
|
|
DUP2 %add_const(32)
|
|
|
|
|
// stack: expanded_num_bytes, kexit_info, offset, value
|
|
|
|
|
%update_mem_bytes
|
2022-12-06 23:05:47 -08:00
|
|
|
// stack: kexit_info, offset, value
|
2023-09-18 16:02:52 -04:00
|
|
|
%stack(kexit_info, offset, value) -> (offset, value, 32, kexit_info)
|
|
|
|
|
PUSH @SEGMENT_MAIN_MEMORY
|
|
|
|
|
GET_CONTEXT
|
|
|
|
|
// stack: addr: 3, value, len, kexit_info
|
|
|
|
|
MSTORE_32BYTES
|
|
|
|
|
// stack: kexit_info
|
2022-12-06 23:05:47 -08:00
|
|
|
EXIT_KERNEL
|
|
|
|
|
|
|
|
|
|
global sys_mstore8:
|
2023-03-19 22:35:53 -07:00
|
|
|
// stack: kexit_info, offset, value
|
|
|
|
|
DUP2 %ensure_reasonable_offset
|
2023-03-19 20:17:30 -07:00
|
|
|
// stack: kexit_info, offset, value
|
|
|
|
|
%charge_gas_const(@GAS_VERYLOW)
|
|
|
|
|
// stack: kexit_info, offset, value
|
|
|
|
|
DUP2 %increment
|
|
|
|
|
// stack: expanded_num_bytes, kexit_info, offset, value
|
|
|
|
|
%update_mem_bytes
|
2022-12-06 23:05:47 -08:00
|
|
|
// stack: kexit_info, offset, value
|
2023-04-03 16:39:18 +02:00
|
|
|
%stack (kexit_info, offset, value) -> (value, 0x100, offset, kexit_info)
|
|
|
|
|
MOD SWAP1
|
2022-12-06 23:05:47 -08:00
|
|
|
%mstore_current(@SEGMENT_MAIN_MEMORY)
|
|
|
|
|
// stack: kexit_info
|
|
|
|
|
EXIT_KERNEL
|
2023-03-19 22:52:44 -07:00
|
|
|
|
|
|
|
|
global sys_calldataload:
|
|
|
|
|
// stack: kexit_info, i
|
|
|
|
|
%charge_gas_const(@GAS_VERYLOW)
|
|
|
|
|
// stack: kexit_info, i
|
2023-06-08 12:08:02 +02:00
|
|
|
%mload_context_metadata(@CTX_METADATA_CALLDATA_SIZE)
|
|
|
|
|
%stack (calldata_size, kexit_info, i) -> (calldata_size, i, kexit_info, i)
|
|
|
|
|
LT %jumpi(calldataload_large_offset)
|
2023-03-19 22:52:44 -07:00
|
|
|
%stack (kexit_info, i) -> (@SEGMENT_CALLDATA, i, 32, sys_calldataload_after_mload_packing, kexit_info)
|
|
|
|
|
GET_CONTEXT
|
|
|
|
|
// stack: ADDR: 3, 32, sys_calldataload_after_mload_packing, kexit_info
|
|
|
|
|
%jump(mload_packing)
|
|
|
|
|
sys_calldataload_after_mload_packing:
|
|
|
|
|
// stack: value, kexit_info
|
|
|
|
|
SWAP1
|
|
|
|
|
EXIT_KERNEL
|
|
|
|
|
PANIC
|
2023-06-08 12:08:02 +02:00
|
|
|
calldataload_large_offset:
|
|
|
|
|
%stack (kexit_info, i) -> (kexit_info, 0)
|
|
|
|
|
EXIT_KERNEL
|
2023-03-22 06:42:14 +01:00
|
|
|
|
|
|
|
|
// Macro for {CALLDATA,CODE,RETURNDATA}COPY (W_copy in Yellow Paper).
|
2023-04-05 06:24:26 +02:00
|
|
|
%macro wcopy(segment, context_metadata_size)
|
2023-03-22 06:42:14 +01:00
|
|
|
// stack: kexit_info, dest_offset, offset, size
|
2023-03-29 19:58:44 +02:00
|
|
|
PUSH @GAS_VERYLOW
|
|
|
|
|
DUP5
|
|
|
|
|
// stack: size, Gverylow, kexit_info, dest_offset, offset, size
|
2023-05-17 10:06:12 +02:00
|
|
|
ISZERO %jumpi(wcopy_empty)
|
2023-03-29 19:58:44 +02:00
|
|
|
// stack: Gverylow, kexit_info, dest_offset, offset, size
|
|
|
|
|
DUP5 %num_bytes_to_num_words %mul_const(@GAS_COPY) ADD %charge_gas
|
2023-03-22 06:42:14 +01:00
|
|
|
|
2023-03-22 19:14:55 +01:00
|
|
|
%stack (kexit_info, dest_offset, offset, size) -> (dest_offset, size, kexit_info, dest_offset, offset, size)
|
2023-04-13 18:49:18 +08:00
|
|
|
%add_or_fault
|
2023-03-22 19:14:55 +01:00
|
|
|
// stack: expanded_num_bytes, kexit_info, dest_offset, offset, size, kexit_info
|
2023-03-22 06:42:14 +01:00
|
|
|
DUP1 %ensure_reasonable_offset
|
|
|
|
|
%update_mem_bytes
|
|
|
|
|
|
2023-04-05 06:24:26 +02:00
|
|
|
%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
|
2023-05-17 10:06:12 +02:00
|
|
|
GT %jumpi(wcopy_large_offset)
|
2023-04-05 06:24:26 +02:00
|
|
|
|
2023-10-24 15:56:46 -04:00
|
|
|
PUSH $segment
|
|
|
|
|
%mload_context_metadata($context_metadata_size)
|
|
|
|
|
// stack: total_size, segment, kexit_info, dest_offset, offset, size
|
|
|
|
|
DUP6 DUP6 ADD
|
|
|
|
|
// stack: offset + size, total_size, segment, kexit_info, dest_offset, offset, size
|
|
|
|
|
LT %jumpi(wcopy_within_bounds)
|
|
|
|
|
|
|
|
|
|
%mload_context_metadata($context_metadata_size)
|
|
|
|
|
// stack: total_size, segment, kexit_info, dest_offset, offset, size
|
|
|
|
|
DUP6 DUP6 ADD
|
|
|
|
|
// stack: offset + size, total_size, segment, kexit_info, dest_offset, offset, size
|
|
|
|
|
SUB // extra_size = offset + size - total_size
|
|
|
|
|
// stack: extra_size, segment, kexit_info, dest_offset, offset, size
|
|
|
|
|
DUP1 DUP7 SUB
|
|
|
|
|
// stack: copy_size = size - extra_size, extra_size, 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, segment, kexit_info, dest_offset, offset, size
|
|
|
|
|
|
2023-03-22 06:42:14 +01:00
|
|
|
GET_CONTEXT
|
2023-10-24 15:56:46 -04:00
|
|
|
%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)
|
2023-10-23 07:16:39 -04:00
|
|
|
%jump(memcpy_bytes)
|
2023-05-17 10:06:12 +02:00
|
|
|
%endmacro
|
2023-04-05 06:24:26 +02:00
|
|
|
|
2023-10-24 15:56:46 -04:00
|
|
|
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)
|
|
|
|
|
|
2023-05-17 10:06:12 +02:00
|
|
|
wcopy_empty:
|
2023-03-29 19:58:44 +02:00
|
|
|
// stack: Gverylow, kexit_info, dest_offset, offset, size
|
|
|
|
|
%charge_gas
|
|
|
|
|
%stack (kexit_info, dest_offset, offset, size) -> (kexit_info)
|
|
|
|
|
EXIT_KERNEL
|
2023-04-05 06:24:26 +02:00
|
|
|
|
2023-05-17 10:06:12 +02:00
|
|
|
wcopy_large_offset:
|
2023-04-05 06:24:26 +02:00
|
|
|
// 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) ->
|
2023-10-23 07:55:09 -04:00
|
|
|
(context, @SEGMENT_MAIN_MEMORY, dest_offset, size, wcopy_after, kexit_info)
|
2023-04-05 06:24:26 +02:00
|
|
|
%jump(memset)
|
2023-05-17 10:06:12 +02:00
|
|
|
|
|
|
|
|
wcopy_after:
|
|
|
|
|
// stack: kexit_info
|
|
|
|
|
EXIT_KERNEL
|
2023-03-22 06:42:14 +01:00
|
|
|
|
|
|
|
|
global sys_calldatacopy:
|
2023-04-05 06:24:26 +02:00
|
|
|
%wcopy(@SEGMENT_CALLDATA, @CTX_METADATA_CALLDATA_SIZE)
|
2023-03-22 06:42:14 +01:00
|
|
|
|
|
|
|
|
global sys_codecopy:
|
2023-04-05 06:24:26 +02:00
|
|
|
%wcopy(@SEGMENT_CODE, @CTX_METADATA_CODE_SIZE)
|
2023-03-22 06:42:14 +01:00
|
|
|
|
2023-05-17 10:06:12 +02:00
|
|
|
// Same as %wcopy but with overflow checks.
|
2023-03-22 06:42:14 +01:00
|
|
|
global sys_returndatacopy:
|
2023-05-17 10:06:12 +02:00
|
|
|
// 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
|
|
|
|
|
|
2023-06-02 19:58:04 +02:00
|
|
|
// stack: kexit_info, dest_offset, offset, size
|
|
|
|
|
DUP4
|
|
|
|
|
// stack: size, kexit_info, dest_offset, offset, size
|
|
|
|
|
ISZERO %jumpi(returndatacopy_empty)
|
|
|
|
|
|
2023-05-17 10:06:12 +02:00
|
|
|
%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)
|
|
|
|
|
|
2023-10-24 15:56:46 -04:00
|
|
|
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
|
|
|
|
|
|
2023-05-17 10:06:12 +02:00
|
|
|
GET_CONTEXT
|
2023-10-24 15:56:46 -04:00
|
|
|
%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)
|
2023-06-02 19:58:04 +02:00
|
|
|
|
|
|
|
|
returndatacopy_empty:
|
|
|
|
|
%stack (kexit_info, dest_offset, offset, size) -> (kexit_info)
|
|
|
|
|
EXIT_KERNEL
|