|
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[_pathFromRoot.back().asIndex()]->encodeAllPossibleSubPathsInAssemblyTree(_pathFromRoot, _assembliesOnPath); |
681 | 682 | }
|
682 | 683 | }
|
683 | 684 |
|
@@ -798,20 +799,20 @@ 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 (SubAssemblyID subID {0}; subID.value < m_subs.size(); ++subID.value) |
802 | 803 | {
|
803 | 804 | OptimiserSettings settings = _settings;
|
804 |
| - Assembly& sub = *m_subs[subId]; |
| 805 | + Assembly& sub = *m_subs[subID.asIndex()]; |
805 | 806 | std::set<size_t> referencedTags;
|
806 | 807 | for (auto& codeSection: m_codeSections)
|
807 |
| - referencedTags += JumpdestRemover::referencedTags(codeSection.items, subId); |
| 808 | + referencedTags += JumpdestRemover::referencedTags(codeSection.items, subID); |
808 | 809 | std::map<u256, u256> const& subTagReplacements = sub.optimiseInternal(
|
809 | 810 | settings,
|
810 | 811 | referencedTags
|
811 | 812 | );
|
812 | 813 | // Apply the replacements (can be empty).
|
813 | 814 | for (auto& codeSection: m_codeSections)
|
814 |
| - BlockDeduplicator::applyTagReplacement(codeSection.items, subTagReplacements, subId); |
| 815 | + BlockDeduplicator::applyTagReplacement(codeSection.items, subTagReplacements, subID); |
815 | 816 | }
|
816 | 817 |
|
817 | 818 | std::map<u256, u256> tagReplacements;
|
@@ -1188,7 +1189,7 @@ LinkerObject const& Assembly::assemble() const
|
1188 | 1189 | [[nodiscard]] bytes Assembly::assembleTag(AssemblyItem const& _item, size_t _pos, bool _addJumpDest) const
|
1189 | 1190 | {
|
1190 | 1191 | solRequire(_item.data() != 0, AssemblyException, "Invalid tag position.");
|
1191 |
| - solRequire(_item.splitForeignPushTag().first == std::numeric_limits<size_t>::max(), AssemblyException, "Foreign tag."); |
| 1192 | + solRequire(_item.splitForeignPushTag().first.empty(), AssemblyException, "Foreign tag."); |
1192 | 1193 | solRequire(_pos < 0xffffffffL, AssemblyException, "Tag too large.");
|
1193 | 1194 | size_t tagId = static_cast<size_t>(_item.data());
|
1194 | 1195 | solRequire(m_tagPositionsInBytecode[tagId] == std::numeric_limits<size_t>::max(), AssemblyException, "Duplicate tag position.");
|
@@ -1259,10 +1260,10 @@ LinkerObject const& Assembly::assembleLegacy() const
|
1259 | 1260 | if (item.type() == PushTag)
|
1260 | 1261 | {
|
1261 | 1262 | auto [subId, tagId] = item.splitForeignPushTag();
|
1262 |
| - if (subId == std::numeric_limits<size_t>::max()) |
| 1263 | + if (subId.empty()) |
1263 | 1264 | continue;
|
1264 |
| - assertThrow(subId < m_subs.size(), AssemblyException, "Invalid sub id"); |
1265 |
| - auto subTagPosition = m_subs[subId]->m_tagPositionsInBytecode.at(tagId); |
| 1265 | + solRequire(subId.value < m_subs.size(), AssemblyException, "Invalid sub id"); |
| 1266 | + auto subTagPosition = m_subs[subId.asIndex()]->m_tagPositionsInBytecode.at(tagId); |
1266 | 1267 | assertThrow(subTagPosition != std::numeric_limits<size_t>::max(), AssemblyException, "Reference to tag without position.");
|
1267 | 1268 | bytesPerTag = std::max(bytesPerTag, numberEncodingSize(subTagPosition));
|
1268 | 1269 | }
|
@@ -1332,17 +1333,18 @@ LinkerObject const& Assembly::assembleLegacy() const
|
1332 | 1333 | break;
|
1333 | 1334 | case PushSub:
|
1334 | 1335 | assembleInstruction([&]() {
|
1335 |
| - assertThrow(item.data() <= std::numeric_limits<size_t>::max(), AssemblyException, ""); |
1336 | 1336 | ret.bytecode.push_back(dataRefPush);
|
1337 |
| - subRefs.insert(std::make_pair(static_cast<size_t>(item.data()), ret.bytecode.size())); |
| 1337 | + subRefs.emplace( |
| 1338 | + SubAssemblyID{item.data()}, |
| 1339 | + ret.bytecode.size() |
| 1340 | + ); |
1338 | 1341 | ret.bytecode.resize(ret.bytecode.size() + bytesPerDataRef);
|
1339 | 1342 | });
|
1340 | 1343 | break;
|
1341 | 1344 | case PushSubSize:
|
1342 | 1345 | {
|
1343 | 1346 | 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(); |
| 1347 | + auto s = subAssemblyById(SubAssemblyID{item.data()})->assemble().bytecode.size(); |
1346 | 1348 | item.setPushedValue(u256(s));
|
1347 | 1349 | unsigned b = std::max<unsigned>(1, numberEncodingSize(s));
|
1348 | 1350 | ret.bytecode.push_back(static_cast<uint8_t>(pushInstruction(b)));
|
@@ -1478,14 +1480,12 @@ LinkerObject const& Assembly::assembleLegacy() const
|
1478 | 1480 | }
|
1479 | 1481 | for (auto const& i: tagRefs)
|
1480 | 1482 | {
|
1481 |
| - size_t subId; |
1482 |
| - size_t tagId; |
1483 |
| - std::tie(subId, tagId) = i.second; |
1484 |
| - assertThrow(subId == std::numeric_limits<size_t>::max() || subId < m_subs.size(), AssemblyException, "Invalid sub id"); |
| 1483 | + auto [subId, tagId] = i.second; |
| 1484 | + solRequire(subId.empty() || subId.value < m_subs.size(), AssemblyException, "Invalid sub id"); |
1485 | 1485 | std::vector<size_t> const& tagPositions =
|
1486 |
| - subId == std::numeric_limits<size_t>::max() ? |
| 1486 | + subId.empty() ? |
1487 | 1487 | m_tagPositionsInBytecode :
|
1488 |
| - m_subs[subId]->m_tagPositionsInBytecode; |
| 1488 | + m_subs[subId.asIndex()]->m_tagPositionsInBytecode; |
1489 | 1489 | assertThrow(tagId < tagPositions.size(), AssemblyException, "Reference to non-existing tag.");
|
1490 | 1490 | size_t pos = tagPositions[tagId];
|
1491 | 1491 | assertThrow(pos != std::numeric_limits<size_t>::max(), AssemblyException, "Reference to tag without position.");
|
@@ -1796,47 +1796,46 @@ LinkerObject const& Assembly::assembleEOF() const
|
1796 | 1796 | return ret;
|
1797 | 1797 | }
|
1798 | 1798 |
|
1799 |
| -std::vector<size_t> Assembly::decodeSubPath(size_t _subObjectId) const |
| 1799 | +std::vector<SubAssemblyID> Assembly::decodeSubPath(SubAssemblyID _subObjectId) const |
1800 | 1800 | {
|
1801 |
| - if (_subObjectId < m_subs.size()) |
| 1801 | + if (_subObjectId.value < m_subs.size()) |
1802 | 1802 | return {_subObjectId};
|
1803 | 1803 |
|
1804 |
| - auto subIdPathIt = find_if( |
1805 |
| - m_subPaths.begin(), |
1806 |
| - m_subPaths.end(), |
| 1804 | + auto subIdPathIt = ranges::find_if( |
| 1805 | + m_subPaths, |
1807 | 1806 | [_subObjectId](auto const& subId) { return subId.second == _subObjectId; }
|
1808 | 1807 | );
|
1809 | 1808 |
|
1810 | 1809 | assertThrow(subIdPathIt != m_subPaths.end(), AssemblyException, "");
|
1811 | 1810 | return subIdPathIt->first;
|
1812 | 1811 | }
|
1813 | 1812 |
|
1814 |
| -size_t Assembly::encodeSubPath(std::vector<size_t> const& _subPath) |
| 1813 | +SubAssemblyID Assembly::encodeSubPath(std::vector<SubAssemblyID> const& _subPath) |
1815 | 1814 | {
|
1816 | 1815 | assertThrow(!_subPath.empty(), AssemblyException, "");
|
1817 | 1816 | if (_subPath.size() == 1)
|
1818 | 1817 | {
|
1819 |
| - assertThrow(_subPath[0] < m_subs.size(), AssemblyException, ""); |
| 1818 | + solAssert(_subPath[0].value < m_subs.size()); |
1820 | 1819 | return _subPath[0];
|
1821 | 1820 | }
|
1822 | 1821 |
|
1823 |
| - if (m_subPaths.find(_subPath) == m_subPaths.end()) |
| 1822 | + if (!m_subPaths.contains(_subPath)) |
1824 | 1823 | {
|
1825 |
| - size_t objectId = std::numeric_limits<size_t>::max() - m_subPaths.size(); |
1826 |
| - assertThrow(objectId >= m_subs.size(), AssemblyException, ""); |
| 1824 | + SubAssemblyID const objectId{std::numeric_limits<SubAssemblyID::value_type>::max() - m_subPaths.size()}; |
| 1825 | + solAssert(objectId.value >= m_subs.size()); |
1827 | 1826 | m_subPaths[_subPath] = objectId;
|
1828 | 1827 | }
|
1829 | 1828 |
|
1830 | 1829 | return m_subPaths[_subPath];
|
1831 | 1830 | }
|
1832 | 1831 |
|
1833 |
| -Assembly const* Assembly::subAssemblyById(size_t _subId) const |
| 1832 | +Assembly const* Assembly::subAssemblyById(SubAssemblyID const _subId) const |
1834 | 1833 | {
|
1835 |
| - std::vector<size_t> subIds = decodeSubPath(_subId); |
| 1834 | + std::vector<SubAssemblyID> subIDs = decodeSubPath(_subId); |
1836 | 1835 | Assembly const* currentAssembly = this;
|
1837 |
| - for (size_t currentSubId: subIds) |
| 1836 | + for (auto const& subID: subIDs) |
1838 | 1837 | {
|
1839 |
| - currentAssembly = currentAssembly->m_subs.at(currentSubId).get(); |
| 1838 | + currentAssembly = currentAssembly->m_subs.at(subID.asIndex()).get(); |
1840 | 1839 | assertThrow(currentAssembly, AssemblyException, "");
|
1841 | 1840 | }
|
1842 | 1841 |
|
|
0 commit comments