Skip to content

Commit

Permalink
baseline: Improve CodeAnalysis API
Browse files Browse the repository at this point in the history
  • Loading branch information
chfast committed Sep 11, 2024
1 parent 3d6e9dc commit e380a81
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 25 deletions.
24 changes: 17 additions & 7 deletions lib/evmone/baseline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,35 @@ class CodeAnalysis
public:
using JumpdestMap = std::vector<bool>;

bytes_view executable_code; ///< Executable code section.
JumpdestMap jumpdest_map; ///< Map of valid jump destinations.
EOF1Header eof_header; ///< The EOF header.

private:
bytes_view m_executable_code; ///< Executable code section.
JumpdestMap m_jumpdest_map; ///< Map of valid jump destinations.
EOF1Header m_eof_header; ///< The EOF header.

/// Padded code for faster legacy code execution.
/// If not nullptr the executable_code must point to it.
std::unique_ptr<uint8_t[]> m_padded_code;

public:
CodeAnalysis(std::unique_ptr<uint8_t[]> padded_code, size_t code_size, JumpdestMap map)
: executable_code{padded_code.get(), code_size},
jumpdest_map{std::move(map)},
: m_executable_code{padded_code.get(), code_size},
m_jumpdest_map{std::move(map)},
m_padded_code{std::move(padded_code)}
{}

CodeAnalysis(bytes_view code, EOF1Header header)
: executable_code{code}, eof_header{std::move(header)}
: m_executable_code{code}, m_eof_header{std::move(header)}
{}

const uint8_t* executable_code() const noexcept { return m_executable_code.data(); }
const bytes_view account_code() const noexcept { return m_executable_code; }
const EOF1Header& eof_header() const noexcept { return m_eof_header; }
bool check_jumpdest(size_t position) const noexcept
{
if (position >= m_jumpdest_map.size())
return false;
return m_jumpdest_map[position];
}
};

