|
39 | 39 | #include <fmt/format.h>
|
40 | 40 |
|
41 | 41 | #include <range/v3/algorithm/any_of.hpp>
|
| 42 | +#include <range/v3/algorithm/find_if.hpp> |
42 | 43 | #include <range/v3/view/drop_exactly.hpp>
|
43 | 44 | #include <range/v3/view/enumerate.hpp>
|
44 | 45 | #include <range/v3/view/map.hpp>
|
@@ -667,17 +668,17 @@ std::pair<std::shared_ptr<Assembly>, std::vector<std::string>> Assembly::fromJSO
|
667 | 668 | return std::make_pair(result, _level == 0 ? parsedSourceList : std::vector<std::string>{});
|
668 | 669 | }
|
669 | 670 |
|
670 |
| -void Assembly::encodeAllPossibleSubPathsInAssemblyTree(std::vector<size_t> _pathFromRoot, std::vector<Assembly*> _assembliesOnPath) |
| 671 | +void Assembly::encodeAllPossibleSubPathsInAssemblyTree(std::vector<SubAssemblyID> _pathFromRoot, std::vector<Assembly*> _assembliesOnPath) |
671 | 672 | {
|
672 | 673 | _assembliesOnPath.push_back(this);
|
673 |
| - for (_pathFromRoot.push_back(0); _pathFromRoot.back() < m_subs.size(); ++_pathFromRoot.back()) |
| 674 | + for (_pathFromRoot.push_back(SubAssemblyID{0}); _pathFromRoot.back().value < m_subs.size(); ++_pathFromRoot.back().value) |
674 | 675 | {
|
675 | 676 | for (size_t distanceFromRoot = 0; distanceFromRoot < _assembliesOnPath.size(); ++distanceFromRoot)
|
676 | 677 | _assembliesOnPath[distanceFromRoot]->encodeSubPath(
|
677 | 678 | _pathFromRoot | ranges::views::drop_exactly(distanceFromRoot) | ranges::to<std::vector>
|
678 | 679 | );
|
679 | 680 |
|
680 |
| - m_subs[_pathFromRoot.back()]->encodeAllPossibleSubPathsInAssemblyTree(_pathFromRoot, _assembliesOnPath); |
| 681 | + m_subs[static_cast<size_t>(_pathFromRoot.back().value)]->encodeAllPossibleSubPathsInAssemblyTree(_pathFromRoot, _assembliesOnPath); |
681 | 682 | }
|
682 | 683 | }
|
683 | 684 |
|
@@ -798,20 +799,21 @@ std::map<u256, u256> const& Assembly::optimiseInternal(
|
798 | 799 |
|
799 | 800 | // Run optimisation for sub-assemblies.
|
800 | 801 | // TODO: verify and double-check this for EOF.
|
801 |
| - for (size_t subId = 0; subId < m_subs.size(); ++subId) |
| 802 | + for (size_t subIDIndex = 0; subIDIndex < m_subs.size(); ++subIDIndex) |
802 | 803 | {
|
| 804 | + SubAssemblyID const subID{subIDIndex}; |
803 | 805 | OptimiserSettings settings = _settings;
|
804 |
| - Assembly& sub = *m_subs[subId]; |
| 806 | + Assembly& sub = *m_subs[subIDIndex]; |
805 | 807 | std::set<size_t> referencedTags;
|
806 | 808 | for (auto& codeSection: m_codeSections)
|
807 |
| - referencedTags += JumpdestRemover::referencedTags(codeSection.items, subId); |
| 809 | + referencedTags += JumpdestRemover::referencedTags(codeSection.items, subID); |
808 | 810 | std::map<u256, u256> const& subTagReplacements = sub.optimiseInternal(
|
809 | 811 | settings,
|
810 | 812 | referencedTags
|
811 | 813 | );
|
812 | 814 | // Apply the replacements (can be empty).
|
813 | 815 | for (auto& codeSection: m_codeSections)
|
814 |
| - BlockDeduplicator::applyTagReplacement(codeSection.items, subTagReplacements, subId); |
| 816 | + BlockDeduplicator::applyTagReplacement(codeSection.items, subTagReplacements, subID); |
815 | 817 | }
|
816 | 818 |
|
817 | 819 | std::map<u256, u256> tagReplacements;
|
@@ -1188,7 +1190,7 @@ LinkerObject const& Assembly::assemble() const
|
1188 | 1190 | [[nodiscard]] bytes Assembly::assembleTag(AssemblyItem const& _item, size_t _pos, bool _addJumpDest) const
|
1189 | 1191 | {
|
1190 | 1192 | solRequire(_item.data() != 0, AssemblyException, "Invalid tag position.");
|
1191 |
| - solRequire(_item.splitForeignPushTag().first == std::numeric_limits<size_t>::max(), AssemblyException, "Foreign tag."); |
| 1193 | + solRequire(_item.splitForeignPushTag().first.empty(), AssemblyException, "Foreign tag."); |
1192 | 1194 | solRequire(_pos < 0xffffffffL, AssemblyException, "Tag too large.");
|
1193 | 1195 | size_t tagId = static_cast<size_t>(_item.data());
|
1194 | 1196 | solRequire(m_tagPositionsInBytecode[tagId] == std::numeric_limits<size_t>::max(), AssemblyException, "Duplicate tag position.");
|
@@ -1259,10 +1261,10 @@ LinkerObject const& Assembly::assembleLegacy() const
|
1259 | 1261 | if (item.type() == PushTag)
|
1260 | 1262 | {
|
1261 | 1263 | auto [subId, tagId] = item.splitForeignPushTag();
|
1262 |
| - if (subId == std::numeric_limits<size_t>::max()) |
| 1264 | + if (subId.empty()) |
1263 | 1265 | continue;
|
1264 |
| - assertThrow(subId < m_subs.size(), AssemblyException, "Invalid sub id"); |
1265 |
| - auto subTagPosition = m_subs[subId]->m_tagPositionsInBytecode.at(tagId); |
| 1266 | + assertThrow(subId.value < m_subs.size(), AssemblyException, "Invalid sub id"); |
| 1267 | + auto subTagPosition = m_subs[static_cast<size_t>(subId.value)]->m_tagPositionsInBytecode.at(tagId); |
1266 | 1268 | assertThrow(subTagPosition != std::numeric_limits<size_t>::max(), AssemblyException, "Reference to tag without position.");
|
1267 | 1269 | bytesPerTag = std::max(bytesPerTag, numberEncodingSize(subTagPosition));
|
1268 | 1270 | }
|
@@ -1332,17 +1334,20 @@ LinkerObject const& Assembly::assembleLegacy() const
|
1332 | 1334 | break;
|
1333 | 1335 | case PushSub:
|
1334 | 1336 | assembleInstruction([&]() {
|
1335 |
| - assertThrow(item.data() <= std::numeric_limits<size_t>::max(), AssemblyException, ""); |
| 1337 | + assertThrow(item.data() <= std::numeric_limits<SubAssemblyID::value_type>::max(), AssemblyException, ""); |
1336 | 1338 | ret.bytecode.push_back(dataRefPush);
|
1337 |
| - subRefs.insert(std::make_pair(static_cast<size_t>(item.data()), ret.bytecode.size())); |
| 1339 | + subRefs.emplace( |
| 1340 | + SubAssemblyID{static_cast<SubAssemblyID::value_type>(item.data())}, |
| 1341 | + ret.bytecode.size() |
| 1342 | + ); |
1338 | 1343 | ret.bytecode.resize(ret.bytecode.size() + bytesPerDataRef);
|
1339 | 1344 | });
|
1340 | 1345 | break;
|
1341 | 1346 | case PushSubSize:
|
1342 | 1347 | {
|
1343 | 1348 | assembleInstruction([&](){
|
1344 |
| - assertThrow(item.data() <= std::numeric_limits<size_t>::max(), AssemblyException, ""); |
1345 |
| - auto s = subAssemblyById(static_cast<size_t>(item.data()))->assemble().bytecode.size(); |
| 1349 | + assertThrow(item.data() <= std::numeric_limits<SubAssemblyID::value_type>::max(), AssemblyException, ""); |
| 1350 | + auto s = subAssemblyById({static_cast<SubAssemblyID::value_type>(item.data())})->assemble().bytecode.size(); |
1346 | 1351 | item.setPushedValue(u256(s));
|
1347 | 1352 | unsigned b = std::max<unsigned>(1, numberEncodingSize(s));
|
1348 | 1353 | ret.bytecode.push_back(static_cast<uint8_t>(pushInstruction(b)));
|
@@ -1478,14 +1483,14 @@ LinkerObject const& Assembly::assembleLegacy() const
|
1478 | 1483 | }
|
1479 | 1484 | for (auto const& i: tagRefs)
|
1480 | 1485 | {
|
1481 |
| - size_t subId; |
| 1486 | + SubAssemblyID subId; |
1482 | 1487 | size_t tagId;
|
1483 | 1488 | std::tie(subId, tagId) = i.second;
|
1484 |
| - assertThrow(subId == std::numeric_limits<size_t>::max() || subId < m_subs.size(), AssemblyException, "Invalid sub id"); |
| 1489 | + assertThrow(subId.empty() || subId.value < m_subs.size(), AssemblyException, "Invalid sub id"); |
1485 | 1490 | std::vector<size_t> const& tagPositions =
|
1486 |
| - subId == std::numeric_limits<size_t>::max() ? |
| 1491 | + subId.empty() ? |
1487 | 1492 | m_tagPositionsInBytecode :
|
1488 |
| - m_subs[subId]->m_tagPositionsInBytecode; |
| 1493 | + m_subs[static_cast<size_t>(subId.value)]->m_tagPositionsInBytecode; |
1489 | 1494 | assertThrow(tagId < tagPositions.size(), AssemblyException, "Reference to non-existing tag.");
|
1490 | 1495 | size_t pos = tagPositions[tagId];
|
1491 | 1496 | assertThrow(pos != std::numeric_limits<size_t>::max(), AssemblyException, "Reference to tag without position.");
|
@@ -1796,47 +1801,46 @@ LinkerObject const& Assembly::assembleEOF() const
|
1796 | 1801 | return ret;
|
1797 | 1802 | }
|
1798 | 1803 |
|
1799 |
| -std::vector<size_t> Assembly::decodeSubPath(size_t _subObjectId) const |
| 1804 | +std::vector<SubAssemblyID> Assembly::decodeSubPath(SubAssemblyID _subObjectId) const |
1800 | 1805 | {
|
1801 |
| - if (_subObjectId < m_subs.size()) |
| 1806 | + if (_subObjectId.value < m_subs.size()) |
1802 | 1807 | return {_subObjectId};
|
1803 | 1808 |
|
1804 |
| - auto subIdPathIt = find_if( |
1805 |
| - m_subPaths.begin(), |
1806 |
| - m_subPaths.end(), |
| 1809 | + auto subIdPathIt = ranges::find_if( |
| 1810 | + m_subPaths, |
1807 | 1811 | [_subObjectId](auto const& subId) { return subId.second == _subObjectId; }
|
1808 | 1812 | );
|
1809 | 1813 |
|
1810 | 1814 | assertThrow(subIdPathIt != m_subPaths.end(), AssemblyException, "");
|
1811 | 1815 | return subIdPathIt->first;
|
1812 | 1816 | }
|
1813 | 1817 |
|
1814 |
| -size_t Assembly::encodeSubPath(std::vector<size_t> const& _subPath) |
| 1818 | +SubAssemblyID Assembly::encodeSubPath(std::vector<SubAssemblyID> const& _subPath) |
1815 | 1819 | {
|
1816 | 1820 | assertThrow(!_subPath.empty(), AssemblyException, "");
|
1817 | 1821 | if (_subPath.size() == 1)
|
1818 | 1822 | {
|
1819 |
| - assertThrow(_subPath[0] < m_subs.size(), AssemblyException, ""); |
| 1823 | + assertThrow(_subPath[0].value < m_subs.size(), AssemblyException, ""); |
1820 | 1824 | return _subPath[0];
|
1821 | 1825 | }
|
1822 | 1826 |
|
1823 |
| - if (m_subPaths.find(_subPath) == m_subPaths.end()) |
| 1827 | + if (!m_subPaths.contains(_subPath)) |
1824 | 1828 | {
|
1825 |
| - size_t objectId = std::numeric_limits<size_t>::max() - m_subPaths.size(); |
1826 |
| - assertThrow(objectId >= m_subs.size(), AssemblyException, ""); |
| 1829 | + SubAssemblyID const objectId{std::numeric_limits<SubAssemblyID::value_type>::max() - m_subPaths.size()}; |
| 1830 | + assertThrow(objectId.value >= m_subs.size(), AssemblyException, ""); |
1827 | 1831 | m_subPaths[_subPath] = objectId;
|
1828 | 1832 | }
|
1829 | 1833 |
|
1830 | 1834 | return m_subPaths[_subPath];
|
1831 | 1835 | }
|
1832 | 1836 |
|
1833 |
| -Assembly const* Assembly::subAssemblyById(size_t _subId) const |
| 1837 | +Assembly const* Assembly::subAssemblyById(SubAssemblyID const _subId) const |
1834 | 1838 | {
|
1835 |
| - std::vector<size_t> subIds = decodeSubPath(_subId); |
| 1839 | + std::vector<SubAssemblyID> subIDs = decodeSubPath(_subId); |
1836 | 1840 | Assembly const* currentAssembly = this;
|
1837 |
| - for (size_t currentSubId: subIds) |
| 1841 | + for (auto [subIDIndex]: subIDs) |
1838 | 1842 | {
|
1839 |
| - currentAssembly = currentAssembly->m_subs.at(currentSubId).get(); |
| 1843 | + currentAssembly = currentAssembly->m_subs.at(static_cast<size_t>(subIDIndex)).get(); |
1840 | 1844 | assertThrow(currentAssembly, AssemblyException, "");
|
1841 | 1845 | }
|
1842 | 1846 |
|
|
0 commit comments