Skip to content

Commit

Permalink
baseline: Move execution to separate file
Browse files Browse the repository at this point in the history
Move the Baseline execution implementation to separate file:
baseline.cpp → baseline_execution.cpp
  • Loading branch information
chfast committed Jul 4, 2024
1 parent f3b5067 commit b6d881b
Show file tree
Hide file tree
Showing 2 changed files with 1 addition and 66 deletions.
2 changes: 1 addition & 1 deletion lib/evmone/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ add_library(evmone
advanced_execution.cpp
advanced_execution.hpp
advanced_instructions.cpp
baseline.cpp
baseline.hpp
baseline_execution.cpp
baseline_instruction_table.cpp
baseline_instruction_table.hpp
constants.hpp
Expand Down
65 changes: 0 additions & 65 deletions lib/evmone/baseline.cpp → lib/evmone/baseline_execution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,71 +24,6 @@

namespace evmone::baseline
{
namespace
{
CodeAnalysis::JumpdestMap analyze_jumpdests(bytes_view code)
{
// To find if op is any PUSH opcode (OP_PUSH1 <= op <= OP_PUSH32)
// it can be noticed that OP_PUSH32 is INT8_MAX (0x7f) therefore
// static_cast<int8_t>(op) <= OP_PUSH32 is always true and can be skipped.
static_assert(OP_PUSH32 == std::numeric_limits<int8_t>::max());

CodeAnalysis::JumpdestMap map(code.size()); // Allocate and init bitmap with zeros.
for (size_t i = 0; i < code.size(); ++i)
{
const auto op = code[i];
if (static_cast<int8_t>(op) >= OP_PUSH1) // If any PUSH opcode (see explanation above).
i += op - size_t{OP_PUSH1 - 1}; // Skip PUSH data.
else if (INTX_UNLIKELY(op == OP_JUMPDEST))
map[i] = true;
}

return map;
}

std::unique_ptr<uint8_t[]> pad_code(bytes_view code)
{
// We need at most 33 bytes of code padding: 32 for possible missing all data bytes of PUSH32
// at the very end of the code; and one more byte for STOP to guarantee there is a terminating
// instruction at the code end.
constexpr auto padding = 32 + 1;

auto padded_code = std::make_unique_for_overwrite<uint8_t[]>(code.size() + padding);
std::copy(std::begin(code), std::end(code), padded_code.get());
std::fill_n(&padded_code[code.size()], padding, uint8_t{OP_STOP});
return padded_code;
}


CodeAnalysis analyze_legacy(bytes_view code)
{
// TODO: The padded code buffer and jumpdest bitmap can be created with single allocation.
return {pad_code(code), code.size(), analyze_jumpdests(code)};
}

CodeAnalysis analyze_eof1(bytes_view container)
{
auto header = read_valid_eof1_header(container);

// Extract all code sections as single buffer reference.
// TODO: It would be much easier if header had code_sections_offset and data_section_offset
// with code_offsets[] being relative to code_sections_offset.
const auto code_sections_offset = header.code_offsets[0];
const auto code_sections_end = size_t{header.code_offsets.back()} + header.code_sizes.back();
const auto executable_code =
container.substr(code_sections_offset, code_sections_end - code_sections_offset);

return CodeAnalysis{executable_code, std::move(header)};
}
} // namespace

CodeAnalysis analyze(evmc_revision rev, bytes_view code)
{
if (rev < EVMC_PRAGUE || !is_eof_container(code))
return analyze_legacy(code);
return analyze_eof1(code);
}

namespace
{
/// Checks instruction requirements before execution.
Expand Down

0 comments on commit b6d881b

Please sign in to comment.