Skip to content

Commit 4247f71

Browse files
committed
WIP
1 parent 70da6b2 commit 4247f71

File tree

1 file changed

+28
-17
lines changed

1 file changed

+28
-17
lines changed

lib/evmone/analysis.cpp

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,15 @@ namespace evmone
1111
{
1212
namespace
1313
{
14+
struct block_analysis
15+
{
16+
int gas_cost = 0;
17+
18+
int stack_req = 0;
19+
int stack_max_growth = 0;
20+
int stack_change = 0;
21+
};
22+
1423
inline constexpr evmc_call_kind op2call_kind(uint8_t opcode) noexcept
1524
{
1625
switch (opcode)
@@ -52,9 +61,9 @@ code_analysis analyze(
5261
const auto* instr_table = evmc_get_instruction_metrics_table(rev);
5362

5463
size_t beginblock_instr_index = 0;
55-
block_info* block = nullptr;
64+
block_analysis block;
65+
bool no_block = false;
5666

57-
int block_stack_change = 0;
5867
int instr_index = 0;
5968

6069
const auto code_end = code + code_size;
@@ -65,15 +74,18 @@ code_analysis analyze(
6574

6675
const bool jumpdest = opcode == OP_JUMPDEST;
6776

68-
if (!block || jumpdest)
77+
if (no_block || jumpdest)
6978
{
79+
block = {};
80+
no_block = false;
81+
7082
// Create BEGINBLOCK instruction which either replaces JUMPDEST or is injected
7183
// in case there is no JUMPDEST.
7284
beginblock_instr_index = analysis.instrs.size();
7385
analysis.instrs.emplace_back(fns[OPX_BEGINBLOCK]);
7486

7587
// Start new block.
76-
block_stack_change = 0;
88+
block.stack_change = 0;
7789

7890
if (jumpdest) // Add the jumpdest to the map.
7991
{
@@ -85,25 +97,24 @@ code_analysis analyze(
8597
}
8698

8799
auto& instr = jumpdest ? analysis.instrs.back() : analysis.instrs.emplace_back(fns[opcode]);
88-
block = &analysis.instrs[beginblock_instr_index].arg.block;
100+
// block = &analysis.instrs[beginblock_instr_index].arg.block;
89101

90102
const auto metrics = instr_table[opcode];
91103
const auto instr_stack_req = metrics.num_stack_arguments;
92104
const auto instr_stack_change = metrics.num_stack_returned_items - instr_stack_req;
93105

94106
// TODO: Define a block_analysis struct with regular ints for analysis.
95107
// Compress it when block is closed.
96-
auto stack_req = instr_stack_req - block_stack_change;
97-
if (stack_req > std::numeric_limits<decltype(block->stack_req)>::max())
98-
stack_req = std::numeric_limits<decltype(block->stack_req)>::max();
108+
auto stack_req = instr_stack_req - block.stack_change;
109+
if (stack_req > std::numeric_limits<decltype(block.stack_req)>::max())
110+
stack_req = std::numeric_limits<decltype(block.stack_req)>::max();
99111

100-
block->stack_req = std::max(block->stack_req, static_cast<int16_t>(stack_req));
101-
block_stack_change += instr_stack_change;
102-
block->stack_max_growth =
103-
static_cast<int16_t>(std::max(int{block->stack_max_growth}, block_stack_change));
112+
block.stack_req = std::max(block.stack_req, stack_req);
113+
block.stack_change += instr_stack_change;
114+
block.stack_max_growth = std::max(block.stack_max_growth, block.stack_change);
104115

105116
if (metrics.gas_cost > 0) // can be -1 for undefined instruction
106-
block->gas_cost += metrics.gas_cost;
117+
block.gas_cost += metrics.gas_cost;
107118

108119
switch (opcode)
109120
{
@@ -161,7 +172,7 @@ code_analysis analyze(
161172
break;
162173

163174
case OP_GAS:
164-
instr.arg.p.number = block->gas_cost;
175+
instr.arg.p.number = block.gas_cost;
165176
break;
166177

167178
case OP_CALL:
@@ -170,7 +181,7 @@ code_analysis analyze(
170181
case OP_STATICCALL:
171182
case OP_CREATE:
172183
case OP_CREATE2:
173-
instr.arg.p.number = block->gas_cost;
184+
instr.arg.p.number = block.gas_cost;
174185
instr.arg.p.call_kind =
175186
op2call_kind(opcode == OP_STATICCALL ? uint8_t{OP_CALL} : opcode);
176187
break;
@@ -195,13 +206,13 @@ code_analysis analyze(
195206
case OP_RETURN:
196207
case OP_REVERT:
197208
case OP_SELFDESTRUCT:
198-
block = nullptr;
209+
no_block = true;
199210
break;
200211
}
201212
}
202213

203214
// Not terminated block or empty code.
204-
if (block || code_size == 0 || code[code_size - 1] == OP_JUMPI)
215+
if (!no_block || code_size == 0 || code[code_size - 1] == OP_JUMPI)
205216
analysis.instrs.emplace_back(fns[OP_STOP]);
206217

207218
// FIXME: assert(analysis.instrs.size() <= max_instrs_size);

0 commit comments

Comments
 (0)