Skip to content

eof: Contract creation fix and tests. #15595

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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