/// Analyze the EVM code in preparation for execution.
Expand Down
14 changes: 7 additions & 7 deletions lib/evmone/baseline_execution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,24 +292,24 @@ evmc_result execute(
{
state.analysis.baseline = &analysis; // Assign code analysis for instruction implementations.

const auto code = analysis.executable_code;
const auto code = analysis.executable_code();

const auto& cost_table = get_baseline_cost_table(state.rev, analysis.eof_header.version);
const auto& cost_table = get_baseline_cost_table(state.rev, analysis.eof_header().version);

auto* tracer = vm.get_tracer();
if (INTX_UNLIKELY(tracer != nullptr))
{
tracer->notify_execution_start(state.rev, *state.msg, analysis.executable_code);
gas = dispatch<true>(cost_table, state, gas, code.data(), tracer);
tracer->notify_execution_start(state.rev, *state.msg, analysis.account_code());
gas = dispatch<true>(cost_table, state, gas, code, tracer);
}
else
{
#if EVMONE_CGOTO_SUPPORTED
if (vm.cgoto)
gas = dispatch_cgoto(cost_table, state, gas, code.data());
gas = dispatch_cgoto(cost_table, state, gas, code);
else
#endif
gas = dispatch<false>(cost_table, state, gas, code.data());
gas = dispatch<false>(cost_table, state, gas, code);
}

const auto gas_left = (state.status == EVMC_SUCCESS || state.status == EVMC_REVERT) ? gas : 0;
Expand Down Expand Up @@ -350,7 +350,7 @@ evmc_result execute(evmc_vm* c_vm, const evmc_host_interface* host, evmc_host_co
}

const auto code_analysis = analyze(container, eof_enabled);
const auto data = code_analysis.eof_header.get_data(container);
const auto data = code_analysis.eof_header().get_data(container);
auto state = std::make_unique<ExecutionState>(*msg, rev, *host, ctx, container, data);
return execute(*vm, msg->gas, *state, code_analysis);
}
Expand Down
18 changes: 8 additions & 10 deletions lib/evmone/instructions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -741,14 +741,14 @@ Result sstore(StackTop stack, int64_t gas_left, ExecutionState& state) noexcept;
/// Internal jump implementation for JUMP/JUMPI instructions.
inline code_iterator jump_impl(ExecutionState& state, const uint256& dst) noexcept
{
const auto& jumpdest_map = state.analysis.baseline->jumpdest_map;
if (dst >= jumpdest_map.size() || !jumpdest_map[static_cast<size_t>(dst)])
if (dst[3] != 0 || dst[2] != 0 || dst[1] != 0 ||
!state.analysis.baseline->check_jumpdest(dst[0]))
{
state.status = EVMC_BAD_JUMP_DESTINATION;
return nullptr;
}

return &state.analysis.baseline->executable_code[static_cast<size_t>(dst)];
return &state.analysis.baseline->executable_code()[static_cast<size_t>(dst)];
}

/// JUMP instruction implementation using baseline::CodeAnalysis.
Expand Down Expand Up @@ -801,7 +801,7 @@ inline code_iterator rjumpv(StackTop stack, ExecutionState& /*state*/, code_iter

inline code_iterator pc(StackTop stack, ExecutionState& state, code_iterator pos) noexcept
{
stack.push(static_cast<uint64_t>(pos - state.analysis.baseline->executable_code.data()));
stack.push(static_cast<uint64_t>(pos - state.analysis.baseline->executable_code()));
return pos + 1;
}

Expand Down Expand Up @@ -1098,7 +1098,7 @@ Result eofcreate(
inline code_iterator callf(StackTop stack, ExecutionState& state, code_iterator pos) noexcept
{
const auto index = read_uint16_be(&pos[1]);
const auto& header = state.analysis.baseline->eof_header;
const auto& header = state.analysis.baseline->eof_header();
const auto stack_size = &stack.top() - state.stack_space.bottom();

const auto callee_required_stack_size =
Expand All @@ -1118,8 +1118,7 @@ inline code_iterator callf(StackTop stack, ExecutionState& state, code_iterator
state.call_stack.push_back(pos + 3);

const auto offset = header.code_offsets[index] - header.code_offsets[0];
auto code = state.analysis.baseline->executable_code;
return code.data() + offset;
return state.analysis.baseline->executable_code() + offset;
}

inline code_iterator retf(StackTop /*stack*/, ExecutionState& state, code_iterator /*pos*/) noexcept
Expand All @@ -1132,7 +1131,7 @@ inline code_iterator retf(StackTop /*stack*/, ExecutionState& state, code_iterat
inline code_iterator jumpf(StackTop stack, ExecutionState& state, code_iterator pos) noexcept
{
const auto index = read_uint16_be(&pos[1]);
const auto& header = state.analysis.baseline->eof_header;
const auto& header = state.analysis.baseline->eof_header();
const auto stack_size = &stack.top() - state.stack_space.bottom();

const auto callee_required_stack_size =
Expand All @@ -1144,8 +1143,7 @@ inline code_iterator jumpf(StackTop stack, ExecutionState& state, code_iterator
}

const auto offset = header.code_offsets[index] - header.code_offsets[0];
const auto code = state.analysis.baseline->executable_code;
return code.data() + offset;
return state.analysis.baseline->executable_code() + offset;
}

template <evmc_status_code StatusCode>
Expand Down
2 changes: 1 addition & 1 deletion lib/evmone/instructions_calls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ Result eofcreate(
const auto initcontainer_index = pos[1];
pos += 2;
const auto& container = state.original_code;
const auto& eof_header = state.analysis.baseline->eof_header;
const auto& eof_header = state.analysis.baseline->eof_header();
const auto initcontainer = eof_header.get_container(container, initcontainer_index);

// Charge for initcode hashing.
Expand Down

0 comments on commit e380a81

Please sign in to comment.