Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/compiler/evm_frontend/evm_imported.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ const RuntimeFunctions &getRuntimeFunctionTable() {
.GetTLoad = &evmGetTLoad,
.SetTStore = &evmSetTStore,
.SetCallDataCopy = &evmSetCallDataCopy,
.TouchExtCodeCopyAccount = &evmTouchExtCodeCopyAccount,
.SetExtCodeCopy = &evmSetExtCodeCopy,
.SetReturnDataCopy = &evmSetReturnDataCopy,
.ExpandMemoryNoGas = &evmExpandMemoryNoGas,
Expand Down Expand Up @@ -674,6 +675,21 @@ void evmSetCallDataCopy(zen::runtime::EVMInstance *Instance,
}
}

void evmTouchExtCodeCopyAccount(zen::runtime::EVMInstance *Instance,
const uint8_t *Address) {
const zen::runtime::EVMModule *Module = Instance->getModule();
ZEN_ASSERT(Module && Module->Host);
evmc::address Addr = loadAddressFromLE(Address);

evmc_revision Rev = Instance->getRevision();
if (Rev >= EVMC_BERLIN &&
Module->Host->access_account(Addr) == EVMC_ACCESS_COLD) {
if (!Instance->chargeGas(zen::evm::ADDITIONAL_COLD_ACCOUNT_ACCESS_COST)) {
return;
}
}
}

void evmSetExtCodeCopy(zen::runtime::EVMInstance *Instance,
const uint8_t *Address, uint64_t DestOffset,
uint64_t Offset, uint64_t Size) {
Expand Down
3 changes: 3 additions & 0 deletions src/compiler/evm_frontend/evm_imported.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ struct RuntimeFunctions {
U256WithU256Fn GetTLoad;
VoidWithU256U256Fn SetTStore;
VoidWithUInt64UInt64UInt64Fn SetCallDataCopy;
VoidWithBytes32Fn TouchExtCodeCopyAccount;
VoidWithBytes32UInt64UInt64UInt64Fn SetExtCodeCopy;
UInt64WithUInt64UInt64UInt64Fn SetReturnDataCopy;
VoidWithUInt64Fn ExpandMemoryNoGas;
Expand Down Expand Up @@ -218,6 +219,8 @@ const uint8_t *evmGetBlobHash(zen::runtime::EVMInstance *Instance,
const intx::uint256 *evmGetBlobBaseFee(zen::runtime::EVMInstance *Instance);
void evmSetCallDataCopy(zen::runtime::EVMInstance *Instance,
uint64_t DestOffset, uint64_t Offset, uint64_t Size);
void evmTouchExtCodeCopyAccount(zen::runtime::EVMInstance *Instance,
const uint8_t *Address);
void evmSetExtCodeCopy(zen::runtime::EVMInstance *Instance,
const uint8_t *Address, uint64_t DestOffset,
uint64_t Offset, uint64_t Size);
Expand Down
17 changes: 17 additions & 0 deletions src/compiler/evm_frontend/evm_mir_compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5035,6 +5035,11 @@ void EVMMirBuilder::handleMStore8(Operand AddrComponents,
void EVMMirBuilder::handleMCopy(Operand DestAddrComponents,
Operand SrcAddrComponents,
Operand LengthComponents) {
if (LengthComponents.isConstU64() &&
LengthComponents.getConstValue()[0] == 0) {
return;
}

MType *I64Type = &Ctx.I64Type;
MInstruction *Zero = createIntConstInstruction(I64Type, 0);

Expand Down Expand Up @@ -6737,6 +6742,18 @@ void EVMMirBuilder::handleExtCodeCopy(Operand AddressComponents,
Operand OffsetComponents,
Operand SizeComponents) {
const auto &RuntimeFunctions = getRuntimeFunctionTable();
if (SizeComponents.isConstU64() && SizeComponents.getConstValue()[0] == 0) {
#ifdef ZEN_ENABLE_EVM_GAS_REGISTER
syncGasToMemory();
#endif
callRuntimeForWithErrorCheck<void, const uint8_t *>(
RuntimeFunctions.TouchExtCodeCopyAccount, AddressComponents);
#ifdef ZEN_ENABLE_EVM_GAS_REGISTER
reloadGasFromMemory();
#endif
return;
}

// Use max uint64_t value if the offset/size is not 64-bit, because the
// extcodecopy will fill zeros when offset is beyond code size or handle large
// size properly.
Expand Down
12 changes: 12 additions & 0 deletions tests/evm_asm/extcodecopy_zero_size.easm
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// EXTCODECOPY with zero size keeps existing memory and skips code copy work
PUSH1 0x2C
PUSH1 0x00
MSTORE
PUSH1 0x00
PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
PUSH1 0x00
EXTCODECOPY
PUSH1 0x20
PUSH1 0x00
RETURN
1 change: 1 addition & 0 deletions tests/evm_asm/extcodecopy_zero_size.evm.hex
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
602C60005260007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60003C60206000F3
8 changes: 8 additions & 0 deletions tests/evm_asm/extcodecopy_zero_size.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
status: success
error_code: 0
stack: []
memory: '000000000000000000000000000000000000000000000000000000000000002C'
storage: {}
transient_storage: {}
return: '000000000000000000000000000000000000000000000000000000000000002C'
events: []
11 changes: 11 additions & 0 deletions tests/evm_asm/mcopy_zero_size.easm
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// MCOPY with zero size keeps existing memory and skips source/destination access
PUSH1 0x2D
PUSH1 0x00
MSTORE
PUSH1 0x00
PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
MCOPY
PUSH1 0x20
PUSH1 0x00
RETURN
1 change: 1 addition & 0 deletions tests/evm_asm/mcopy_zero_size.evm.hex
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
602D60005260007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E60206000F3
8 changes: 8 additions & 0 deletions tests/evm_asm/mcopy_zero_size.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
status: success
error_code: 0
stack: []
memory: '000000000000000000000000000000000000000000000000000000000000002D'
storage: {}
transient_storage: {}
return: '000000000000000000000000000000000000000000000000000000000000002D'
events: []
Loading