mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-09 01:03:08 +00:00
Fix wcopy and extcodecopy for ranges over code limit
This commit is contained in:
parent
ed5ec3ca9c
commit
c1c1ab6d0f
@ -139,52 +139,43 @@ extcodecopy_contd:
|
||||
DUP1 DUP4
|
||||
// stack: offset, code_size, code_size, size, offset, dest_offset, retdest
|
||||
GT %jumpi(extcodecopy_large_offset)
|
||||
|
||||
// stack: code_size, size, offset, dest_offset, retdest
|
||||
SWAP1
|
||||
// stack: size, code_size, offset, dest_offset, retdest
|
||||
PUSH 0
|
||||
DUP3 DUP3 ADD
|
||||
// stack: offset + size, code_size, size, offset, dest_offset, retdest
|
||||
DUP2 GT %jumpi(extcodecopy_within_bounds)
|
||||
|
||||
// Loop copying the `code[offset]` to `memory[dest_offset]` until `i==size`.
|
||||
// Each iteration increments `offset, dest_offset, i`.
|
||||
// TODO: Consider implementing this with memcpy.
|
||||
extcodecopy_loop:
|
||||
// stack: i, size, code_size, offset, dest_offset, retdest
|
||||
DUP2 DUP2 EQ
|
||||
// stack: i == size, i, size, code_size, offset, dest_offset, retdest
|
||||
%jumpi(extcodecopy_end)
|
||||
%stack (i, size, code_size, offset, dest_offset, retdest)
|
||||
-> (offset, code_size, offset, code_size, dest_offset, i, size, retdest)
|
||||
LT
|
||||
// stack: offset < code_size, offset, code_size, dest_offset, i, size, retdest
|
||||
DUP2
|
||||
// stack: offset, offset < code_size, offset, code_size, dest_offset, i, size, retdest
|
||||
%mload_kernel(@SEGMENT_KERNEL_ACCOUNT_CODE)
|
||||
// stack: opcode, offset < code_size, offset, code_size, dest_offset, i, size, retdest
|
||||
%stack (opcode, offset_lt_code_size, offset, code_size, dest_offset, i, size, retdest)
|
||||
-> (offset_lt_code_size, 0, opcode, offset, code_size, dest_offset, i, size, retdest)
|
||||
// If `offset >= code_size`, use `opcode=0`. Necessary since `SEGMENT_KERNEL_ACCOUNT_CODE` might be clobbered from previous calls.
|
||||
%select_bool
|
||||
// stack: opcode, offset, code_size, dest_offset, i, size, retdest
|
||||
DUP4
|
||||
// stack: dest_offset, opcode, offset, code_size, dest_offset, i, size, retdest
|
||||
%mstore_current(@SEGMENT_MAIN_MEMORY)
|
||||
// stack: offset, code_size, dest_offset, i, size, retdest
|
||||
%increment
|
||||
// stack: offset+1, code_size, dest_offset, i, size, retdest
|
||||
SWAP2
|
||||
// stack: dest_offset, code_size, offset+1, i, size, retdest
|
||||
%increment
|
||||
// stack: dest_offset+1, code_size, offset+1, i, size, retdest
|
||||
SWAP3
|
||||
// stack: i, code_size, offset+1, dest_offset+1, size, retdest
|
||||
%increment
|
||||
// stack: i+1, code_size, offset+1, dest_offset+1, size, retdest
|
||||
%stack (i, code_size, offset, dest_offset, size, retdest) -> (i, size, code_size, offset, dest_offset, retdest)
|
||||
%jump(extcodecopy_loop)
|
||||
// stack: code_size, size, offset, dest_offset, retdest
|
||||
DUP3 DUP3 ADD
|
||||
// stack: offset + size, code_size, size, offset, dest_offset, retdest
|
||||
SUB
|
||||
// stack: extra_size = offset + size - code_size, size, offset, dest_offset, retdest
|
||||
DUP1 DUP3 SUB
|
||||
// stack: copy_size = size - extra_size, extra_size, size, offset, dest_offset, retdest
|
||||
|
||||
// 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, size, offset, dest_offset, retdest
|
||||
|
||||
GET_CONTEXT
|
||||
%stack (context, new_dest_offset, copy_size, extra_size, size, offset, dest_offset, retdest) ->
|
||||
(context, @SEGMENT_MAIN_MEMORY, dest_offset, 0, @SEGMENT_KERNEL_ACCOUNT_CODE, offset, copy_size, extcodecopy_end, new_dest_offset, extra_size, retdest)
|
||||
%jump(memcpy_bytes)
|
||||
|
||||
extcodecopy_within_bounds:
|
||||
// stack: code_size, size, offset, dest_offset, retdest
|
||||
GET_CONTEXT
|
||||
%stack (context, code_size, size, offset, dest_offset, retdest) ->
|
||||
(context, @SEGMENT_MAIN_MEMORY, dest_offset, 0, @SEGMENT_KERNEL_ACCOUNT_CODE, offset, size, retdest)
|
||||
%jump(memcpy_bytes)
|
||||
|
||||
// Same as extcodecopy_large_offset, but without `offset` in the stack.
|
||||
extcodecopy_end:
|
||||
%stack (i, size, code_size, offset, dest_offset, retdest) -> (retdest)
|
||||
JUMP
|
||||
// stack: dest_offset, size, retdest
|
||||
GET_CONTEXT
|
||||
%stack (context, dest_offset, size, retdest) ->
|
||||
(context, @SEGMENT_MAIN_MEMORY, dest_offset, size, retdest)
|
||||
%jump(memset)
|
||||
|
||||
extcodecopy_large_offset:
|
||||
// offset is larger than the code size. So we just have to write zeros.
|
||||
|
||||
@ -2,8 +2,10 @@
|
||||
// DST = (dst_ctx, dst_segment, dst_addr).
|
||||
// This tuple definition is used for brevity in the stack comments below.
|
||||
global memset:
|
||||
// stack: DST, count, retdest
|
||||
|
||||
// Handle empty case
|
||||
DUP7
|
||||
DUP4
|
||||
// stack: count, DST, count, retdest
|
||||
ISZERO
|
||||
// stack: count == 0, DST, count, retdest
|
||||
@ -33,9 +35,9 @@ global memset:
|
||||
%add_const(0x20)
|
||||
SWAP2
|
||||
// Decrement count.
|
||||
SWAP4
|
||||
SWAP3
|
||||
%sub_const(0x20)
|
||||
SWAP4
|
||||
SWAP3
|
||||
|
||||
// Continue the loop.
|
||||
%jump(memset)
|
||||
|
||||
@ -92,12 +92,48 @@ calldataload_large_offset:
|
||||
// stack: offset, total_size, kexit_info, dest_offset, offset, size
|
||||
GT %jumpi(wcopy_large_offset)
|
||||
|
||||
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
|
||||
|
||||
GET_CONTEXT
|
||||
%stack (context, kexit_info, dest_offset, offset, size) ->
|
||||
(context, @SEGMENT_MAIN_MEMORY, dest_offset, context, $segment, offset, size, wcopy_after, kexit_info)
|
||||
%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)
|
||||
%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
|
||||
@ -149,10 +185,30 @@ global sys_returndatacopy:
|
||||
// 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, kexit_info, dest_offset, offset, size) ->
|
||||
(context, @SEGMENT_MAIN_MEMORY, dest_offset, context, @SEGMENT_RETURNDATA, offset, size, wcopy_after, kexit_info)
|
||||
%jump(memcpy)
|
||||
%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)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user