mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Properly compute source mappings for immutables.
This commit is contained in:
committed by
Mathias Baumann
parent
49d7b78466
commit
b1dd0d0d02
@@ -65,7 +65,7 @@ void AssemblyItem::setPushTagSubIdAndTag(size_t _subId, size_t _tag)
|
||||
setData(data);
|
||||
}
|
||||
|
||||
size_t AssemblyItem::bytesRequired(size_t _addressLength) const
|
||||
size_t AssemblyItem::bytesRequired(size_t _addressLength, Precision _precision) const
|
||||
{
|
||||
switch (m_type)
|
||||
{
|
||||
@@ -87,10 +87,25 @@ size_t AssemblyItem::bytesRequired(size_t _addressLength) const
|
||||
case PushImmutable:
|
||||
return 1 + 32;
|
||||
case AssignImmutable:
|
||||
if (m_immutableOccurrences)
|
||||
return 1 + (3 + 32) * *m_immutableOccurrences;
|
||||
{
|
||||
unsigned long immutableOccurrences = 0;
|
||||
|
||||
// Skip exact immutables count if no precise count was requested
|
||||
if (_precision == Precision::Approximate)
|
||||
immutableOccurrences = 1; // Assume one immut. ref.
|
||||
else
|
||||
return 1 + (3 + 32) * 1024; // 1024 occurrences are beyond the maximum code size anyways.
|
||||
{
|
||||
solAssert(m_immutableOccurrences, "No immutable references. `bytesRequired()` called before assembly()?");
|
||||
immutableOccurrences = m_immutableOccurrences.value();
|
||||
}
|
||||
|
||||
if (immutableOccurrences != 0)
|
||||
// (DUP DUP PUSH <n> ADD MSTORE)* (PUSH <n> ADD MSTORE)
|
||||
return (immutableOccurrences - 1) * (5 + 32) + (3 + 32);
|
||||
else
|
||||
// POP POP
|
||||
return 2;
|
||||
}
|
||||
case VerbatimBytecode:
|
||||
return std::get<2>(*m_verbatimBytecode).size();
|
||||
default:
|
||||
@@ -322,6 +337,26 @@ ostream& solidity::evmasm::operator<<(ostream& _out, AssemblyItem const& _item)
|
||||
return _out;
|
||||
}
|
||||
|
||||
size_t AssemblyItem::opcodeCount() const noexcept
|
||||
{
|
||||
switch (m_type)
|
||||
{
|
||||
case AssemblyItemType::AssignImmutable:
|
||||
// Append empty items if this AssignImmutable was referenced more than once.
|
||||
// For n immutable occurrences the first (n - 1) occurrences will
|
||||
// generate 5 opcodes and the last will generate 3 opcodes,
|
||||
// because it is reusing the 2 top-most elements on the stack.
|
||||
solAssert(m_immutableOccurrences, "");
|
||||
|
||||
if (m_immutableOccurrences.value() != 0)
|
||||
return (*m_immutableOccurrences - 1) * 5 + 3;
|
||||
else
|
||||
return 2; // two POP's
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
std::string AssemblyItem::computeSourceMapping(
|
||||
AssemblyItems const& _items,
|
||||
map<string, unsigned> const& _sourceIndicesMap
|
||||
@@ -334,6 +369,7 @@ std::string AssemblyItem::computeSourceMapping(
|
||||
int prevSourceIndex = -1;
|
||||
int prevModifierDepth = -1;
|
||||
char prevJump = 0;
|
||||
|
||||
for (auto const& item: _items)
|
||||
{
|
||||
if (!ret.empty())
|
||||
@@ -402,6 +438,9 @@ std::string AssemblyItem::computeSourceMapping(
|
||||
}
|
||||
}
|
||||
|
||||
if (item.opcodeCount() > 1)
|
||||
ret += string(item.opcodeCount() - 1, ';');
|
||||
|
||||
prevStart = location.start;
|
||||
prevLength = length;
|
||||
prevSourceIndex = sourceIndex;
|
||||
|
||||
Reference in New Issue
Block a user