java-topology/defects/solc/patch/solc-0002-assembly-rjump-index.patch

37 lines
1.9 KiB
Diff
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# UNDF: UNDF-2026-000000289
diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp
index b8cb7c3..patched 100644
--- a/libevmasm/Assembly.cpp
+++ b/libevmasm/Assembly.cpp
@@ -1034,6 +1034,19 @@ uint16_t calculateMaxStackHeight(Assembly::CodeSection const& _section)
AssemblyItems const& items = _section.items;
solAssert(!items.empty());
uint16_t overallMaxHeight = _section.inputs;
std::stack<size_t> worklist;
std::vector<size_t> maxStackHeights(items.size(), UNVISITED);
+ // Build a tag-label → index map once so each RJUMP/CRJUMP target lookup
+ // is O(1) instead of O(N) linear scan. Without this, J jumps over N items
+ // costs O(J×N); with the map it costs O(J+N).
+ std::unordered_map<u256, size_t> tagIndex;
+ for (size_t i = 0; i < items.size(); ++i)
+ if (items[i].type() == Tag)
+ tagIndex.emplace(items[i].data(), i);
+
// Init first item stack height to number of inputs to the code section
// maxStackHeights stores stack height for an item before the item execution
maxStackHeights[0] = _section.inputs;
@@ -1073,8 +1086,10 @@ uint16_t calculateMaxStackHeight(Assembly::CodeSection const& _section)
// Add jumps destinations to successors
// TODO: Remember to add RJUMPV when it is supported.
if (item.type() == RelativeJump || item.type() == ConditionalRelativeJump)
{
- auto const tagIt = std::find(items.begin(), items.end(), item.tag());
- solAssert(tagIt != items.end(), "Tag not found.");
- successors.emplace_back(static_cast<size_t>(std::distance(items.begin(), tagIt)));
+ auto const mapIt = tagIndex.find(item.tag().data());
+ solAssert(mapIt != tagIndex.end(), "Tag not found.");
+ successors.emplace_back(mapIt->second);
// TODO: This assert fails until the code is not topologically sorted. Uncomment when sorting introduced.
// If backward jump the successor must be already visited.
// solAssert(idx <= successors.back() || maxStackHeights[successors.back()] != UNVISITED);