Skip to content

Commit 1306ff1

Browse files
committed
Provide better execute() C++ API
Change the execute API for Advanced interpreter to map the Baseline API. The new API requires to provide the execution state object (user can make better decision how to allocate it) and the code analysis (it is bound to the code itself so user can cache them together).
1 parent c01c8a3 commit 1306ff1

File tree

4 files changed

+26
-24
lines changed

4 files changed

+26
-24
lines changed

lib/evmone/analysis.hpp

+3-10
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,7 @@ struct AdvancedExecutionState : ExecutionState
5555
/// Pointer to code analysis.
5656
const AdvancedCodeAnalysis* analysis = nullptr;
5757

58-
AdvancedExecutionState() = default;
59-
60-
AdvancedExecutionState(const evmc_message& message, evmc_revision revision,
61-
const evmc_host_interface& host_interface, evmc_host_context* host_ctx,
62-
const uint8_t* code_ptr, size_t code_size, const AdvancedCodeAnalysis& a) noexcept
63-
: ExecutionState{message, revision, host_interface, host_ctx, code_ptr, code_size},
64-
analysis{&a}
65-
{}
58+
using ExecutionState::ExecutionState;
6659

6760
/// Terminates the execution with the given status code.
6861
const instruction* exit(evmc_status_code status_code) noexcept
@@ -74,11 +67,11 @@ struct AdvancedExecutionState : ExecutionState
7467
/// Resets the contents of the execution_state so that it could be reused.
7568
void reset(const evmc_message& message, evmc_revision revision,
7669
const evmc_host_interface& host_interface, evmc_host_context* host_ctx,
77-
const uint8_t* code_ptr, size_t code_size, const AdvancedCodeAnalysis& a) noexcept
70+
const uint8_t* code_ptr, size_t code_size) noexcept
7871
{
7972
ExecutionState::reset(message, revision, host_interface, host_ctx, code_ptr, code_size);
8073
current_block_cost = 0;
81-
analysis = &a;
74+
analysis = nullptr;
8275
}
8376
};
8477

lib/evmone/execution.cpp

+14-10
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,26 @@
88

99
namespace evmone
1010
{
11-
evmc_result execute(evmc_vm* /*unused*/, const evmc_host_interface* host, evmc_host_context* ctx,
12-
evmc_revision rev, const evmc_message* msg, const uint8_t* code, size_t code_size) noexcept
11+
evmc_result execute(AdvancedExecutionState& state, const AdvancedCodeAnalysis& analysis) noexcept
1312
{
14-
const auto analysis = analyze(rev, code, code_size);
13+
state.analysis = &analysis; // Allow accessing the analysis by instructions.
1514

16-
auto state =
17-
std::make_unique<AdvancedExecutionState>(*msg, rev, *host, ctx, code, code_size, analysis);
18-
19-
const auto* instr = &state->analysis->instrs[0];
15+
const auto* instr = &state.analysis->instrs[0]; // Start with the first instruction.
2016
while (instr != nullptr)
21-
instr = instr->fn(instr, *state);
17+
instr = instr->fn(instr, state);
2218

2319
const auto gas_left =
24-
(state->status == EVMC_SUCCESS || state->status == EVMC_REVERT) ? state->gas_left : 0;
20+
(state.status == EVMC_SUCCESS || state.status == EVMC_REVERT) ? state.gas_left : 0;
2521

2622
return evmc::make_result(
27-
state->status, gas_left, &state->memory[state->output_offset], state->output_size);
23+
state.status, gas_left, &state.memory[state.output_offset], state.output_size);
24+
}
25+
26+
evmc_result execute(evmc_vm* /*unused*/, const evmc_host_interface* host, evmc_host_context* ctx,
27+
evmc_revision rev, const evmc_message* msg, const uint8_t* code, size_t code_size) noexcept
28+
{
29+
const auto analysis = analyze(rev, code, code_size);
30+
auto state = std::make_unique<AdvancedExecutionState>(*msg, rev, *host, ctx, code, code_size);
31+
return execute(*state, analysis);
2832
}
2933
} // namespace evmone

lib/evmone/execution.hpp

+7
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@
77

88
namespace evmone
99
{
10+
struct AdvancedExecutionState;
11+
struct AdvancedCodeAnalysis;
12+
13+
/// Execute the already analyzed code using the provided execution state.
14+
evmc_result execute(AdvancedExecutionState& state, const AdvancedCodeAnalysis& analysis) noexcept;
15+
16+
/// EVMC-compatible execute() function.
1017
evmc_result execute(evmc_vm* vm, const evmc_host_interface* host, evmc_host_context* ctx,
1118
evmc_revision rev, const evmc_message* msg, const uint8_t* code, size_t code_size) noexcept;
1219
} // namespace evmone

test/unittests/execution_state_test.cpp

+2-4
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,8 @@ TEST(execution_state, reset_advanced)
117117
msg2.gas = 13;
118118
const evmc_host_interface host_interface2{};
119119
const uint8_t code2[]{0x80, 0x81};
120-
evmone::AdvancedCodeAnalysis analysis2;
121120

122-
st.reset(
123-
msg2, EVMC_HOMESTEAD, host_interface2, nullptr, code2, std::size(code2), analysis2);
121+
st.reset(msg2, EVMC_HOMESTEAD, host_interface2, nullptr, code2, std::size(code2));
124122

125123
// TODO: We are not able to test HostContext with current API. It may require an execution
126124
// test.
@@ -136,7 +134,7 @@ TEST(execution_state, reset_advanced)
136134
EXPECT_EQ(st.output_offset, 0);
137135
EXPECT_EQ(st.output_size, 0);
138136
EXPECT_EQ(st.current_block_cost, 0u);
139-
EXPECT_EQ(st.analysis, &analysis2);
137+
EXPECT_EQ(st.analysis, nullptr);
140138
}
141139
}
142140

0 commit comments

Comments
 (0)