mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Refactoring yul source locations.
This commit is contained in:
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user