From 78972803b9373d220560324b4307d30e0c5dea63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 27 Aug 2019 14:54:34 +0200 Subject: [PATCH] Keep block info in instruction argument --- lib/evmone/analysis.cpp | 10 ++++------ lib/evmone/analysis.hpp | 1 - lib/evmone/instructions.cpp | 2 +- test/unittests/analysis_test.cpp | 25 ++++++++----------------- test/utils/dump.cpp | 2 +- 5 files changed, 14 insertions(+), 26 deletions(-) diff --git a/lib/evmone/analysis.cpp b/lib/evmone/analysis.cpp index c5ec546441..fc965091f8 100644 --- a/lib/evmone/analysis.cpp +++ b/lib/evmone/analysis.cpp @@ -179,9 +179,8 @@ code_analysis analyze( static_cast(block.stack_req) : std::numeric_limits::max(); const auto stack_max_growth = static_cast(block.stack_max_growth); - analysis.blocks.emplace_back(block_info{block.gas_cost, stack_req, stack_max_growth}); - analysis.instrs[block.first_instruction_index].arg.p.number = - static_cast(analysis.blocks.size() - 1); + analysis.instrs[block.first_instruction_index].arg.block = { + block.gas_cost, stack_req, stack_max_growth}; // Create new block. analysis.instrs.emplace_back(fns[OPX_BEGINBLOCK]); @@ -194,9 +193,8 @@ code_analysis analyze( static_cast(block.stack_req) : std::numeric_limits::max(); const auto stack_max_growth = static_cast(block.stack_max_growth); - analysis.blocks.emplace_back(block_info{block.gas_cost, stack_req, stack_max_growth}); - analysis.instrs[block.first_instruction_index].arg.p.number = - static_cast(analysis.blocks.size() - 1); + analysis.instrs[block.first_instruction_index].arg.block = { + block.gas_cost, stack_req, stack_max_growth}; // Make sure the last block is terminated. // TODO: This is not needed if the last instruction is a terminating one. diff --git a/lib/evmone/analysis.hpp b/lib/evmone/analysis.hpp index 1cd1ca85eb..42ddcfc4be 100644 --- a/lib/evmone/analysis.hpp +++ b/lib/evmone/analysis.hpp @@ -189,7 +189,6 @@ static_assert(sizeof(block_info) == 8); struct code_analysis { std::vector instrs; - std::vector blocks; /// Storage for large push values. std::vector push_values; diff --git a/lib/evmone/instructions.cpp b/lib/evmone/instructions.cpp index bc806d6632..587bedbaf5 100644 --- a/lib/evmone/instructions.cpp +++ b/lib/evmone/instructions.cpp @@ -1200,7 +1200,7 @@ const instr_info* op_selfdestruct(const instr_info*, execution_state& state) noe const instr_info* opx_beginblock(const instr_info* instr, execution_state& state) noexcept { - auto& block = state.analysis->blocks[static_cast(instr->arg.p.number)]; + auto& block = instr->arg.block; if ((state.gas_left -= block.gas_cost) < 0) return state.exit(EVMC_OUT_OF_GAS); diff --git a/test/unittests/analysis_test.cpp b/test/unittests/analysis_test.cpp index da9b4239fe..215c6d0732 100644 --- a/test/unittests/analysis_test.cpp +++ b/test/unittests/analysis_test.cpp @@ -30,7 +30,6 @@ TEST(analysis, example1) ASSERT_EQ(analysis.instrs.size(), 8); EXPECT_EQ(analysis.instrs[0].fn, fake_fn_table[OPX_BEGINBLOCK]); - EXPECT_EQ(analysis.instrs[0].arg.p.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]); @@ -39,10 +38,9 @@ TEST(analysis, example1) EXPECT_EQ(analysis.instrs[6].fn, fake_fn_table[OP_SSTORE]); EXPECT_EQ(analysis.instrs[7].fn, fake_fn_table[OP_STOP]); - ASSERT_EQ(analysis.blocks.size(), 1); - EXPECT_EQ(analysis.blocks[0].gas_cost, 14); - EXPECT_EQ(analysis.blocks[0].stack_req, 0); - EXPECT_EQ(analysis.blocks[0].stack_max_growth, 2); + EXPECT_EQ(analysis.instrs[0].arg.block.gas_cost, 14); + EXPECT_EQ(analysis.instrs[0].arg.block.stack_req, 0); + EXPECT_EQ(analysis.instrs[0].arg.block.stack_max_growth, 2); } TEST(analysis, stack_up_and_down) @@ -52,16 +50,14 @@ TEST(analysis, stack_up_and_down) ASSERT_EQ(analysis.instrs.size(), 20); EXPECT_EQ(analysis.instrs[0].fn, fake_fn_table[OPX_BEGINBLOCK]); - EXPECT_EQ(analysis.instrs[0].arg.p.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]); - ASSERT_EQ(analysis.blocks.size(), 1); - EXPECT_EQ(analysis.blocks[0].gas_cost, 7 * 3 + 10 * 2 + 3); - EXPECT_EQ(analysis.blocks[0].stack_req, 3); - EXPECT_EQ(analysis.blocks[0].stack_max_growth, 7); + EXPECT_EQ(analysis.instrs[0].arg.block.gas_cost, 7 * 3 + 10 * 2 + 3); + EXPECT_EQ(analysis.instrs[0].arg.block.stack_req, 3); + EXPECT_EQ(analysis.instrs[0].arg.block.stack_max_growth, 7); } TEST(analysis, push) @@ -86,11 +82,12 @@ TEST(analysis, jumpdest_skip) const auto code = bytecode{} + OP_STOP + OP_JUMPDEST; auto analysis = evmone::analyze(fake_fn_table, 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[0].arg.block.gas_cost, 0); 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[2].arg.block.gas_cost, 1); EXPECT_EQ(analysis.instrs[3].fn, fake_fn_table[OP_STOP]); } @@ -99,7 +96,6 @@ 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()); - ASSERT_EQ(analysis.blocks.size(), 4); ASSERT_EQ(analysis.jumpdest_offsets.size(), 1); ASSERT_EQ(analysis.jumpdest_targets.size(), 1); EXPECT_EQ(analysis.jumpdest_offsets[0], 6); @@ -114,7 +110,6 @@ TEST(analysis, empty) bytes code; auto analysis = evmone::analyze(fake_fn_table, rev, &code[0], code.size()); - EXPECT_EQ(analysis.blocks.size(), 1); EXPECT_EQ(analysis.instrs.size(), 2); EXPECT_EQ(analysis.instrs[0].fn, fake_fn_table[OPX_BEGINBLOCK]); EXPECT_EQ(analysis.instrs[1].fn, fake_fn_table[OP_STOP]); @@ -125,7 +120,6 @@ TEST(analysis, only_jumpdest) const auto code = bytecode{OP_JUMPDEST}; auto analysis = evmone::analyze(fake_fn_table, rev, &code[0], code.size()); - ASSERT_EQ(analysis.blocks.size(), 1); ASSERT_EQ(analysis.jumpdest_offsets.size(), 1); ASSERT_EQ(analysis.jumpdest_targets.size(), 1); EXPECT_EQ(analysis.jumpdest_offsets[0], 0); @@ -137,7 +131,6 @@ TEST(analysis, jumpi_at_the_end) const auto code = bytecode{OP_JUMPI}; auto analysis = evmone::analyze(fake_fn_table, 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_JUMPI]); @@ -152,7 +145,6 @@ TEST(analysis, terminated_last_block) const auto code = ret(0, 0); auto analysis = evmone::analyze(fake_fn_table, rev, &code[0], code.size()); - EXPECT_EQ(analysis.blocks.size(), 2); ASSERT_EQ(analysis.instrs.size(), 6); EXPECT_EQ(analysis.instrs[0].fn, fake_fn_table[OPX_BEGINBLOCK]); EXPECT_EQ(analysis.instrs[3].fn, fake_fn_table[OP_RETURN]); @@ -165,7 +157,6 @@ 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()); - EXPECT_EQ(analysis.blocks.size(), 7); ASSERT_EQ(analysis.instrs.size(), 11); EXPECT_EQ(analysis.instrs[0].fn, fake_fn_table[OP_JUMPDEST]); EXPECT_EQ(analysis.instrs[1].fn, fake_fn_table[OP_JUMPDEST]); diff --git a/test/utils/dump.cpp b/test/utils/dump.cpp index 55db077d8d..d40f9b237b 100644 --- a/test/utils/dump.cpp +++ b/test/utils/dump.cpp @@ -28,7 +28,7 @@ void dump(const evmone::code_analysis& analysis) if (c == OPX_BEGINBLOCK) { - block = &analysis.blocks[size_t(instr.arg.p.number)]; + block = &instr.arg.block; const auto get_jumpdest_offset = [&analysis](size_t index) noexcept {