From 707d817480a5069b3bb7873094b3790d47a83611 Mon Sep 17 00:00:00 2001 From: Vladislav Volosnikov Date: Fri, 20 Dec 2024 14:16:58 +0100 Subject: [PATCH] Handle calldata-related opcodes in constructor --- system-contracts/contracts/EvmEmulator.yul | 47 +++++++++++++------ .../evm-emulator/EvmEmulator.template.yul | 4 ++ .../evm-emulator/EvmEmulatorLoop.template.yul | 10 ++-- .../ConstructorScope.template.yul | 11 +++++ .../RuntimeScope.template.yul | 14 ++++++ 5 files changed, 65 insertions(+), 21 deletions(-) create mode 100644 system-contracts/evm-emulator/calldata-opcodes/ConstructorScope.template.yul create mode 100644 system-contracts/evm-emulator/calldata-opcodes/RuntimeScope.template.yul diff --git a/system-contracts/contracts/EvmEmulator.yul b/system-contracts/contracts/EvmEmulator.yul index 6653c623c..5b41e6643 100644 --- a/system-contracts/contracts/EvmEmulator.yul +++ b/system-contracts/contracts/EvmEmulator.yul @@ -1309,6 +1309,18 @@ object "EvmEmulator" { } } + function $llvm_AlwaysInline_llvm$_calldatasize() -> size { + size := 0 + } + + function $llvm_AlwaysInline_llvm$_calldatacopy(dstOffset, sourceOffset, truncatedLen) { + $llvm_AlwaysInline_llvm$_memsetToZero(dstOffset, truncatedLen) + } + + function $llvm_AlwaysInline_llvm$_calldataload(calldataOffset) -> res { + res := 0 + } + function simulate( isCallerEVM, evmGasLeft, @@ -1667,18 +1679,14 @@ object "EvmEmulator" { let calldataOffset := accessStackHead(sp, stackHead) - stackHead := 0 - // EraVM will revert if offset + length overflows uint32 - if lt(calldataOffset, UINT32_MAX()) { - stackHead := calldataload(calldataOffset) - } + stackHead := $llvm_AlwaysInline_llvm$_calldataload(calldataOffset) ip := add(ip, 1) } case 0x36 { // OP_CALLDATASIZE evmGasLeft := chargeGas(evmGasLeft, 2) - sp, stackHead := pushStackItem(sp, calldatasize(), stackHead) + sp, stackHead := pushStackItem(sp, $llvm_AlwaysInline_llvm$_calldatasize(), stackHead) ip := add(ip, 1) } case 0x37 { // OP_CALLDATACOPY @@ -1713,7 +1721,7 @@ object "EvmEmulator" { } if truncatedLen { - calldatacopy(dstOffset, sourceOffset, truncatedLen) + $llvm_AlwaysInline_llvm$_calldatacopy(dstOffset, sourceOffset, truncatedLen) } ip := add(ip, 1) @@ -4805,18 +4813,14 @@ object "EvmEmulator" { let calldataOffset := accessStackHead(sp, stackHead) - stackHead := 0 - // EraVM will revert if offset + length overflows uint32 - if lt(calldataOffset, UINT32_MAX()) { - stackHead := calldataload(calldataOffset) - } + stackHead := $llvm_AlwaysInline_llvm$_calldataload(calldataOffset) ip := add(ip, 1) } case 0x36 { // OP_CALLDATASIZE evmGasLeft := chargeGas(evmGasLeft, 2) - sp, stackHead := pushStackItem(sp, calldatasize(), stackHead) + sp, stackHead := pushStackItem(sp, $llvm_AlwaysInline_llvm$_calldatasize(), stackHead) ip := add(ip, 1) } case 0x37 { // OP_CALLDATACOPY @@ -4851,7 +4855,7 @@ object "EvmEmulator" { } if truncatedLen { - calldatacopy(dstOffset, sourceOffset, truncatedLen) + $llvm_AlwaysInline_llvm$_calldatacopy(dstOffset, sourceOffset, truncatedLen) } ip := add(ip, 1) @@ -6284,6 +6288,21 @@ object "EvmEmulator" { } + function $llvm_AlwaysInline_llvm$_calldatasize() -> size { + size := calldatasize() + } + + function $llvm_AlwaysInline_llvm$_calldatacopy(dstOffset, sourceOffset, truncatedLen) { + calldatacopy(dstOffset, sourceOffset, truncatedLen) + } + + function $llvm_AlwaysInline_llvm$_calldataload(calldataOffset) -> res { + // EraVM will revert if offset + length overflows uint32 + if lt(calldataOffset, UINT32_MAX()) { + res := calldataload(calldataOffset) + } + } + if eq(isCallerEVM, 1) { // Includes gas returnOffset := sub(returnOffset, 32) diff --git a/system-contracts/evm-emulator/EvmEmulator.template.yul b/system-contracts/evm-emulator/EvmEmulator.template.yul index 8e1a4b813..22d188075 100644 --- a/system-contracts/evm-emulator/EvmEmulator.template.yul +++ b/system-contracts/evm-emulator/EvmEmulator.template.yul @@ -60,6 +60,8 @@ object "EvmEmulator" { + + function simulate( isCallerEVM, evmGasLeft, @@ -134,6 +136,8 @@ object "EvmEmulator" { + + if eq(isCallerEVM, 1) { // Includes gas returnOffset := sub(returnOffset, 32) diff --git a/system-contracts/evm-emulator/EvmEmulatorLoop.template.yul b/system-contracts/evm-emulator/EvmEmulatorLoop.template.yul index cd9d5a2c5..d5056dd19 100644 --- a/system-contracts/evm-emulator/EvmEmulatorLoop.template.yul +++ b/system-contracts/evm-emulator/EvmEmulatorLoop.template.yul @@ -347,18 +347,14 @@ for { } true { } { let calldataOffset := accessStackHead(sp, stackHead) - stackHead := 0 - // EraVM will revert if offset + length overflows uint32 - if lt(calldataOffset, UINT32_MAX()) { - stackHead := calldataload(calldataOffset) - } + stackHead := $llvm_AlwaysInline_llvm$_calldataload(calldataOffset) ip := add(ip, 1) } case 0x36 { // OP_CALLDATASIZE evmGasLeft := chargeGas(evmGasLeft, 2) - sp, stackHead := pushStackItem(sp, calldatasize(), stackHead) + sp, stackHead := pushStackItem(sp, $llvm_AlwaysInline_llvm$_calldatasize(), stackHead) ip := add(ip, 1) } case 0x37 { // OP_CALLDATACOPY @@ -393,7 +389,7 @@ for { } true { } { } if truncatedLen { - calldatacopy(dstOffset, sourceOffset, truncatedLen) + $llvm_AlwaysInline_llvm$_calldatacopy(dstOffset, sourceOffset, truncatedLen) } ip := add(ip, 1) diff --git a/system-contracts/evm-emulator/calldata-opcodes/ConstructorScope.template.yul b/system-contracts/evm-emulator/calldata-opcodes/ConstructorScope.template.yul new file mode 100644 index 000000000..075f4dfaa --- /dev/null +++ b/system-contracts/evm-emulator/calldata-opcodes/ConstructorScope.template.yul @@ -0,0 +1,11 @@ +function $llvm_AlwaysInline_llvm$_calldatasize() -> size { + size := 0 +} + +function $llvm_AlwaysInline_llvm$_calldatacopy(dstOffset, sourceOffset, truncatedLen) { + $llvm_AlwaysInline_llvm$_memsetToZero(dstOffset, truncatedLen) +} + +function $llvm_AlwaysInline_llvm$_calldataload(calldataOffset) -> res { + res := 0 +} \ No newline at end of file diff --git a/system-contracts/evm-emulator/calldata-opcodes/RuntimeScope.template.yul b/system-contracts/evm-emulator/calldata-opcodes/RuntimeScope.template.yul new file mode 100644 index 000000000..51c88e7b5 --- /dev/null +++ b/system-contracts/evm-emulator/calldata-opcodes/RuntimeScope.template.yul @@ -0,0 +1,14 @@ +function $llvm_AlwaysInline_llvm$_calldatasize() -> size { + size := calldatasize() +} + +function $llvm_AlwaysInline_llvm$_calldatacopy(dstOffset, sourceOffset, truncatedLen) { + calldatacopy(dstOffset, sourceOffset, truncatedLen) +} + +function $llvm_AlwaysInline_llvm$_calldataload(calldataOffset) -> res { + // EraVM will revert if offset + length overflows uint32 + if lt(calldataOffset, UINT32_MAX()) { + res := calldataload(calldataOffset) + } +} \ No newline at end of file