Refactoring yul source locations.

This commit is contained in:
Djordje Mijovic
2021-05-04 16:05:23 +02:00
parent fe4822a1d2
commit e404b6e7a6
62 changed files with 394 additions and 358 deletions
+36 -26
View File
@@ -44,6 +44,16 @@ using namespace solidity;
using namespace solidity::yul;
using namespace solidity::util;
namespace
{
langutil::SourceLocation extractSourceLocationFromDebugData(shared_ptr<DebugData const> const& _debugData)
{
return _debugData ? _debugData->location : langutil::SourceLocation{};
}
}
CodeTransform::CodeTransform(
AbstractAssembly& _assembly,
AsmAnalysisInfo& _analysisInfo,
@@ -145,13 +155,13 @@ void CodeTransform::operator()(VariableDeclaration const& _varDecl)
}
else
{
m_assembly.setSourceLocation(_varDecl.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_varDecl.debugData));
size_t variablesLeft = numVariables;
while (variablesLeft--)
m_assembly.appendConstant(u256(0));
}
m_assembly.setSourceLocation(_varDecl.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_varDecl.debugData));
bool atTopOfStack = true;
for (size_t varIndex = 0; varIndex < numVariables; ++varIndex)
{
@@ -205,13 +215,13 @@ void CodeTransform::operator()(Assignment const& _assignment)
std::visit(*this, *_assignment.value);
expectDeposit(static_cast<int>(_assignment.variableNames.size()), height);
m_assembly.setSourceLocation(_assignment.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_assignment.debugData));
generateMultiAssignment(_assignment.variableNames);
}
void CodeTransform::operator()(ExpressionStatement const& _statement)
{
m_assembly.setSourceLocation(_statement.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_statement.debugData));
std::visit(*this, _statement.expression);
}
@@ -225,7 +235,7 @@ void CodeTransform::operator()(FunctionCall const& _call)
});
else
{
m_assembly.setSourceLocation(_call.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_call.debugData));
EVMAssembly::LabelID returnLabel(numeric_limits<EVMAssembly::LabelID>::max()); // only used for evm 1.0
returnLabel = m_assembly.newLabelId();
@@ -240,7 +250,7 @@ void CodeTransform::operator()(FunctionCall const& _call)
yulAssert(function->arguments.size() == _call.arguments.size(), "");
for (auto const& arg: _call.arguments | ranges::views::reverse)
visitExpression(arg);
m_assembly.setSourceLocation(_call.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_call.debugData));
m_assembly.appendJumpTo(
functionEntryID(_call.functionName.name, *function),
static_cast<int>(function->returns.size() - function->arguments.size()) - 1,
@@ -252,7 +262,7 @@ void CodeTransform::operator()(FunctionCall const& _call)
void CodeTransform::operator()(Identifier const& _identifier)
{
m_assembly.setSourceLocation(_identifier.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_identifier.debugData));
// First search internals, then externals.
yulAssert(m_scope, "");
if (m_scope->lookup(_identifier.name, GenericVisitor{
@@ -284,19 +294,19 @@ void CodeTransform::operator()(Identifier const& _identifier)
void CodeTransform::operator()(Literal const& _literal)
{
m_assembly.setSourceLocation(_literal.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_literal.debugData));
m_assembly.appendConstant(valueOfLiteral(_literal));
}
void CodeTransform::operator()(If const& _if)
{
visitExpression(*_if.condition);
m_assembly.setSourceLocation(_if.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_if.debugData));
m_assembly.appendInstruction(evmasm::Instruction::ISZERO);
AbstractAssembly::LabelID end = m_assembly.newLabelId();
m_assembly.appendJumpToIf(end);
(*this)(_if.body);
m_assembly.setSourceLocation(_if.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_if.debugData));
m_assembly.appendLabel(end);
}
@@ -313,7 +323,7 @@ void CodeTransform::operator()(Switch const& _switch)
if (c.value)
{
(*this)(*c.value);
m_assembly.setSourceLocation(c.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(c.debugData));
AbstractAssembly::LabelID bodyLabel = m_assembly.newLabelId();
caseBodies[&c] = bodyLabel;
yulAssert(m_assembly.stackHeight() == expressionHeight + 1, "");
@@ -325,24 +335,24 @@ void CodeTransform::operator()(Switch const& _switch)
// default case
(*this)(c.body);
}
m_assembly.setSourceLocation(_switch.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_switch.debugData));
m_assembly.appendJumpTo(end);
size_t numCases = caseBodies.size();
for (auto const& c: caseBodies)
{
m_assembly.setSourceLocation(c.first->location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(c.first->debugData));
m_assembly.appendLabel(c.second);
(*this)(c.first->body);
// Avoid useless "jump to next" for the last case.
if (--numCases > 0)
{
m_assembly.setSourceLocation(c.first->location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(c.first->debugData));
m_assembly.appendJumpTo(end);
}
}
m_assembly.setSourceLocation(_switch.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_switch.debugData));
m_assembly.appendLabel(end);
m_assembly.appendInstruction(evmasm::Instruction::POP);
}
@@ -363,7 +373,7 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
m_context->variableStackHeights[&var] = height++;
}
m_assembly.setSourceLocation(_function.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_function.debugData));
int const stackHeightBefore = m_assembly.stackHeight();
m_assembly.appendLabel(functionEntryID(_function.name, function));
@@ -488,11 +498,11 @@ void CodeTransform::operator()(ForLoop const& _forLoop)
AbstractAssembly::LabelID postPart = m_assembly.newLabelId();
AbstractAssembly::LabelID loopEnd = m_assembly.newLabelId();
m_assembly.setSourceLocation(_forLoop.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_forLoop.debugData));
m_assembly.appendLabel(loopStart);
visitExpression(*_forLoop.condition);
m_assembly.setSourceLocation(_forLoop.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_forLoop.debugData));
m_assembly.appendInstruction(evmasm::Instruction::ISZERO);
m_assembly.appendJumpToIf(loopEnd);
@@ -500,12 +510,12 @@ void CodeTransform::operator()(ForLoop const& _forLoop)
m_context->forLoopStack.emplace(Context::ForLoopLabels{ {postPart, stackHeightBody}, {loopEnd, stackHeightBody} });
(*this)(_forLoop.body);
m_assembly.setSourceLocation(_forLoop.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_forLoop.debugData));
m_assembly.appendLabel(postPart);
(*this)(_forLoop.post);
m_assembly.setSourceLocation(_forLoop.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_forLoop.debugData));
m_assembly.appendJumpTo(loopStart);
m_assembly.appendLabel(loopEnd);
@@ -525,7 +535,7 @@ int CodeTransform::appendPopUntil(int _targetDepth)
void CodeTransform::operator()(Break const& _break)
{
yulAssert(!m_context->forLoopStack.empty(), "Invalid break-statement. Requires surrounding for-loop in code generation.");
m_assembly.setSourceLocation(_break.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_break.debugData));
Context::JumpInfo const& jump = m_context->forLoopStack.top().done;
m_assembly.appendJumpTo(jump.label, appendPopUntil(jump.targetStackHeight));
@@ -534,7 +544,7 @@ void CodeTransform::operator()(Break const& _break)
void CodeTransform::operator()(Continue const& _continue)
{
yulAssert(!m_context->forLoopStack.empty(), "Invalid continue-statement. Requires surrounding for-loop in code generation.");
m_assembly.setSourceLocation(_continue.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_continue.debugData));
Context::JumpInfo const& jump = m_context->forLoopStack.top().post;
m_assembly.appendJumpTo(jump.label, appendPopUntil(jump.targetStackHeight));
@@ -544,7 +554,7 @@ void CodeTransform::operator()(Leave const& _leaveStatement)
{
yulAssert(m_functionExitLabel, "Invalid leave-statement. Requires surrounding function in code generation.");
yulAssert(m_functionExitStackHeight, "");
m_assembly.setSourceLocation(_leaveStatement.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_leaveStatement.debugData));
m_assembly.appendJumpTo(*m_functionExitLabel, appendPopUntil(*m_functionExitStackHeight));
}
@@ -605,7 +615,7 @@ void CodeTransform::setupReturnVariablesAndFunctionExit()
// Allocate slots for return variables as if they were declared as variables in the virtual function scope.
for (TypedName const& var: m_delayedReturnVariables)
(*this)(VariableDeclaration{var.location, {var}, {}});
(*this)(VariableDeclaration{var.debugData, {var}, {}});
m_functionExitStackHeight = ranges::max(m_delayedReturnVariables | ranges::views::transform([&](TypedName const& _name) {
return variableStackHeight(_name.name);
@@ -654,7 +664,7 @@ void CodeTransform::visitStatements(vector<Statement> const& _statements)
auto const* functionDefinition = std::get_if<FunctionDefinition>(&statement);
if (functionDefinition && !jumpTarget)
{
m_assembly.setSourceLocation(locationOf(statement));
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(functionDefinition->debugData));
jumpTarget = m_assembly.newLabelId();
m_assembly.appendJumpTo(*jumpTarget, 0);
}
@@ -675,7 +685,7 @@ void CodeTransform::visitStatements(vector<Statement> const& _statements)
void CodeTransform::finalizeBlock(Block const& _block, optional<int> blockStartStackHeight)
{
m_assembly.setSourceLocation(_block.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_block.debugData));
freeUnusedVariables();