-
Notifications
You must be signed in to change notification settings - Fork 294
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Drop op_table parameter in analysis() #167
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,33 +11,24 @@ | |
using namespace evmone; | ||
|
||
constexpr auto rev = EVMC_BYZANTIUM; | ||
|
||
const auto fake_fn_table = []() noexcept | ||
{ | ||
evmone::exec_fn_table fns; | ||
for (size_t i = 0; i < fns.size(); ++i) | ||
fns[i] = (evmone::exec_fn)i; | ||
return fns; | ||
} | ||
(); | ||
|
||
const auto& op_table = get_op_table(rev); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Danger of static init fiasco? in case There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The problem does not apply to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah right, haven't noticed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good notice anyway. |
||
|
||
TEST(analysis, example1) | ||
{ | ||
const auto code = push(0x2a) + push(0x1e) + OP_MSTORE8 + OP_MSIZE + push(0) + OP_SSTORE; | ||
const auto analysis = analyze(fake_fn_table, rev, &code[0], code.size()); | ||
const auto analysis = analyze(rev, &code[0], code.size()); | ||
|
||
ASSERT_EQ(analysis.instrs.size(), 8); | ||
|
||
EXPECT_EQ(analysis.instrs[0].fn, fake_fn_table[OPX_BEGINBLOCK]); | ||
EXPECT_EQ(analysis.instrs[0].fn, op_table[OPX_BEGINBLOCK]); | ||
EXPECT_EQ(analysis.instrs[0].arg.number, 0); | ||
EXPECT_EQ(analysis.instrs[1].fn, fake_fn_table[OP_PUSH1]); | ||
EXPECT_EQ(analysis.instrs[2].fn, fake_fn_table[OP_PUSH1]); | ||
EXPECT_EQ(analysis.instrs[3].fn, fake_fn_table[OP_MSTORE8]); | ||
EXPECT_EQ(analysis.instrs[4].fn, fake_fn_table[OP_MSIZE]); | ||
EXPECT_EQ(analysis.instrs[5].fn, fake_fn_table[OP_PUSH1]); | ||
EXPECT_EQ(analysis.instrs[6].fn, fake_fn_table[OP_SSTORE]); | ||
EXPECT_EQ(analysis.instrs[7].fn, fake_fn_table[OP_STOP]); | ||
EXPECT_EQ(analysis.instrs[1].fn, op_table[OP_PUSH1]); | ||
EXPECT_EQ(analysis.instrs[2].fn, op_table[OP_PUSH1]); | ||
EXPECT_EQ(analysis.instrs[3].fn, op_table[OP_MSTORE8]); | ||
EXPECT_EQ(analysis.instrs[4].fn, op_table[OP_MSIZE]); | ||
EXPECT_EQ(analysis.instrs[5].fn, op_table[OP_PUSH1]); | ||
EXPECT_EQ(analysis.instrs[6].fn, op_table[OP_SSTORE]); | ||
EXPECT_EQ(analysis.instrs[7].fn, op_table[OP_STOP]); | ||
|
||
ASSERT_EQ(analysis.blocks.size(), 1); | ||
EXPECT_EQ(analysis.blocks[0].gas_cost, 14); | ||
|
@@ -48,15 +39,15 @@ TEST(analysis, example1) | |
TEST(analysis, stack_up_and_down) | ||
{ | ||
const auto code = OP_DUP2 + 6 * OP_DUP1 + 10 * OP_POP + push(0); | ||
const auto analysis = analyze(fake_fn_table, rev, &code[0], code.size()); | ||
const auto analysis = analyze(rev, &code[0], code.size()); | ||
|
||
ASSERT_EQ(analysis.instrs.size(), 20); | ||
EXPECT_EQ(analysis.instrs[0].fn, fake_fn_table[OPX_BEGINBLOCK]); | ||
EXPECT_EQ(analysis.instrs[0].fn, op_table[OPX_BEGINBLOCK]); | ||
EXPECT_EQ(analysis.instrs[0].arg.number, 0); | ||
EXPECT_EQ(analysis.instrs[1].fn, fake_fn_table[OP_DUP2]); | ||
EXPECT_EQ(analysis.instrs[2].fn, fake_fn_table[OP_DUP1]); | ||
EXPECT_EQ(analysis.instrs[8].fn, fake_fn_table[OP_POP]); | ||
EXPECT_EQ(analysis.instrs[18].fn, fake_fn_table[OP_PUSH1]); | ||
EXPECT_EQ(analysis.instrs[1].fn, op_table[OP_DUP2]); | ||
EXPECT_EQ(analysis.instrs[2].fn, op_table[OP_DUP1]); | ||
EXPECT_EQ(analysis.instrs[8].fn, op_table[OP_POP]); | ||
EXPECT_EQ(analysis.instrs[18].fn, op_table[OP_PUSH1]); | ||
|
||
ASSERT_EQ(analysis.blocks.size(), 1); | ||
EXPECT_EQ(analysis.blocks[0].gas_cost, 7 * 3 + 10 * 2 + 3); | ||
|
@@ -68,11 +59,11 @@ TEST(analysis, push) | |
{ | ||
constexpr auto push_value = 0x8807060504030201; | ||
const auto code = push(push_value) + "7f00ee"; | ||
const auto analysis = analyze(fake_fn_table, rev, &code[0], code.size()); | ||
const auto analysis = analyze(rev, &code[0], code.size()); | ||
|
||
ASSERT_EQ(analysis.instrs.size(), 4); | ||
ASSERT_EQ(analysis.push_values.size(), 1); | ||
EXPECT_EQ(analysis.instrs[0].fn, fake_fn_table[OPX_BEGINBLOCK]); | ||
EXPECT_EQ(analysis.instrs[0].fn, op_table[OPX_BEGINBLOCK]); | ||
EXPECT_EQ(analysis.instrs[1].arg.small_push_value, push_value); | ||
EXPECT_EQ(analysis.instrs[2].arg.push_value, &analysis.push_values[0]); | ||
EXPECT_EQ(analysis.push_values[0], intx::uint256{0xee} << 240); | ||
|
@@ -84,20 +75,20 @@ TEST(analysis, jumpdest_skip) | |
// and no new block should be created in this place. | ||
|
||
const auto code = bytecode{} + OP_STOP + OP_JUMPDEST; | ||
auto analysis = evmone::analyze(fake_fn_table, rev, &code[0], code.size()); | ||
auto analysis = evmone::analyze(rev, &code[0], code.size()); | ||
|
||
EXPECT_EQ(analysis.blocks.size(), 2); | ||
ASSERT_EQ(analysis.instrs.size(), 4); | ||
EXPECT_EQ(analysis.instrs[0].fn, fake_fn_table[OPX_BEGINBLOCK]); | ||
EXPECT_EQ(analysis.instrs[1].fn, fake_fn_table[OP_STOP]); | ||
EXPECT_EQ(analysis.instrs[2].fn, fake_fn_table[OP_JUMPDEST]); | ||
EXPECT_EQ(analysis.instrs[3].fn, fake_fn_table[OP_STOP]); | ||
EXPECT_EQ(analysis.instrs[0].fn, op_table[OPX_BEGINBLOCK]); | ||
EXPECT_EQ(analysis.instrs[1].fn, op_table[OP_STOP]); | ||
EXPECT_EQ(analysis.instrs[2].fn, op_table[OP_JUMPDEST]); | ||
EXPECT_EQ(analysis.instrs[3].fn, op_table[OP_STOP]); | ||
} | ||
|
||
TEST(analysis, jump1) | ||
{ | ||
const auto code = jump(add(4, 2)) + OP_JUMPDEST + mstore(0, 3) + ret(0, 0x20) + jump(6); | ||
const auto analysis = analyze(fake_fn_table, rev, &code[0], code.size()); | ||
const auto analysis = analyze(rev, &code[0], code.size()); | ||
|
||
ASSERT_EQ(analysis.blocks.size(), 3); | ||
ASSERT_EQ(analysis.jumpdest_offsets.size(), 1); | ||
|
@@ -112,17 +103,17 @@ TEST(analysis, jump1) | |
TEST(analysis, empty) | ||
{ | ||
bytes code; | ||
auto analysis = evmone::analyze(fake_fn_table, rev, &code[0], code.size()); | ||
auto analysis = evmone::analyze(rev, &code[0], code.size()); | ||
|
||
EXPECT_EQ(analysis.blocks.size(), 0); | ||
ASSERT_EQ(analysis.instrs.size(), 1); | ||
EXPECT_EQ(analysis.instrs[0].fn, fake_fn_table[OP_STOP]); | ||
EXPECT_EQ(analysis.instrs[0].fn, op_table[OP_STOP]); | ||
} | ||
|
||
TEST(analysis, only_jumpdest) | ||
{ | ||
const auto code = bytecode{OP_JUMPDEST}; | ||
auto analysis = evmone::analyze(fake_fn_table, rev, &code[0], code.size()); | ||
auto analysis = evmone::analyze(rev, &code[0], code.size()); | ||
|
||
ASSERT_EQ(analysis.blocks.size(), 1); | ||
ASSERT_EQ(analysis.jumpdest_offsets.size(), 1); | ||
|
@@ -134,45 +125,45 @@ TEST(analysis, only_jumpdest) | |
TEST(analysis, jumpi_at_the_end) | ||
{ | ||
const auto code = bytecode{OP_JUMPI}; | ||
auto analysis = evmone::analyze(fake_fn_table, rev, &code[0], code.size()); | ||
auto analysis = evmone::analyze(rev, &code[0], code.size()); | ||
|
||
EXPECT_EQ(analysis.blocks.size(), 1); | ||
ASSERT_EQ(analysis.instrs.size(), 3); | ||
EXPECT_EQ(analysis.instrs[0].fn, fake_fn_table[OPX_BEGINBLOCK]); | ||
EXPECT_EQ(analysis.instrs[1].fn, fake_fn_table[OP_JUMPI]); | ||
EXPECT_EQ(analysis.instrs[2].fn, fake_fn_table[OP_STOP]); | ||
EXPECT_EQ(analysis.instrs[0].fn, op_table[OPX_BEGINBLOCK]); | ||
EXPECT_EQ(analysis.instrs[1].fn, op_table[OP_JUMPI]); | ||
EXPECT_EQ(analysis.instrs[2].fn, op_table[OP_STOP]); | ||
} | ||
|
||
TEST(analysis, terminated_last_block) | ||
{ | ||
// TODO: Even if the last basic block is properly terminated an additional artificial block | ||
// is going to be created with only STOP instruction. | ||
const auto code = ret(0, 0); | ||
auto analysis = evmone::analyze(fake_fn_table, rev, &code[0], code.size()); | ||
auto analysis = evmone::analyze(rev, &code[0], code.size()); | ||
|
||
EXPECT_EQ(analysis.blocks.size(), 1); | ||
ASSERT_EQ(analysis.instrs.size(), 4); | ||
EXPECT_EQ(analysis.instrs[0].fn, fake_fn_table[OPX_BEGINBLOCK]); | ||
EXPECT_EQ(analysis.instrs[3].fn, fake_fn_table[OP_RETURN]); | ||
EXPECT_EQ(analysis.instrs[0].fn, op_table[OPX_BEGINBLOCK]); | ||
EXPECT_EQ(analysis.instrs[3].fn, op_table[OP_RETURN]); | ||
} | ||
|
||
TEST(analysis, jumpdests_groups) | ||
{ | ||
const auto code = 3 * OP_JUMPDEST + push(1) + 3 * OP_JUMPDEST + push(2) + OP_JUMPI; | ||
auto analysis = evmone::analyze(fake_fn_table, rev, &code[0], code.size()); | ||
auto analysis = evmone::analyze(rev, &code[0], code.size()); | ||
|
||
EXPECT_EQ(analysis.blocks.size(), 6); | ||
ASSERT_EQ(analysis.instrs.size(), 10); | ||
EXPECT_EQ(analysis.instrs[0].fn, fake_fn_table[OP_JUMPDEST]); | ||
EXPECT_EQ(analysis.instrs[1].fn, fake_fn_table[OP_JUMPDEST]); | ||
EXPECT_EQ(analysis.instrs[2].fn, fake_fn_table[OP_JUMPDEST]); | ||
EXPECT_EQ(analysis.instrs[3].fn, fake_fn_table[OP_PUSH1]); | ||
EXPECT_EQ(analysis.instrs[4].fn, fake_fn_table[OP_JUMPDEST]); | ||
EXPECT_EQ(analysis.instrs[5].fn, fake_fn_table[OP_JUMPDEST]); | ||
EXPECT_EQ(analysis.instrs[6].fn, fake_fn_table[OP_JUMPDEST]); | ||
EXPECT_EQ(analysis.instrs[7].fn, fake_fn_table[OP_PUSH1]); | ||
EXPECT_EQ(analysis.instrs[8].fn, fake_fn_table[OP_JUMPI]); | ||
EXPECT_EQ(analysis.instrs[9].fn, fake_fn_table[OP_STOP]); | ||
EXPECT_EQ(analysis.instrs[0].fn, op_table[OP_JUMPDEST]); | ||
EXPECT_EQ(analysis.instrs[1].fn, op_table[OP_JUMPDEST]); | ||
EXPECT_EQ(analysis.instrs[2].fn, op_table[OP_JUMPDEST]); | ||
EXPECT_EQ(analysis.instrs[3].fn, op_table[OP_PUSH1]); | ||
EXPECT_EQ(analysis.instrs[4].fn, op_table[OP_JUMPDEST]); | ||
EXPECT_EQ(analysis.instrs[5].fn, op_table[OP_JUMPDEST]); | ||
EXPECT_EQ(analysis.instrs[6].fn, op_table[OP_JUMPDEST]); | ||
EXPECT_EQ(analysis.instrs[7].fn, op_table[OP_PUSH1]); | ||
EXPECT_EQ(analysis.instrs[8].fn, op_table[OP_JUMPI]); | ||
EXPECT_EQ(analysis.instrs[9].fn, op_table[OP_STOP]); | ||
|
||
|
||
ASSERT_EQ(analysis.jumpdest_offsets.size(), 6); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you make it exported?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Used in analysis tests (evmone is usually built as shared library).