Skip to content

Commit

Permalink
Split jumpdest map into 2 vectors of int16_t
Browse files Browse the repository at this point in the history
  • Loading branch information
chfast committed Aug 3, 2019
1 parent f49efce commit d3cfba8
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 14 deletions.
5 changes: 4 additions & 1 deletion lib/evmone/analysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ code_analysis analyze(
beginblock_instr.arg.p.number = static_cast<int>(analysis.blocks.size() - 1);

if (jumpdest) // Add the jumpdest to the map.
analysis.jumpdest_map.emplace_back(static_cast<int>(i), instr_index);
{
analysis.jumpdest_offsets.emplace_back(static_cast<int16_t>(i));
analysis.jumpdest_targets.emplace_back(static_cast<int16_t>(instr_index));
}
else // Increase instruction count because additional BEGINBLOCK was injected.
++instr_index;
}
Expand Down
18 changes: 13 additions & 5 deletions lib/evmone/analysis.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,15 +152,23 @@ struct code_analysis
/// invalidated when the container grows.
std::deque<bytes32> args_storage;

std::vector<std::pair<int, int>> jumpdest_map;
/// The offsets of JUMPDESTs in the original code.
/// These are values that JUMP/JUMPI receives as an argument.
/// The elements are sorted.
std::vector<int16_t> jumpdest_offsets;

/// The indexes of the instructions in the generated instruction table
/// matching the elements from jumdest_offsets.
/// This is value to which the next instruction pointer must be set in JUMP/JUMPI.
std::vector<int16_t> jumpdest_targets;
};

inline int find_jumpdest(const code_analysis& analysis, int offset) noexcept
{
const auto& m = analysis.jumpdest_map;
const auto it = std::lower_bound(std::begin(m), std::end(m), offset,
[](std::pair<int, int> p, int v) noexcept { return p.first < v; });
return (it != std::end(m) && it->first == offset) ? it->second : -1;
const auto begin = std::begin(analysis.jumpdest_offsets);
const auto end = std::end(analysis.jumpdest_offsets);
const auto it = std::lower_bound(begin, end, offset);
return (it != end && *it == offset) ? analysis.jumpdest_targets[it - begin] : -1;
}

EVMC_EXPORT code_analysis analyze(
Expand Down
12 changes: 8 additions & 4 deletions test/unittests/analysis_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,10 @@ TEST(analysis, jump1)
const auto analysis = analyze(fake_fn_table, rev, &code[0], code.size());

ASSERT_EQ(analysis.blocks.size(), 3);
ASSERT_EQ(analysis.jumpdest_map.size(), 1);
EXPECT_EQ(analysis.jumpdest_map[0], std::pair(6, 5));
ASSERT_EQ(analysis.jumpdest_offsets.size(), 1);
ASSERT_EQ(analysis.jumpdest_targets.size(), 1);
EXPECT_EQ(analysis.jumpdest_offsets[0], 6);
EXPECT_EQ(analysis.jumpdest_targets[0], 5);
EXPECT_EQ(find_jumpdest(analysis, 6), 5);
EXPECT_EQ(find_jumpdest(analysis, 0), -1);
EXPECT_EQ(find_jumpdest(analysis, 7), -1);
Expand All @@ -109,8 +111,10 @@ TEST(analysis, only_jumpdest)
auto analysis = evmone::analyze(fake_fn_table, rev, &code[0], code.size());

ASSERT_EQ(analysis.blocks.size(), 1);
ASSERT_EQ(analysis.jumpdest_map.size(), 1);
EXPECT_EQ(analysis.jumpdest_map[0], std::pair(0, 0));
ASSERT_EQ(analysis.jumpdest_offsets.size(), 1);
ASSERT_EQ(analysis.jumpdest_targets.size(), 1);
EXPECT_EQ(analysis.jumpdest_offsets[0], 0);
EXPECT_EQ(analysis.jumpdest_targets[0], 0);
}

TEST(analysis, jumpi_at_the_end)
Expand Down
8 changes: 4 additions & 4 deletions test/utils/dump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ void dump_analysis(const evmone::code_analysis& analysis)

auto get_jumpdest_offset = [&analysis](size_t index) noexcept
{
for (const auto& d : analysis.jumpdest_map)
for (size_t i = 0; i < analysis.jumpdest_targets.size(); ++i)
{
if (d.second == static_cast<int>(index))
return d.first;
if (i == index)
return analysis.jumpdest_offsets[i];
}
return -1;
return int16_t{-1};
};

std::cout << "";
Expand Down

0 comments on commit d3cfba8

Please sign in to comment.