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
+2
View File
@@ -23,6 +23,8 @@
#pragma once
#include <libyul/ASTForward.h>
#include <libsolutil/Common.h>
#include <libsolutil/CommonData.h>
+6 -6
View File
@@ -100,7 +100,7 @@ void ConstantOptimiser::visit(Expression& _e)
if (
Expression const* repr =
RepresentationFinder(m_dialect, m_meter, locationOf(_e), m_cache)
RepresentationFinder(m_dialect, m_meter, debugDataOf(_e), m_cache)
.tryFindRepresentation(valueOfLiteral(literal))
)
_e = ASTCopier{}.translate(*repr);
@@ -180,7 +180,7 @@ Representation const& RepresentationFinder::findRepresentation(u256 const& _valu
Representation RepresentationFinder::represent(u256 const& _value) const
{
Representation repr;
repr.expression = make_unique<Expression>(Literal{m_location, LiteralKind::Number, YulString{formatNumber(_value)}, {}});
repr.expression = make_unique<Expression>(Literal{m_debugData, LiteralKind::Number, YulString{formatNumber(_value)}, {}});
repr.cost = m_meter.costs(*repr.expression);
return repr;
}
@@ -192,8 +192,8 @@ Representation RepresentationFinder::represent(
{
Representation repr;
repr.expression = make_unique<Expression>(FunctionCall{
m_location,
Identifier{m_location, _instruction},
m_debugData,
Identifier{m_debugData, _instruction},
{ASTCopier{}.translate(*_argument.expression)}
});
repr.cost = _argument.cost + m_meter.instructionCosts(*m_dialect.builtin(_instruction)->instruction);
@@ -208,8 +208,8 @@ Representation RepresentationFinder::represent(
{
Representation repr;
repr.expression = make_unique<Expression>(FunctionCall{
m_location,
Identifier{m_location, _instruction},
m_debugData,
Identifier{m_debugData, _instruction},
{ASTCopier{}.translate(*_arg1.expression), ASTCopier{}.translate(*_arg2.expression)}
});
repr.cost = m_meter.instructionCosts(*m_dialect.builtin(_instruction)->instruction) + _arg1.cost + _arg2.cost;
+3 -3
View File
@@ -74,12 +74,12 @@ public:
RepresentationFinder(
EVMDialect const& _dialect,
GasMeter const& _meter,
langutil::SourceLocation _location,
std::shared_ptr<DebugData const> _debugData,
std::map<u256, Representation>& _cache
):
m_dialect(_dialect),
m_meter(_meter),
m_location(std::move(_location)),
m_debugData(std::move(_debugData)),
m_cache(_cache)
{}
@@ -100,7 +100,7 @@ private:
EVMDialect const& m_dialect;
GasMeter const& m_meter;
langutil::SourceLocation m_location;
std::shared_ptr<DebugData const> m_debugData;
/// Counter for the complexity of optimization, will stop when it reaches zero.
size_t m_maxSteps = 10000;
std::map<u256, Representation>& m_cache;
+1 -1
View File
@@ -39,7 +39,7 @@ size_t constexpr assemblySizeReferenceSize = 4;
}
void EVMAssembly::setSourceLocation(SourceLocation const&)
void EVMAssembly::setSourceLocation(langutil::SourceLocation const&)
{
// Ignored for now;
}
+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();
+1
View File
@@ -39,6 +39,7 @@ class ErrorReporter;
namespace solidity::yul
{
struct AsmAnalysisInfo;
class EVMAssembly;
+2 -2
View File
@@ -55,7 +55,7 @@ void visitArguments(
for (auto const& arg: _call.arguments | ranges::views::reverse)
_visitExpression(arg);
_assembly.setSourceLocation(_call.location);
_assembly.setSourceLocation(_call.debugData->location);
}
@@ -259,7 +259,7 @@ map<YulString, BuiltinFunctionForEVM> createBuiltins(langutil::EVMVersion _evmVe
_visitExpression(_call.arguments[2]);
YulString identifier = std::get<Literal>(_call.arguments[1]).value;
_visitExpression(_call.arguments[0]);
_assembly.setSourceLocation(_call.location);
_assembly.setSourceLocation(_call.debugData->location);
_assembly.appendImmutableAssignment(identifier.str());
}
));
@@ -32,10 +32,10 @@
#include <libyul/optimiser/OptimiserStep.h>
#include <libyul/optimiser/ForLoopConditionIntoBody.h>
#include <libyul/AST.h>
#include <libyul/AsmParser.h>
#include <libyul/AsmAnalysis.h>
#include <libyul/AsmAnalysisInfo.h>
#include <libyul/AST.h>
#include <libyul/Object.h>
#include <liblangutil/ErrorReporter.h>
+39 -39
View File
@@ -65,8 +65,8 @@ void WordSizeTransform::operator()(FunctionCall& _fc)
void WordSizeTransform::operator()(If& _if)
{
_if.condition = make_unique<Expression>(FunctionCall{
locationOf(*_if.condition),
Identifier{locationOf(*_if.condition), "or_bool"_yulstring},
debugDataOf(*_if.condition),
Identifier{debugDataOf(*_if.condition), "or_bool"_yulstring},
expandValueToVector(*_if.condition)
});
(*this)(_if.body);
@@ -81,8 +81,8 @@ void WordSizeTransform::operator()(ForLoop& _for)
{
(*this)(_for.pre);
_for.condition = make_unique<Expression>(FunctionCall{
locationOf(*_for.condition),
Identifier{locationOf(*_for.condition), "or_bool"_yulstring},
debugDataOf(*_for.condition),
Identifier{debugDataOf(*_for.condition), "or_bool"_yulstring},
expandValueToVector(*_for.condition)
});
(*this)(_for.post);
@@ -116,18 +116,18 @@ void WordSizeTransform::operator()(Block& _block)
vector<Statement> ret;
for (size_t i = 0; i < 3; i++)
ret.emplace_back(VariableDeclaration{
varDecl.location,
{TypedName{varDecl.location, newLhs[i], m_targetDialect.defaultType}},
varDecl.debugData,
{TypedName{varDecl.debugData, newLhs[i], m_targetDialect.defaultType}},
make_unique<Expression>(Literal{
locationOf(*varDecl.value),
debugDataOf(*varDecl.value),
LiteralKind::Number,
"0"_yulstring,
m_targetDialect.defaultType
})
});
ret.emplace_back(VariableDeclaration{
varDecl.location,
{TypedName{varDecl.location, newLhs[3], m_targetDialect.defaultType}},
varDecl.debugData,
{TypedName{varDecl.debugData, newLhs[3], m_targetDialect.defaultType}},
std::move(varDecl.value)
});
return {std::move(ret)};
@@ -147,8 +147,8 @@ void WordSizeTransform::operator()(Block& _block)
vector<Statement> ret;
for (size_t i = 0; i < 4; i++)
ret.emplace_back(VariableDeclaration{
varDecl.location,
{TypedName{varDecl.location, newLhs[i], m_targetDialect.defaultType}},
varDecl.debugData,
{TypedName{varDecl.debugData, newLhs[i], m_targetDialect.defaultType}},
std::move(newRhs[i])
}
);
@@ -177,18 +177,18 @@ void WordSizeTransform::operator()(Block& _block)
vector<Statement> ret;
for (size_t i = 0; i < 3; i++)
ret.emplace_back(Assignment{
assignment.location,
{Identifier{assignment.location, newLhs[i]}},
assignment.debugData,
{Identifier{assignment.debugData, newLhs[i]}},
make_unique<Expression>(Literal{
locationOf(*assignment.value),
debugDataOf(*assignment.value),
LiteralKind::Number,
"0"_yulstring,
m_targetDialect.defaultType
})
});
ret.emplace_back(Assignment{
assignment.location,
{Identifier{assignment.location, newLhs[3]}},
assignment.debugData,
{Identifier{assignment.debugData, newLhs[3]}},
std::move(assignment.value)
});
return {std::move(ret)};
@@ -208,8 +208,8 @@ void WordSizeTransform::operator()(Block& _block)
vector<Statement> ret;
for (size_t i = 0; i < 4; i++)
ret.emplace_back(Assignment{
assignment.location,
{Identifier{assignment.location, m_variableMapping.at(lhsName)[i]}},
assignment.debugData,
{Identifier{assignment.debugData, m_variableMapping.at(lhsName)[i]}},
std::move(newRhs[i])
}
);
@@ -258,7 +258,7 @@ void WordSizeTransform::rewriteVarDeclList(TypedNameList& _nameList)
{
TypedNameList ret;
for (auto newName: generateU64IdentifierNames(_n.name))
ret.emplace_back(TypedName{_n.location, newName, m_targetDialect.defaultType});
ret.emplace_back(TypedName{_n.debugData, newName, m_targetDialect.defaultType});
return ret;
}
);
@@ -272,14 +272,14 @@ void WordSizeTransform::rewriteIdentifierList(vector<Identifier>& _ids)
{
vector<Identifier> ret;
for (auto newId: m_variableMapping.at(_id.name))
ret.push_back(Identifier{_id.location, newId});
ret.push_back(Identifier{_id.debugData, newId});
return ret;
}
);
}
vector<Statement> WordSizeTransform::handleSwitchInternal(
langutil::SourceLocation const& _location,
shared_ptr<DebugData const> const& _debugData,
vector<YulString> const& _splitExpressions,
vector<Case> _cases,
YulString _runDefaultFlag,
@@ -304,19 +304,19 @@ vector<Statement> WordSizeTransform::handleSwitchInternal(
}
Switch ret{
_location,
make_unique<Expression>(Identifier{_location, _splitExpressions.at(_depth)}),
_debugData,
make_unique<Expression>(Identifier{_debugData, _splitExpressions.at(_depth)}),
{}
};
for (auto& c: cases)
{
Literal label{_location, LiteralKind::Number, YulString(c.first.str()), m_targetDialect.defaultType};
Literal label{_debugData, LiteralKind::Number, YulString(c.first.str()), m_targetDialect.defaultType};
ret.cases.emplace_back(Case{
c.second.front().location,
c.second.front().debugData,
make_unique<Literal>(std::move(label)),
Block{_location, handleSwitchInternal(
_location,
Block{_debugData, handleSwitchInternal(
_debugData,
_splitExpressions,
std::move(c.second),
_runDefaultFlag,
@@ -326,13 +326,13 @@ vector<Statement> WordSizeTransform::handleSwitchInternal(
}
if (!_runDefaultFlag.empty())
ret.cases.emplace_back(Case{
_location,
_debugData,
nullptr,
Block{_location, make_vector<Statement>(
Block{_debugData, make_vector<Statement>(
Assignment{
_location,
{{_location, _runDefaultFlag}},
make_unique<Expression>(Literal{_location, LiteralKind::Boolean, "true"_yulstring, m_targetDialect.boolType})
_debugData,
{{_debugData, _runDefaultFlag}},
make_unique<Expression>(Literal{_debugData, LiteralKind::Boolean, "true"_yulstring, m_targetDialect.boolType})
}
)}
});
@@ -356,8 +356,8 @@ std::vector<Statement> WordSizeTransform::handleSwitch(Switch& _switch)
defaultCase = std::move(_switch.cases.back());
_switch.cases.pop_back();
ret.emplace_back(VariableDeclaration{
_switch.location,
{TypedName{_switch.location, runDefaultFlag, m_targetDialect.boolType}},
_switch.debugData,
{TypedName{_switch.debugData, runDefaultFlag, m_targetDialect.boolType}},
{}
});
}
@@ -366,7 +366,7 @@ std::vector<Statement> WordSizeTransform::handleSwitch(Switch& _switch)
splitExpressions.emplace_back(std::get<Identifier>(*expr).name);
ret += handleSwitchInternal(
_switch.location,
_switch.debugData,
splitExpressions,
std::move(_switch.cases),
runDefaultFlag,
@@ -374,8 +374,8 @@ std::vector<Statement> WordSizeTransform::handleSwitch(Switch& _switch)
);
if (!runDefaultFlag.empty())
ret.emplace_back(If{
_switch.location,
make_unique<Expression>(Identifier{_switch.location, runDefaultFlag}),
_switch.debugData,
make_unique<Expression>(Identifier{_switch.debugData, runDefaultFlag}),
std::move(defaultCase.body)
});
return ret;
@@ -397,7 +397,7 @@ array<unique_ptr<Expression>, 4> WordSizeTransform::expandValue(Expression const
{
auto const& id = std::get<Identifier>(_e);
for (size_t i = 0; i < 4; i++)
ret[i] = make_unique<Expression>(Identifier{id.location, m_variableMapping.at(id.name)[i]});
ret[i] = make_unique<Expression>(Identifier{id.debugData, m_variableMapping.at(id.name)[i]});
}
else if (holds_alternative<Literal>(_e))
{
@@ -410,7 +410,7 @@ array<unique_ptr<Expression>, 4> WordSizeTransform::expandValue(Expression const
val >>= 64;
ret[exprIndexReverse] = make_unique<Expression>(
Literal{
lit.location,
lit.debugData,
LiteralKind::Number,
YulString(currentVal.str()),
m_targetDialect.defaultType
+1 -1
View File
@@ -87,7 +87,7 @@ private:
std::vector<Statement> handleSwitch(Switch& _switch);
std::vector<Statement> handleSwitchInternal(
langutil::SourceLocation const& _location,
std::shared_ptr<DebugData const> const& _debugData,
std::vector<YulString> const& _splitExpressions,
std::vector<Case> _cases,
YulString _runDefaultFlag,