mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Some fixes.
This commit is contained in:
parent
64817db4ca
commit
4f205b2f9e
@ -541,15 +541,23 @@ LinkerObject const& Assembly::assemble() const
|
|||||||
// TODO: assert zero inputs/outputs on code section zero
|
// TODO: assert zero inputs/outputs on code section zero
|
||||||
// TODO: assert one code section being present and *only* one being present unless EOF
|
// TODO: assert one code section being present and *only* one being present unless EOF
|
||||||
|
|
||||||
|
unsigned bytesRequiredForDataUpperBound = static_cast<unsigned>(m_auxiliaryData.size());
|
||||||
|
for (auto const& sub: m_subs)
|
||||||
|
bytesRequiredForDataUpperBound += static_cast<unsigned>(sub->assemble().bytecode.size());
|
||||||
|
// Some of these may be unreferenced and not actually end up in data.
|
||||||
|
for (auto const& dataItem: m_data)
|
||||||
|
bytesRequiredForDataUpperBound += static_cast<unsigned>(dataItem.second.size());
|
||||||
|
|
||||||
// Insert EOF1 header.
|
// Insert EOF1 header.
|
||||||
vector<size_t> codeSectionSizeOffsets;
|
vector<size_t> codeSectionSizeOffsets;
|
||||||
auto setCodeSectionSize = [&](size_t _section, size_t _size) {
|
auto setCodeSectionSize = [&](size_t _section, size_t _size) {
|
||||||
bytesRef length(ret.bytecode.data() + codeSectionSizeOffsets.at(_section), 2);
|
bytesRef length(ret.bytecode.data() + codeSectionSizeOffsets.at(_section), 2);
|
||||||
toBigEndian(_size, length);
|
toBigEndian(_size, length);
|
||||||
};
|
};
|
||||||
size_t dataSectionSizeOffset = 0;
|
std::optional<size_t> dataSectionSizeOffset;
|
||||||
auto setDataSectionSize = [&](size_t _size) {
|
auto setDataSectionSize = [&](size_t _size) {
|
||||||
bytesRef length(ret.bytecode.data() + dataSectionSizeOffset, 2);
|
assertThrow(dataSectionSizeOffset.has_value(), AssemblyException, "");
|
||||||
|
bytesRef length(ret.bytecode.data() + *dataSectionSizeOffset, 2);
|
||||||
toBigEndian(_size, length);
|
toBigEndian(_size, length);
|
||||||
};
|
};
|
||||||
if (needsEOFContainer)
|
if (needsEOFContainer)
|
||||||
@ -575,10 +583,13 @@ LinkerObject const& Assembly::assemble() const
|
|||||||
ret.bytecode.push_back(0x00); // placeholder for length of code
|
ret.bytecode.push_back(0x00); // placeholder for length of code
|
||||||
ret.bytecode.push_back(0x00);
|
ret.bytecode.push_back(0x00);
|
||||||
}
|
}
|
||||||
ret.bytecode.push_back(0x02); // kind=data
|
if (bytesRequiredForDataUpperBound > 0)
|
||||||
dataSectionSizeOffset = ret.bytecode.size();
|
{
|
||||||
ret.bytecode.push_back(0x00); // length of data
|
ret.bytecode.push_back(0x02); // kind=data
|
||||||
ret.bytecode.push_back(0x00);
|
dataSectionSizeOffset = ret.bytecode.size();
|
||||||
|
ret.bytecode.push_back(0x00); // length of data
|
||||||
|
ret.bytecode.push_back(0x00);
|
||||||
|
}
|
||||||
ret.bytecode.push_back(0x00); // terminator
|
ret.bytecode.push_back(0x00); // terminator
|
||||||
|
|
||||||
if (needsTypeSection)
|
if (needsTypeSection)
|
||||||
@ -597,21 +608,16 @@ LinkerObject const& Assembly::assemble() const
|
|||||||
multimap<h256, unsigned> dataRef;
|
multimap<h256, unsigned> dataRef;
|
||||||
multimap<size_t, size_t> subRef;
|
multimap<size_t, size_t> subRef;
|
||||||
vector<unsigned> sizeRef; ///< Pointers to code locations where the size of the program is inserted
|
vector<unsigned> sizeRef; ///< Pointers to code locations where the size of the program is inserted
|
||||||
unsigned bytesPerTag = numberEncodingSize(bytesRequiredForCode);
|
unsigned bytesPerTag = numberEncodingSize(headerSize + bytesRequiredForCode);
|
||||||
uint8_t tagPush = static_cast<uint8_t>(pushInstruction(bytesPerTag));
|
uint8_t tagPush = static_cast<uint8_t>(pushInstruction(bytesPerTag));
|
||||||
|
|
||||||
if (!needsEOFContainer)
|
if (!needsEOFContainer)
|
||||||
++bytesRequiredForCode; ///< Additional INVALID marker.
|
++bytesRequiredForCode; ///< Additional INVALID marker.
|
||||||
|
|
||||||
// TODO: all of this is a bit off
|
unsigned bytesRequiredIncludingDataUpperBound = headerSize + bytesRequiredForCode + bytesRequiredForDataUpperBound;
|
||||||
unsigned bytesRequiredForData = static_cast<unsigned>(m_auxiliaryData.size());
|
unsigned bytesPerDataRef = numberEncodingSize(bytesRequiredIncludingDataUpperBound);
|
||||||
for (auto const& sub: m_subs)
|
|
||||||
bytesRequiredForData += static_cast<unsigned>(sub->assemble().bytecode.size());
|
|
||||||
|
|
||||||
unsigned bytesRequiredIncludingData = headerSize + bytesRequiredForCode + bytesRequiredForData;
|
|
||||||
unsigned bytesPerDataRef = numberEncodingSize(bytesRequiredIncludingData);
|
|
||||||
uint8_t dataRefPush = static_cast<uint8_t>(pushInstruction(bytesPerDataRef));
|
uint8_t dataRefPush = static_cast<uint8_t>(pushInstruction(bytesPerDataRef));
|
||||||
ret.bytecode.reserve(bytesRequiredIncludingData);
|
ret.bytecode.reserve(bytesRequiredIncludingDataUpperBound);
|
||||||
|
|
||||||
auto const codeStart = ret.bytecode.size();
|
auto const codeStart = ret.bytecode.size();
|
||||||
|
|
||||||
@ -839,14 +845,18 @@ LinkerObject const& Assembly::assemble() const
|
|||||||
auto dataLength = ret.bytecode.size() - dataStart;
|
auto dataLength = ret.bytecode.size() - dataStart;
|
||||||
if (needsEOFContainer)
|
if (needsEOFContainer)
|
||||||
{
|
{
|
||||||
// Note: Temporary solution to current evmone requirement of non-empty data section.
|
assertThrow(bytesRequiredForDataUpperBound >= dataLength, AssemblyException, "Unexpected data size.");
|
||||||
if (dataLength == 0)
|
if (bytesRequiredForDataUpperBound > 0)
|
||||||
{
|
{
|
||||||
ret.bytecode.push_back(0);
|
if (dataLength == 0)
|
||||||
dataLength++;
|
{
|
||||||
|
// We have commited to a data section, but not actually needed it, so create a fake one.
|
||||||
|
++dataLength;
|
||||||
|
ret.bytecode.push_back(0);
|
||||||
|
}
|
||||||
|
setDataSectionSize(dataLength);
|
||||||
|
assertThrow(dataLength <= 0xffff, AssemblyException, "Invalid data section size.");
|
||||||
}
|
}
|
||||||
assertThrow(dataLength > 0u && dataLength <= 0xffff, AssemblyException, "Invalid data section size.");
|
|
||||||
setDataSectionSize(dataLength);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -79,7 +79,7 @@ public:
|
|||||||
uint16_t createFunction(uint8_t _args, uint8_t _rets)
|
uint16_t createFunction(uint8_t _args, uint8_t _rets)
|
||||||
{
|
{
|
||||||
size_t functionID = m_codeSections.size();
|
size_t functionID = m_codeSections.size();
|
||||||
assertThrow(functionID <= 0xFFFF, AssemblyException, "Too many functions.");
|
assertThrow(functionID < 1024, AssemblyException, "Too many functions.");
|
||||||
assertThrow(m_currentCodeSection == 0, AssemblyException, "Functions need to be declared from the main block.");
|
assertThrow(m_currentCodeSection == 0, AssemblyException, "Functions need to be declared from the main block.");
|
||||||
m_codeSections.emplace_back(CodeSection{_args, _rets, {}});
|
m_codeSections.emplace_back(CodeSection{_args, _rets, {}});
|
||||||
return static_cast<uint16_t>(functionID);
|
return static_cast<uint16_t>(functionID);
|
||||||
|
Loading…
Reference in New Issue
Block a user