|
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>
|
@@ -715,17 +716,17 @@ std::pair<std::shared_ptr<Assembly>, std::vector<std::string>> Assembly::fromJSO
|
715 | 716 | return std::make_pair(result, _level == 0 ? parsedSourceList : std::vector<std::string>{});
|
716 | 717 | }
|
717 | 718 |
|
718 |
| -void Assembly::encodeAllPossibleSubPathsInAssemblyTree(std::vector<size_t> _pathFromRoot, std::vector<Assembly*> _assembliesOnPath) |
| 719 | +void Assembly::encodeAllPossibleSubPathsInAssemblyTree(std::vector<SubAssemblyID> _pathFromRoot, std::vector<Assembly*> _assembliesOnPath) |
719 | 720 | {
|
720 | 721 | _assembliesOnPath.push_back(this);
|
721 |
| - for (_pathFromRoot.push_back(0); _pathFromRoot.back() < m_subs.size(); ++_pathFromRoot.back()) |
| 722 | + for (_pathFromRoot.push_back(SubAssemblyID{0}); _pathFromRoot.back().value < m_subs.size(); ++_pathFromRoot.back().value) |
722 | 723 | {
|
723 | 724 | for (size_t distanceFromRoot = 0; distanceFromRoot < _assembliesOnPath.size(); ++distanceFromRoot)
|
724 | 725 | _assembliesOnPath[distanceFromRoot]->encodeSubPath(
|
725 | 726 | _pathFromRoot | ranges::views::drop_exactly(distanceFromRoot) | ranges::to<std::vector>
|
726 | 727 | );
|
727 | 728 |
|
728 |
| - m_subs[_pathFromRoot.back()]->encodeAllPossibleSubPathsInAssemblyTree(_pathFromRoot, _assembliesOnPath); |
| 729 | + m_subs[_pathFromRoot.back().asIndex()]->encodeAllPossibleSubPathsInAssemblyTree(_pathFromRoot, _assembliesOnPath); |
729 | 730 | }
|
730 | 731 | }
|
731 | 732 |
|
@@ -846,20 +847,20 @@ std::map<u256, u256> const& Assembly::optimiseInternal(
|
846 | 847 |
|
847 | 848 | // Run optimisation for sub-assemblies.
|
848 | 849 | // TODO: verify and double-check this for EOF.
|
849 |
| - for (size_t subId = 0; subId < m_subs.size(); ++subId) |
| 850 | + for (SubAssemblyID subID{0}; subID.value < m_subs.size(); ++subID.value) |
850 | 851 | {
|
851 | 852 | OptimiserSettings settings = _settings;
|
852 |
| - Assembly& sub = *m_subs[subId]; |
| 853 | + Assembly& sub = *m_subs[subID.asIndex()]; |
853 | 854 | std::set<size_t> referencedTags;
|
854 | 855 | for (auto& codeSection: m_codeSections)
|
855 |
| - referencedTags += JumpdestRemover::referencedTags(codeSection.items, subId); |
| 856 | + referencedTags += JumpdestRemover::referencedTags(codeSection.items, subID); |
856 | 857 | std::map<u256, u256> const& subTagReplacements = sub.optimiseInternal(
|
857 | 858 | settings,
|
858 | 859 | referencedTags
|
859 | 860 | );
|
860 | 861 | // Apply the replacements (can be empty).
|
861 | 862 | for (auto& codeSection: m_codeSections)
|
862 |
| - BlockDeduplicator::applyTagReplacement(codeSection.items, subTagReplacements, subId); |
| 863 | + BlockDeduplicator::applyTagReplacement(codeSection.items, subTagReplacements, subID); |
863 | 864 | }
|
864 | 865 |
|
865 | 866 | std::map<u256, u256> tagReplacements;
|
@@ -1235,7 +1236,7 @@ LinkerObject const& Assembly::assemble() const
|
1235 | 1236 | [[nodiscard]] bytes Assembly::assembleTag(AssemblyItem const& _item, size_t _pos, bool _addJumpDest) const
|
1236 | 1237 | {
|
1237 | 1238 | solRequire(_item.data() != 0, AssemblyException, "Invalid tag position.");
|
1238 |
| - solRequire(_item.splitForeignPushTag().first == std::numeric_limits<size_t>::max(), AssemblyException, "Foreign tag."); |
| 1239 | + solRequire(_item.splitForeignPushTag().first.empty(), AssemblyException, "Foreign tag."); |
1239 | 1240 | solRequire(_pos < 0xffffffffL, AssemblyException, "Tag too large.");
|
1240 | 1241 | size_t tagId = static_cast<size_t>(_item.data());
|
1241 | 1242 | solRequire(m_tagPositionsInBytecode[tagId] == std::numeric_limits<size_t>::max(), AssemblyException, "Duplicate tag position.");
|
@@ -1306,10 +1307,10 @@ LinkerObject const& Assembly::assembleLegacy() const
|
1306 | 1307 | if (item.type() == PushTag)
|
1307 | 1308 | {
|
1308 | 1309 | auto [subId, tagId] = item.splitForeignPushTag();
|
1309 |
| - if (subId == std::numeric_limits<size_t>::max()) |
| 1310 | + if (subId.empty()) |
1310 | 1311 | continue;
|
1311 |
| - assertThrow(subId < m_subs.size(), AssemblyException, "Invalid sub id"); |
1312 |
| - auto subTagPosition = m_subs[subId]->m_tagPositionsInBytecode.at(tagId); |
| 1312 | + solAssert(subId.value < m_subs.size(), "Invalid sub id"); |
| 1313 | + auto subTagPosition = m_subs[subId.asIndex()]->m_tagPositionsInBytecode.at(tagId); |
1313 | 1314 | assertThrow(subTagPosition != std::numeric_limits<size_t>::max(), AssemblyException, "Reference to tag without position.");
|
1314 | 1315 | bytesPerTag = std::max(bytesPerTag, numberEncodingSize(subTagPosition));
|
1315 | 1316 | }
|
@@ -1358,15 +1359,15 @@ LinkerObject const& Assembly::assembleLegacy() const
|
1358 | 1359 | ret.bytecode.resize(ret.bytecode.size() + bytesPerDataRef);
|
1359 | 1360 | break;
|
1360 | 1361 | case PushSub:
|
1361 |
| - assertThrow(item.data() <= std::numeric_limits<size_t>::max(), AssemblyException, ""); |
| 1362 | + solAssert(item.data() <= std::numeric_limits<SubAssemblyID::ValueType>::max()); |
1362 | 1363 | ret.bytecode.push_back(dataRefPush);
|
1363 |
| - subRefs.insert(std::make_pair(static_cast<size_t>(item.data()), ret.bytecode.size())); |
| 1364 | + subRefs.emplace(SubAssemblyID{item.data()}, ret.bytecode.size()); |
1364 | 1365 | ret.bytecode.resize(ret.bytecode.size() + bytesPerDataRef);
|
1365 | 1366 | break;
|
1366 | 1367 | case PushSubSize:
|
1367 | 1368 | {
|
1368 |
| - assertThrow(item.data() <= std::numeric_limits<size_t>::max(), AssemblyException, ""); |
1369 |
| - auto s = subAssemblyById(static_cast<size_t>(item.data()))->assemble().bytecode.size(); |
| 1369 | + solAssert(item.data() <= std::numeric_limits<SubAssemblyID::ValueType>::max()); |
| 1370 | + auto s = subAssemblyById(SubAssemblyID{item.data()})->assemble().bytecode.size(); |
1370 | 1371 | item.setPushedValue(u256(s));
|
1371 | 1372 | unsigned b = std::max<unsigned>(1, numberEncodingSize(s));
|
1372 | 1373 | ret.bytecode.push_back(static_cast<uint8_t>(pushInstruction(b)));
|
@@ -1481,14 +1482,12 @@ LinkerObject const& Assembly::assembleLegacy() const
|
1481 | 1482 | }
|
1482 | 1483 | for (auto const& i: tagRefs)
|
1483 | 1484 | {
|
1484 |
| - size_t subId; |
1485 |
| - size_t tagId; |
1486 |
| - std::tie(subId, tagId) = i.second; |
1487 |
| - assertThrow(subId == std::numeric_limits<size_t>::max() || subId < m_subs.size(), AssemblyException, "Invalid sub id"); |
| 1485 | + auto [subId, tagId] = i.second; |
| 1486 | + solAssert(subId.empty() || subId.value < m_subs.size(), "Invalid sub id"); |
1488 | 1487 | std::vector<size_t> const& tagPositions =
|
1489 |
| - subId == std::numeric_limits<size_t>::max() ? |
| 1488 | + subId.empty() ? |
1490 | 1489 | m_tagPositionsInBytecode :
|
1491 |
| - m_subs[subId]->m_tagPositionsInBytecode; |
| 1490 | + m_subs[subId.asIndex()]->m_tagPositionsInBytecode; |
1492 | 1491 | assertThrow(tagId < tagPositions.size(), AssemblyException, "Reference to non-existing tag.");
|
1493 | 1492 | size_t pos = tagPositions[tagId];
|
1494 | 1493 | assertThrow(pos != std::numeric_limits<size_t>::max(), AssemblyException, "Reference to tag without position.");
|
@@ -1813,47 +1812,46 @@ LinkerObject const& Assembly::assembleEOF() const
|
1813 | 1812 | return ret;
|
1814 | 1813 | }
|
1815 | 1814 |
|
1816 |
| -std::vector<size_t> Assembly::decodeSubPath(size_t _subObjectId) const |
| 1815 | +std::vector<SubAssemblyID> Assembly::decodeSubPath(SubAssemblyID _subObjectId) const |
1817 | 1816 | {
|
1818 |
| - if (_subObjectId < m_subs.size()) |
| 1817 | + if (_subObjectId.value < m_subs.size()) |
1819 | 1818 | return {_subObjectId};
|
1820 | 1819 |
|
1821 |
| - auto subIdPathIt = find_if( |
1822 |
| - m_subPaths.begin(), |
1823 |
| - m_subPaths.end(), |
| 1820 | + auto subIdPathIt = ranges::find_if( |
| 1821 | + m_subPaths, |
1824 | 1822 | [_subObjectId](auto const& subId) { return subId.second == _subObjectId; }
|
1825 | 1823 | );
|
1826 | 1824 |
|
1827 | 1825 | assertThrow(subIdPathIt != m_subPaths.end(), AssemblyException, "");
|
1828 | 1826 | return subIdPathIt->first;
|
1829 | 1827 | }
|
1830 | 1828 |
|
1831 |
| -size_t Assembly::encodeSubPath(std::vector<size_t> const& _subPath) |
| 1829 | +SubAssemblyID Assembly::encodeSubPath(std::vector<SubAssemblyID> const& _subPath) |
1832 | 1830 | {
|
1833 | 1831 | assertThrow(!_subPath.empty(), AssemblyException, "");
|
1834 | 1832 | if (_subPath.size() == 1)
|
1835 | 1833 | {
|
1836 |
| - assertThrow(_subPath[0] < m_subs.size(), AssemblyException, ""); |
| 1834 | + solAssert(_subPath[0].value < m_subs.size()); |
1837 | 1835 | return _subPath[0];
|
1838 | 1836 | }
|
1839 | 1837 |
|
1840 |
| - if (m_subPaths.find(_subPath) == m_subPaths.end()) |
| 1838 | + if (!m_subPaths.contains(_subPath)) |
1841 | 1839 | {
|
1842 |
| - size_t objectId = std::numeric_limits<size_t>::max() - m_subPaths.size(); |
1843 |
| - assertThrow(objectId >= m_subs.size(), AssemblyException, ""); |
| 1840 | + SubAssemblyID const objectId{std::numeric_limits<SubAssemblyID::ValueType>::max() - m_subPaths.size()}; |
| 1841 | + solAssert(objectId.value >= m_subs.size()); |
1844 | 1842 | m_subPaths[_subPath] = objectId;
|
1845 | 1843 | }
|
1846 | 1844 |
|
1847 | 1845 | return m_subPaths[_subPath];
|
1848 | 1846 | }
|
1849 | 1847 |
|
1850 |
| -Assembly const* Assembly::subAssemblyById(size_t _subId) const |
| 1848 | +Assembly const* Assembly::subAssemblyById(SubAssemblyID const _subId) const |
1851 | 1849 | {
|
1852 |
| - std::vector<size_t> subIds = decodeSubPath(_subId); |
| 1850 | + std::vector<SubAssemblyID> subIDs = decodeSubPath(_subId); |
1853 | 1851 | Assembly const* currentAssembly = this;
|
1854 |
| - for (size_t currentSubId: subIds) |
| 1852 | + for (auto const& subID: subIDs) |
1855 | 1853 | {
|
1856 |
| - currentAssembly = currentAssembly->m_subs.at(currentSubId).get(); |
| 1854 | + currentAssembly = currentAssembly->m_subs.at(subID.asIndex()).get(); |
1857 | 1855 | assertThrow(currentAssembly, AssemblyException, "");
|
1858 | 1856 | }
|
1859 | 1857 |
|
|
0 commit comments