Skip to content

Commit 9370155

Browse files
authored
Merge pull request #159 from ethereum/call_kind
Drop the call kind runtime argument
2 parents bf2fc13 + 759b414 commit 9370155

File tree

5 files changed

+32
-58
lines changed

5 files changed

+32
-58
lines changed

lib/evmone/analysis.cpp

+6-32
Original file line numberDiff line numberDiff line change
@@ -9,33 +9,12 @@
99

1010
namespace evmone
1111
{
12-
namespace
13-
{
14-
inline constexpr evmc_call_kind op2call_kind(uint8_t opcode) noexcept
15-
{
16-
switch (opcode)
17-
{
18-
default:
19-
case OP_CREATE:
20-
return EVMC_CREATE;
21-
case OP_CALL:
22-
return EVMC_CALL;
23-
case OP_CALLCODE:
24-
return EVMC_CALLCODE;
25-
case OP_DELEGATECALL:
26-
return EVMC_DELEGATECALL;
27-
case OP_CREATE2:
28-
return EVMC_CREATE2;
29-
}
30-
}
31-
3212
inline constexpr uint64_t load64be(const unsigned char* data) noexcept
3313
{
3414
return uint64_t{data[7]} | (uint64_t{data[6]} << 8) | (uint64_t{data[5]} << 16) |
3515
(uint64_t{data[4]} << 24) | (uint64_t{data[3]} << 32) | (uint64_t{data[2]} << 40) |
3616
(uint64_t{data[1]} << 48) | (uint64_t{data[0]} << 56);
3717
}
38-
} // namespace
3918

4019
code_analysis analyze(
4120
const exec_fn_table& fns, evmc_revision rev, const uint8_t* code, size_t code_size) noexcept
@@ -73,7 +52,7 @@ code_analysis analyze(
7352
// Create BEGINBLOCK instruction which either replaces JUMPDEST or is injected
7453
// in case there is no JUMPDEST.
7554
auto& beginblock_instr = analysis.instrs.emplace_back(fns[OPX_BEGINBLOCK]);
76-
beginblock_instr.arg.p.number = static_cast<int>(analysis.blocks.size() - 1);
55+
beginblock_instr.arg.number = static_cast<int>(analysis.blocks.size() - 1);
7756

7857
if (jumpdest) // Add the jumpdest to the map.
7958
{
@@ -150,32 +129,27 @@ code_analysis analyze(
150129
case ANY_DUP:
151130
// TODO: This is not needed, but we keep it
152131
// otherwise compiler will not use the jumptable for switch implementation.
153-
instr.arg.p.number = opcode - OP_DUP1;
132+
instr.arg.number = opcode - OP_DUP1;
154133
break;
155134

156135
case ANY_SWAP:
157136
// TODO: This is not needed, but we keep it
158137
// otherwise compiler will not use the jumptable for switch implementation.
159-
instr.arg.p.number = opcode - OP_SWAP1 + 1;
138+
instr.arg.number = opcode - OP_SWAP1 + 1;
160139
break;
161140

162141
case OP_GAS:
163-
instr.arg.p.number = block->gas_cost;
164-
break;
165-
166142
case OP_CALL:
167143
case OP_CALLCODE:
168144
case OP_DELEGATECALL:
169145
case OP_STATICCALL:
170146
case OP_CREATE:
171147
case OP_CREATE2:
172-
instr.arg.p.number = block->gas_cost;
173-
instr.arg.p.call_kind =
174-
op2call_kind(opcode == OP_STATICCALL ? uint8_t{OP_CALL} : opcode);
148+
instr.arg.number = block->gas_cost;
175149
break;
176150

177151
case OP_PC:
178-
instr.arg.p.number = static_cast<int>(code_pos - code - 1);
152+
instr.arg.number = static_cast<int>(code_pos - code - 1);
179153
break;
180154

181155
case OP_LOG0:
@@ -185,7 +159,7 @@ code_analysis analyze(
185159
case OP_LOG4:
186160
// TODO: This is not needed, but we keep it
187161
// otherwise compiler will not use the jumptable for switch implementation.
188-
instr.arg.p.number = opcode - OP_LOG0;
162+
instr.arg.number = opcode - OP_LOG0;
189163
break;
190164

191165
case OP_JUMP:

lib/evmone/analysis.hpp

+1-5
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,7 @@ struct execution_state
145145

146146
union instr_argument
147147
{
148-
struct p // A pair of fields.
149-
{
150-
int number;
151-
evmc_call_kind call_kind;
152-
} p;
148+
int number;
153149
const uint8_t* data;
154150
const intx::uint256* push_value;
155151
uint64_t small_push_value;

lib/evmone/instructions.cpp

+22-18
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ const instr_info* op_jumpi(const instr_info* instr, execution_state& state) noex
548548

549549
const instr_info* op_pc(const instr_info* instr, execution_state& state) noexcept
550550
{
551-
state.stack.push(instr->arg.p.number);
551+
state.stack.push(instr->arg.number);
552552
return ++instr;
553553
}
554554

@@ -560,7 +560,7 @@ const instr_info* op_msize(const instr_info* instr, execution_state& state) noex
560560

561561
const instr_info* op_gas(const instr_info* instr, execution_state& state) noexcept
562562
{
563-
const auto correction = state.current_block_cost - instr->arg.p.number;
563+
const auto correction = state.current_block_cost - instr->arg.number;
564564
const auto gas = static_cast<uint64_t>(state.gas_left + correction);
565565
state.stack.push(gas);
566566
return ++instr;
@@ -793,6 +793,7 @@ const instr_info* op_revert(const instr_info*, execution_state& state) noexcept
793793
return state.exit(EVMC_REVERT);
794794
}
795795

796+
template <evmc_call_kind kind>
796797
const instr_info* op_call(const instr_info* instr, execution_state& state) noexcept
797798
{
798799
const auto arg = instr->arg;
@@ -820,26 +821,29 @@ const instr_info* op_call(const instr_info* instr, execution_state& state) noexc
820821

821822

822823
auto msg = evmc_message{};
823-
msg.kind = arg.p.call_kind;
824+
msg.kind = kind;
824825
msg.flags = state.msg->flags;
825826
msg.value = intx::be::store<evmc::uint256be>(value);
826827

827-
auto correction = state.current_block_cost - arg.p.number;
828+
auto correction = state.current_block_cost - arg.number;
828829
auto gas_left = state.gas_left + correction;
829830

830831
auto cost = 0;
831832
auto has_value = value != 0;
833+
832834
if (has_value)
833-
{
834-
if (arg.p.call_kind == EVMC_CALL && state.msg->flags & EVMC_STATIC)
835-
return state.exit(EVMC_STATIC_MODE_VIOLATION);
836835
cost += 9000;
837-
}
838836

839-
if (arg.p.call_kind == EVMC_CALL && (has_value || state.rev < EVMC_SPURIOUS_DRAGON))
837+
if constexpr (kind == EVMC_CALL)
840838
{
841-
if (!state.host.account_exists(dst))
842-
cost += 25000;
839+
if (has_value && state.msg->flags & EVMC_STATIC)
840+
return state.exit(EVMC_STATIC_MODE_VIOLATION);
841+
842+
if (has_value || state.rev < EVMC_SPURIOUS_DRAGON)
843+
{
844+
if (!state.host.account_exists(dst))
845+
cost += 25000;
846+
}
843847
}
844848

845849
if ((gas_left -= cost) < 0)
@@ -938,7 +942,7 @@ const instr_info* op_delegatecall(const instr_info* instr, execution_state& stat
938942
auto msg = evmc_message{};
939943
msg.kind = EVMC_DELEGATECALL;
940944

941-
auto correction = state.current_block_cost - arg.p.number;
945+
auto correction = state.current_block_cost - arg.number;
942946
auto gas_left = state.gas_left + correction;
943947

944948
// TEST: Gas saturation for big gas values.
@@ -1013,7 +1017,7 @@ const instr_info* op_staticcall(const instr_info* instr, execution_state& state)
10131017

10141018
msg.depth = state.msg->depth + 1;
10151019

1016-
auto correction = state.current_block_cost - arg.p.number;
1020+
auto correction = state.current_block_cost - arg.number;
10171021
auto gas_left = state.gas_left + correction;
10181022

10191023
msg.gas = std::numeric_limits<int64_t>::max();
@@ -1077,7 +1081,7 @@ const instr_info* op_create(const instr_info* instr, execution_state& state) noe
10771081

10781082
auto msg = evmc_message{};
10791083

1080-
auto correction = state.current_block_cost - arg.p.number;
1084+
auto correction = state.current_block_cost - arg.number;
10811085
msg.gas = state.gas_left + correction;
10821086
if (state.rev >= EVMC_TANGERINE_WHISTLE)
10831087
msg.gas = msg.gas - msg.gas / 64;
@@ -1143,7 +1147,7 @@ const instr_info* op_create2(const instr_info* instr, execution_state& state) no
11431147

11441148
auto msg = evmc_message{};
11451149

1146-
auto correction = state.current_block_cost - arg.p.number;
1150+
auto correction = state.current_block_cost - arg.number;
11471151
auto gas = state.gas_left + correction;
11481152
msg.gas = gas - gas / 64;
11491153

@@ -1200,7 +1204,7 @@ const instr_info* op_selfdestruct(const instr_info*, execution_state& state) noe
12001204

12011205
const instr_info* opx_beginblock(const instr_info* instr, execution_state& state) noexcept
12021206
{
1203-
auto& block = state.analysis->blocks[static_cast<size_t>(instr->arg.p.number)];
1207+
auto& block = state.analysis->blocks[static_cast<size_t>(instr->arg.number)];
12041208

12051209
if ((state.gas_left -= block.gas_cost) < 0)
12061210
return state.exit(EVMC_OUT_OF_GAS);
@@ -1324,8 +1328,8 @@ constexpr exec_fn_table create_op_table_frontier() noexcept
13241328
table[OP_LOG4] = op_log<OP_LOG4>;
13251329

13261330
table[OP_CREATE] = op_create;
1327-
table[OP_CALL] = op_call;
1328-
table[OP_CALLCODE] = op_call;
1331+
table[OP_CALL] = op_call<EVMC_CALL>;
1332+
table[OP_CALLCODE] = op_call<EVMC_CALLCODE>;
13291333
table[OP_RETURN] = op_return;
13301334
table[OP_INVALID] = op_invalid;
13311335
table[OP_SELFDESTRUCT] = op_selfdestruct;

test/unittests/analysis_test.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ TEST(analysis, example1)
3030
ASSERT_EQ(analysis.instrs.size(), 8);
3131

3232
EXPECT_EQ(analysis.instrs[0].fn, fake_fn_table[OPX_BEGINBLOCK]);
33-
EXPECT_EQ(analysis.instrs[0].arg.p.number, 0);
33+
EXPECT_EQ(analysis.instrs[0].arg.number, 0);
3434
EXPECT_EQ(analysis.instrs[1].fn, fake_fn_table[OP_PUSH1]);
3535
EXPECT_EQ(analysis.instrs[2].fn, fake_fn_table[OP_PUSH1]);
3636
EXPECT_EQ(analysis.instrs[3].fn, fake_fn_table[OP_MSTORE8]);
@@ -52,7 +52,7 @@ TEST(analysis, stack_up_and_down)
5252

5353
ASSERT_EQ(analysis.instrs.size(), 20);
5454
EXPECT_EQ(analysis.instrs[0].fn, fake_fn_table[OPX_BEGINBLOCK]);
55-
EXPECT_EQ(analysis.instrs[0].arg.p.number, 0);
55+
EXPECT_EQ(analysis.instrs[0].arg.number, 0);
5656
EXPECT_EQ(analysis.instrs[1].fn, fake_fn_table[OP_DUP2]);
5757
EXPECT_EQ(analysis.instrs[2].fn, fake_fn_table[OP_DUP1]);
5858
EXPECT_EQ(analysis.instrs[8].fn, fake_fn_table[OP_POP]);

test/utils/dump.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ void dump(const evmone::code_analysis& analysis)
2828

2929
if (c == OPX_BEGINBLOCK)
3030
{
31-
block = &analysis.blocks[size_t(instr.arg.p.number)];
31+
block = &analysis.blocks[size_t(instr.arg.number)];
3232

3333
const auto get_jumpdest_offset = [&analysis](size_t index) noexcept
3434
{

0 commit comments

Comments
 (0)