@@ -11,6 +11,15 @@ namespace evmone
1111{
1212namespace
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+
1423inline 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