Skip to content

Commit

Permalink
Merge pull request #15595 from ipsilon/eof-container-id-fix
Browse files Browse the repository at this point in the history
eof: Contract creation fix and tests.
  • Loading branch information
cameel authored Nov 29, 2024
2 parents d2a7eb3 + 6b347a1 commit 0b01a8a
Show file tree
Hide file tree
Showing 6 changed files with 4,505 additions and 20 deletions.
25 changes: 16 additions & 9 deletions libevmasm/Assembly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -924,7 +924,7 @@ void appendBigEndianUint16(bytes& _dest, ValueT _value)
}
}

std::tuple<bytes, std::vector<size_t>, size_t> Assembly::createEOFHeader(std::set<uint16_t> const& _referencedSubIds) const
std::tuple<bytes, std::vector<size_t>, size_t> Assembly::createEOFHeader(std::set<ContainerID> const& _referencedSubIds) const
{
bytes retBytecode;
std::vector<size_t> codeSectionSizePositions;
Expand Down Expand Up @@ -1330,9 +1330,9 @@ LinkerObject const& Assembly::assembleLegacy() const
return ret;
}

std::map<uint16_t, uint16_t> Assembly::findReferencedContainers() const
std::map<ContainerID, ContainerID> Assembly::findReferencedContainers() const
{
std::set<uint16_t> referencedSubcontainersIds;
std::set<ContainerID> referencedSubcontainersIds;
solAssert(m_subs.size() <= 0x100); // According to EOF spec

for (auto&& codeSection: m_codeSections)
Expand All @@ -1344,12 +1344,13 @@ std::map<uint16_t, uint16_t> Assembly::findReferencedContainers() const
referencedSubcontainersIds.insert(containerId);
}

std::map<uint16_t, uint16_t> replacements;
std::map<ContainerID, ContainerID> replacements;
uint8_t nUnreferenced = 0;
for (uint8_t i = 0; i < static_cast<uint16_t>(m_subs.size()); ++i)
for (size_t i = 0; i < m_subs.size(); ++i)
{
if (referencedSubcontainersIds.count(i) > 0)
replacements[i] = static_cast<uint16_t>(i - nUnreferenced);
solAssert(i <= std::numeric_limits<ContainerID>::max());
if (referencedSubcontainersIds.count(static_cast<ContainerID>(i)) > 0)
replacements[static_cast<ContainerID>(i)] = static_cast<ContainerID>(i - nUnreferenced);
else
nUnreferenced++;
}
Expand Down Expand Up @@ -1441,13 +1442,19 @@ LinkerObject const& Assembly::assembleEOF() const
case EOFCreate:
{
ret.bytecode.push_back(static_cast<uint8_t>(Instruction::EOFCREATE));
ret.bytecode.push_back(static_cast<uint8_t>(item.data()));
solAssert(item.data() <= std::numeric_limits<ContainerID>::max());
auto const containerID = static_cast<ContainerID>(item.data());
solAssert(subIdsReplacements.count(containerID) == 1);
ret.bytecode.push_back(subIdsReplacements.at(containerID));
break;
}
case ReturnContract:
{
ret.bytecode.push_back(static_cast<uint8_t>(Instruction::RETURNCONTRACT));
ret.bytecode.push_back(static_cast<uint8_t>(item.data()));
solAssert(item.data() <= std::numeric_limits<ContainerID>::max());
auto const containerID = static_cast<ContainerID>(item.data());
solAssert(subIdsReplacements.count(containerID) == 1);
ret.bytecode.push_back(subIdsReplacements.at(containerID));
break;
}
case VerbatimBytecode:
Expand Down
4 changes: 2 additions & 2 deletions libevmasm/Assembly.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,13 +247,13 @@ class Assembly
std::shared_ptr<std::string const> sharedSourceName(std::string const& _name) const;

/// Returns EOF header bytecode | code section sizes offsets | data section size offset
std::tuple<bytes, std::vector<size_t>, size_t> createEOFHeader(std::set<uint16_t> const& _referencedSubIds) const;
std::tuple<bytes, std::vector<size_t>, size_t> createEOFHeader(std::set<ContainerID> const& _referencedSubIds) const;

LinkerObject const& assembleLegacy() const;
LinkerObject const& assembleEOF() const;

/// Returns map from m_subs to an index of subcontainer in the final EOF bytecode
std::map<uint16_t, uint16_t> findReferencedContainers() const;
std::map<ContainerID, ContainerID> findReferencedContainers() const;
/// Returns max AuxDataLoadN offset for the assembly.
std::optional<uint16_t> findMaxAuxDataLoadNOffset() const;

Expand Down
32 changes: 23 additions & 9 deletions libyul/AsmAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -800,13 +800,27 @@ bool AsmAnalyzer::validateInstructions(FunctionCall const& _functionCall)

void AsmAnalyzer::validateObjectStructure(langutil::SourceLocation _astRootLocation)
{
if (m_eofVersion.has_value() && util::contains(m_objectStructure.objectName, '.')) // No dots in object name for EOF
m_errorReporter.syntaxError(
9822_error,
_astRootLocation,
fmt::format(
"The object name \"{objectName}\" is invalid in EOF context. Object names must not contain 'dot' character.",
fmt::arg("objectName", m_objectStructure.objectName)
)
);
if (m_eofVersion.has_value())
{
if (util::contains(m_objectStructure.objectName, '.')) // No dots in object name for EOF
m_errorReporter.syntaxError(
9822_error,
_astRootLocation,
fmt::format(
"The object name \"{objectName}\" is invalid in EOF context. Object names must not contain 'dot' character.",
fmt::arg("objectName", m_objectStructure.objectName)
)
);
else if (m_objectStructure.topLevelSubObjectNames().size() > 256)
{
m_errorReporter.syntaxError(
1305_error,
_astRootLocation,
fmt::format(
"Too many subobjects in \"{objectName}\". At most 256 subobjects allowed when compiling to EOF",
fmt::arg("objectName", m_objectStructure.objectName)
)
);
}
}
}
Loading

0 comments on commit 0b01a8a

Please sign in to comment.