From 9d7703e4b89a829e0c92d1871e1411ee0cba0d00 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 | 24 +++++++----------------- test/utils/dump.cpp | 2 +- 5 files changed, 13 insertions(+), 26 deletions(-) diff --git a/lib/evmone/analysis.cpp b/lib/evmone/analysis.cpp index 136f90e827..269db6ab31 100644 --- a/lib/evmone/analysis.cpp +++ b/lib/evmone/analysis.cpp @@ -155,9 +155,8 @@ code_analysis analyze(evmc_revision rev, const uint8_t* code, size_t code_size) 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.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. @@ -171,9 +170,8 @@ code_analysis analyze(evmc_revision rev, const uint8_t* code, size_t code_size) 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.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 a5de961a02..0c8900981a 100644 --- a/lib/evmone/analysis.hpp +++ b/lib/evmone/analysis.hpp @@ -185,7 +185,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 0d22510518..c8118cb18a 100644 --- a/lib/evmone/instructions.cpp +++ b/lib/evmone/instructions.cpp @@ -1202,7 +1202,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.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 7d3b42e676..73dc6ef056 100644 --- a/test/unittests/analysis_test.cpp +++ b/test/unittests/analysis_test.cpp @@ -21,7 +21,6 @@ TEST(analysis, example1) ASSERT_EQ(analysis.instrs.size(), 8); EXPECT_EQ(analysis.instrs[0].fn, op_table[OPX_BEGINBLOCK]); - EXPECT_EQ(analysis.instrs[0].arg.number, 0); 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]); @@ -30,10 +29,9 @@ TEST(analysis, example1) 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); - 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) @@ -43,16 +41,15 @@ TEST(analysis, stack_up_and_down) ASSERT_EQ(analysis.instrs.size(), 20); EXPECT_EQ(analysis.instrs[0].fn, op_table[OPX_BEGINBLOCK]); - EXPECT_EQ(analysis.instrs[0].arg.number, 0); 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); - 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) @@ -77,7 +74,6 @@ TEST(analysis, jumpdest_skip) const auto code = bytecode{} + OP_STOP + OP_JUMPDEST; 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, op_table[OPX_BEGINBLOCK]); EXPECT_EQ(analysis.instrs[1].fn, op_table[OP_STOP]); @@ -90,7 +86,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(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); @@ -105,7 +100,6 @@ TEST(analysis, empty) bytes code; auto analysis = evmone::analyze(rev, &code[0], code.size()); - EXPECT_EQ(analysis.blocks.size(), 1); ASSERT_EQ(analysis.instrs.size(), 2); EXPECT_EQ(analysis.instrs[0].fn, op_table[OPX_BEGINBLOCK]); EXPECT_EQ(analysis.instrs[1].fn, op_table[OP_STOP]); @@ -116,7 +110,6 @@ TEST(analysis, only_jumpdest) const auto code = bytecode{OP_JUMPDEST}; auto analysis = evmone::analyze(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); @@ -128,7 +121,6 @@ TEST(analysis, jumpi_at_the_end) const auto code = bytecode{OP_JUMPI}; 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, op_table[OPX_BEGINBLOCK]); EXPECT_EQ(analysis.instrs[1].fn, op_table[OP_JUMPI]); @@ -143,7 +135,6 @@ TEST(analysis, terminated_last_block) const auto code = ret(0, 0); auto analysis = evmone::analyze(rev, &code[0], code.size()); - EXPECT_EQ(analysis.blocks.size(), 2); ASSERT_EQ(analysis.instrs.size(), 6); EXPECT_EQ(analysis.instrs[0].fn, op_table[OPX_BEGINBLOCK]); EXPECT_EQ(analysis.instrs[3].fn, op_table[OP_RETURN]); @@ -156,7 +147,6 @@ TEST(analysis, jumpdests_groups) const auto code = 3 * OP_JUMPDEST + push(1) + 3 * OP_JUMPDEST + push(2) + OP_JUMPI; auto analysis = evmone::analyze(rev, &code[0], code.size()); - EXPECT_EQ(analysis.blocks.size(), 7); ASSERT_EQ(analysis.instrs.size(), 11); EXPECT_EQ(analysis.instrs[0].fn, op_table[OP_JUMPDEST]); EXPECT_EQ(analysis.instrs[1].fn, op_table[OP_JUMPDEST]); diff --git a/test/utils/dump.cpp b/test/utils/dump.cpp index 4785303c3b..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.number)]; + block = &instr.arg.block; const auto get_jumpdest_offset = [&analysis](size_t index) noexcept {