Skip to content

Commit 1afff51

Browse files
authored
Merge pull request #313 from ethereum/execute_api
Provide better execute() C++ API
2 parents c01c8a3 + 1306ff1 commit 1afff51

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)