From 3cf1aa03b172d1de2139ac3f177834e577c74129 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Sun, 30 Apr 2023 01:07:36 +0200 Subject: [PATCH] Implement MCOPY --- lib/evmone/instructions.hpp | 23 +++++++++++++++++++++++ lib/evmone/instructions_opcodes.hpp | 1 + lib/evmone/instructions_traits.hpp | 2 ++ 3 files changed, 26 insertions(+) diff --git a/lib/evmone/instructions.hpp b/lib/evmone/instructions.hpp index 1d82e6d3a6..2ed200df70 100644 --- a/lib/evmone/instructions.hpp +++ b/lib/evmone/instructions.hpp @@ -900,6 +900,29 @@ inline code_iterator swapn(StackTop stack, ExecutionState& state, code_iterator return pos + 2; } +inline Result mcopy(StackTop stack, int64_t gas_left, ExecutionState& state) noexcept +{ + const auto& dst_index = stack.pop(); + const auto& src_index = stack.pop(); + const auto& size = stack.pop(); + + if (!check_memory(gas_left, state.memory, std::max(dst_index, src_index), size)) + return {EVMC_OUT_OF_GAS, gas_left}; + + auto dst = static_cast(dst_index); + auto src = static_cast(src_index); + auto copy_size = static_cast(size); + + const auto copy_cost = num_words(copy_size) * 3; + if ((gas_left -= copy_cost) < 0) + return {EVMC_OUT_OF_GAS, gas_left}; + + if (copy_size > 0) + std::memcpy(&state.memory[dst], &state.memory[src], copy_size); + + return {EVMC_SUCCESS, gas_left}; +} + template inline Result log(StackTop stack, int64_t gas_left, ExecutionState& state) noexcept { diff --git a/lib/evmone/instructions_opcodes.hpp b/lib/evmone/instructions_opcodes.hpp index 9b430ce47a..90fb930cba 100644 --- a/lib/evmone/instructions_opcodes.hpp +++ b/lib/evmone/instructions_opcodes.hpp @@ -162,6 +162,7 @@ enum Opcode : uint8_t OP_DUPN = 0xb5, OP_SWAPN = 0xb6, + OP_MCOPY = 0xb7, OP_CREATE = 0xf0, OP_CALL = 0xf1, diff --git a/lib/evmone/instructions_traits.hpp b/lib/evmone/instructions_traits.hpp index fc4bb85776..30b80692e9 100644 --- a/lib/evmone/instructions_traits.hpp +++ b/lib/evmone/instructions_traits.hpp @@ -164,6 +164,7 @@ constexpr inline GasCostTable gas_costs = []() noexcept { table[EVMC_SHANGHAI][OP_PUSH0] = 2; table[EVMC_CANCUN] = table[EVMC_SHANGHAI]; + table[EVMC_CANCUN][OP_MCOPY] = 3; table[EVMC_CANCUN][OP_DUPN] = 3; table[EVMC_CANCUN][OP_SWAPN] = 3; table[EVMC_CANCUN][OP_RJUMP] = 2; @@ -375,6 +376,7 @@ constexpr inline std::array traits = []() noexcept { table[OP_DUPN] = {"DUPN", 1, false, 0, 1, EVMC_CANCUN}; table[OP_SWAPN] = {"SWAPN", 1, false, 0, 0, EVMC_CANCUN}; + table[OP_MCOPY] = {"MCOPY", 0, false, 3, -3, EVMC_CANCUN}; table[OP_CREATE] = {"CREATE", 0, false, 3, -2, EVMC_FRONTIER}; table[OP_CALL] = {"CALL", 0, false, 7, -6, EVMC_FRONTIER};