Purge using namespace std from libyul/backends

Signed-off-by: Jun Zhang <jun@junz.org>
This commit is contained in:
Jun Zhang 2023-08-23 10:24:09 +08:00
parent 37e18612c5
commit 1ebdab43d8
12 changed files with 152 additions and 161 deletions

View File

@ -28,7 +28,6 @@
#include <libsolutil/StackTooDeepString.h> #include <libsolutil/StackTooDeepString.h>
using namespace std;
using namespace solidity; using namespace solidity;
using namespace solidity::yul; using namespace solidity::yul;
using namespace solidity::util; using namespace solidity::util;

View File

@ -30,7 +30,6 @@
#include <variant> #include <variant>
using namespace std;
using namespace solidity; using namespace solidity;
using namespace solidity::yul; using namespace solidity::yul;
using namespace solidity::util; using namespace solidity::util;
@ -48,9 +47,9 @@ struct MiniEVMInterpreter
return std::visit(*this, _expr); return std::visit(*this, _expr);
} }
u256 eval(evmasm::Instruction _instr, vector<Expression> const& _arguments) u256 eval(evmasm::Instruction _instr, std::vector<Expression> const& _arguments)
{ {
vector<u256> args; std::vector<u256> args;
for (auto const& arg: _arguments) for (auto const& arg: _arguments)
args.emplace_back(eval(arg)); args.emplace_back(eval(arg));
switch (_instr) switch (_instr)
@ -92,7 +91,7 @@ struct MiniEVMInterpreter
void ConstantOptimiser::visit(Expression& _e) void ConstantOptimiser::visit(Expression& _e)
{ {
if (holds_alternative<Literal>(_e)) if (std::holds_alternative<Literal>(_e))
{ {
Literal const& literal = std::get<Literal>(_e); Literal const& literal = std::get<Literal>(_e);
if (literal.kind != LiteralKind::Number) if (literal.kind != LiteralKind::Number)
@ -115,7 +114,7 @@ Expression const* RepresentationFinder::tryFindRepresentation(u256 const& _value
return nullptr; return nullptr;
Representation const& repr = findRepresentation(_value); Representation const& repr = findRepresentation(_value);
if (holds_alternative<Literal>(*repr.expression)) if (std::holds_alternative<Literal>(*repr.expression))
return nullptr; return nullptr;
else else
return repr.expression.get(); return repr.expression.get();
@ -180,7 +179,7 @@ Representation const& RepresentationFinder::findRepresentation(u256 const& _valu
Representation RepresentationFinder::represent(u256 const& _value) const Representation RepresentationFinder::represent(u256 const& _value) const
{ {
Representation repr; Representation repr;
repr.expression = make_unique<Expression>(Literal{m_debugData, LiteralKind::Number, YulString{formatNumber(_value)}, {}}); repr.expression = std::make_unique<Expression>(Literal{m_debugData, LiteralKind::Number, YulString{formatNumber(_value)}, {}});
repr.cost = m_meter.costs(*repr.expression); repr.cost = m_meter.costs(*repr.expression);
return repr; return repr;
} }
@ -191,7 +190,7 @@ Representation RepresentationFinder::represent(
) const ) const
{ {
Representation repr; Representation repr;
repr.expression = make_unique<Expression>(FunctionCall{ repr.expression = std::make_unique<Expression>(FunctionCall{
m_debugData, m_debugData,
Identifier{m_debugData, _instruction}, Identifier{m_debugData, _instruction},
{ASTCopier{}.translate(*_argument.expression)} {ASTCopier{}.translate(*_argument.expression)}
@ -207,7 +206,7 @@ Representation RepresentationFinder::represent(
) const ) const
{ {
Representation repr; Representation repr;
repr.expression = make_unique<Expression>(FunctionCall{ repr.expression = std::make_unique<Expression>(FunctionCall{
m_debugData, m_debugData,
Identifier{m_debugData, _instruction}, Identifier{m_debugData, _instruction},
{ASTCopier{}.translate(*_arg1.expression), ASTCopier{}.translate(*_arg2.expression)} {ASTCopier{}.translate(*_arg1.expression), ASTCopier{}.translate(*_arg2.expression)}

View File

@ -45,7 +45,6 @@
using namespace solidity; using namespace solidity;
using namespace solidity::yul; using namespace solidity::yul;
using namespace std;
namespace namespace
{ {
@ -82,15 +81,15 @@ void cleanUnreachable(CFG& _cfg)
/// Sets the ``recursive`` member to ``true`` for all recursive function calls. /// Sets the ``recursive`` member to ``true`` for all recursive function calls.
void markRecursiveCalls(CFG& _cfg) void markRecursiveCalls(CFG& _cfg)
{ {
map<CFG::BasicBlock*, vector<CFG::FunctionCall*>> callsPerBlock; std::map<CFG::BasicBlock*, std::vector<CFG::FunctionCall*>> callsPerBlock;
auto const& findCalls = [&](CFG::BasicBlock* _block) auto const& findCalls = [&](CFG::BasicBlock* _block)
{ {
if (auto* calls = util::valueOrNullptr(callsPerBlock, _block)) if (auto* calls = util::valueOrNullptr(callsPerBlock, _block))
return *calls; return *calls;
vector<CFG::FunctionCall*>& calls = callsPerBlock[_block]; std::vector<CFG::FunctionCall*>& calls = callsPerBlock[_block];
util::BreadthFirstSearch<CFG::BasicBlock*>{{_block}}.run([&](CFG::BasicBlock* _block, auto _addChild) { util::BreadthFirstSearch<CFG::BasicBlock*>{{_block}}.run([&](CFG::BasicBlock* _block, auto _addChild) {
for (auto& operation: _block->operations) for (auto& operation: _block->operations)
if (auto* functionCall = get_if<CFG::FunctionCall>(&operation.operation)) if (auto* functionCall = std::get_if<CFG::FunctionCall>(&operation.operation))
calls.emplace_back(functionCall); calls.emplace_back(functionCall);
std::visit(util::GenericVisitor{ std::visit(util::GenericVisitor{
[&](CFG::BasicBlock::MainExit const&) {}, [&](CFG::BasicBlock::MainExit const&) {},
@ -131,7 +130,7 @@ void markRecursiveCalls(CFG& _cfg)
/// Entering such a block means that control flow will never return to a previously visited block. /// Entering such a block means that control flow will never return to a previously visited block.
void markStartsOfSubGraphs(CFG& _cfg) void markStartsOfSubGraphs(CFG& _cfg)
{ {
vector<CFG::BasicBlock*> entries; std::vector<CFG::BasicBlock*> entries;
entries.emplace_back(_cfg.entry); entries.emplace_back(_cfg.entry);
for (auto&& functionInfo: _cfg.functionInfo | ranges::views::values) for (auto&& functionInfo: _cfg.functionInfo | ranges::views::values)
entries.emplace_back(functionInfo.entry); entries.emplace_back(functionInfo.entry);
@ -141,17 +140,17 @@ void markStartsOfSubGraphs(CFG& _cfg)
* Detect bridges following Algorithm 1 in https://arxiv.org/pdf/2108.07346.pdf * Detect bridges following Algorithm 1 in https://arxiv.org/pdf/2108.07346.pdf
* and mark the bridge targets as starts of sub-graphs. * and mark the bridge targets as starts of sub-graphs.
*/ */
set<CFG::BasicBlock*> visited; std::set<CFG::BasicBlock*> visited;
map<CFG::BasicBlock*, size_t> disc; std::map<CFG::BasicBlock*, size_t> disc;
map<CFG::BasicBlock*, size_t> low; std::map<CFG::BasicBlock*, size_t> low;
map<CFG::BasicBlock*, CFG::BasicBlock*> parent; std::map<CFG::BasicBlock*, CFG::BasicBlock*> parent;
size_t time = 0; size_t time = 0;
auto dfs = [&](CFG::BasicBlock* _u, auto _recurse) -> void { auto dfs = [&](CFG::BasicBlock* _u, auto _recurse) -> void {
visited.insert(_u); visited.insert(_u);
disc[_u] = low[_u] = time; disc[_u] = low[_u] = time;
time++; time++;
vector<CFG::BasicBlock*> children = _u->entries; std::vector<CFG::BasicBlock*> children = _u->entries;
visit(util::GenericVisitor{ visit(util::GenericVisitor{
[&](CFG::BasicBlock::Jump const& _jump) { [&](CFG::BasicBlock::Jump const& _jump) {
children.emplace_back(_jump.target); children.emplace_back(_jump.target);
@ -171,7 +170,7 @@ void markStartsOfSubGraphs(CFG& _cfg)
{ {
parent[v] = _u; parent[v] = _u;
_recurse(v, _recurse); _recurse(v, _recurse);
low[_u] = min(low[_u], low[v]); low[_u] = std::min(low[_u], low[v]);
if (low[v] > disc[_u]) if (low[v] > disc[_u])
{ {
// _u <-> v is a cut edge in the undirected graph // _u <-> v is a cut edge in the undirected graph
@ -186,7 +185,7 @@ void markStartsOfSubGraphs(CFG& _cfg)
} }
} }
else if (v != parent[_u]) else if (v != parent[_u])
low[_u] = min(low[_u], disc[v]); low[_u] = std::min(low[_u], disc[v]);
}; };
dfs(entry, dfs); dfs(entry, dfs);
} }
@ -234,7 +233,7 @@ std::unique_ptr<CFG> ControlFlowGraphBuilder::build(
ControlFlowGraphBuilder::ControlFlowGraphBuilder( ControlFlowGraphBuilder::ControlFlowGraphBuilder(
CFG& _graph, CFG& _graph,
AsmAnalysisInfo const& _analysisInfo, AsmAnalysisInfo const& _analysisInfo,
map<FunctionDefinition const*, ControlFlowSideEffects> const& _functionSideEffects, std::map<FunctionDefinition const*, ControlFlowSideEffects> const& _functionSideEffects,
Dialect const& _dialect Dialect const& _dialect
): ):
m_graph(_graph), m_graph(_graph),
@ -271,7 +270,7 @@ void ControlFlowGraphBuilder::operator()(VariableDeclaration const& _varDecl)
yulAssert(m_currentBlock, ""); yulAssert(m_currentBlock, "");
auto declaredVariables = _varDecl.variables | ranges::views::transform([&](TypedName const& _var) { auto declaredVariables = _varDecl.variables | ranges::views::transform([&](TypedName const& _var) {
return VariableSlot{lookupVariable(_var.name), _var.debugData}; return VariableSlot{lookupVariable(_var.name), _var.debugData};
}) | ranges::to<vector<VariableSlot>>; }) | ranges::to<std::vector<VariableSlot>>;
Stack input; Stack input;
if (_varDecl.value) if (_varDecl.value)
input = visitAssignmentRightHandSide(*_varDecl.value, declaredVariables.size()); input = visitAssignmentRightHandSide(*_varDecl.value, declaredVariables.size());
@ -287,7 +286,7 @@ void ControlFlowGraphBuilder::operator()(Assignment const& _assignment)
{ {
auto assignedVariables = _assignment.variableNames | ranges::views::transform([&](Identifier const& _var) { auto assignedVariables = _assignment.variableNames | ranges::views::transform([&](Identifier const& _var) {
return VariableSlot{lookupVariable(_var.name), _var.debugData}; return VariableSlot{lookupVariable(_var.name), _var.debugData};
}) | ranges::to<vector<VariableSlot>>; }) | ranges::to<std::vector<VariableSlot>>;
Stack input = visitAssignmentRightHandSide(*_assignment.value, assignedVariables.size()); Stack input = visitAssignmentRightHandSide(*_assignment.value, assignedVariables.size());
yulAssert(m_currentBlock); yulAssert(m_currentBlock);
@ -314,7 +313,7 @@ void ControlFlowGraphBuilder::operator()(Block const& _block)
{ {
ScopedSaveAndRestore saveScope(m_scope, m_info.scopes.at(&_block).get()); ScopedSaveAndRestore saveScope(m_scope, m_info.scopes.at(&_block).get());
for (auto const& statement: _block.statements) for (auto const& statement: _block.statements)
if (auto const* function = get_if<FunctionDefinition>(&statement)) if (auto const* function = std::get_if<FunctionDefinition>(&statement))
registerFunction(*function); registerFunction(*function);
for (auto const& statement: _block.statements) for (auto const& statement: _block.statements)
std::visit(*this, statement); std::visit(*this, statement);
@ -334,10 +333,10 @@ void ControlFlowGraphBuilder::operator()(If const& _if)
void ControlFlowGraphBuilder::operator()(Switch const& _switch) void ControlFlowGraphBuilder::operator()(Switch const& _switch)
{ {
yulAssert(m_currentBlock, ""); yulAssert(m_currentBlock, "");
shared_ptr<DebugData const> preSwitchDebugData = debugDataOf(_switch); std::shared_ptr<DebugData const> preSwitchDebugData = debugDataOf(_switch);
auto ghostVariableId = m_graph.ghostVariables.size(); auto ghostVariableId = m_graph.ghostVariables.size();
YulString ghostVariableName("GHOST[" + to_string(ghostVariableId) + "]"); YulString ghostVariableName("GHOST[" + std::to_string(ghostVariableId) + "]");
auto& ghostVar = m_graph.ghostVariables.emplace_back(Scope::Variable{""_yulstring, ghostVariableName}); auto& ghostVar = m_graph.ghostVariables.emplace_back(Scope::Variable{""_yulstring, ghostVariableName});
// Artificially generate: // Artificially generate:
@ -394,12 +393,12 @@ void ControlFlowGraphBuilder::operator()(Switch const& _switch)
void ControlFlowGraphBuilder::operator()(ForLoop const& _loop) void ControlFlowGraphBuilder::operator()(ForLoop const& _loop)
{ {
shared_ptr<DebugData const> preLoopDebugData = debugDataOf(_loop); std::shared_ptr<DebugData const> preLoopDebugData = debugDataOf(_loop);
ScopedSaveAndRestore scopeRestore(m_scope, m_info.scopes.at(&_loop.pre).get()); ScopedSaveAndRestore scopeRestore(m_scope, m_info.scopes.at(&_loop.pre).get());
(*this)(_loop.pre); (*this)(_loop.pre);
std::optional<bool> constantCondition; std::optional<bool> constantCondition;
if (auto const* literalCondition = get_if<yul::Literal>(_loop.condition.get())) if (auto const* literalCondition = std::get_if<yul::Literal>(_loop.condition.get()))
constantCondition = valueOfLiteral(*literalCondition) != 0; constantCondition = valueOfLiteral(*literalCondition) != 0;
CFG::BasicBlock& loopCondition = m_graph.makeBlock(debugDataOf(*_loop.condition)); CFG::BasicBlock& loopCondition = m_graph.makeBlock(debugDataOf(*_loop.condition));
@ -497,13 +496,13 @@ void ControlFlowGraphBuilder::registerFunction(FunctionDefinition const& _functi
std::get<Scope::Variable>(virtualFunctionScope->identifiers.at(_param.name)), std::get<Scope::Variable>(virtualFunctionScope->identifiers.at(_param.name)),
_param.debugData _param.debugData
}; };
}) | ranges::to<vector>, }) | ranges::to<std::vector>,
_functionDefinition.returnVariables | ranges::views::transform([&](auto const& _retVar) { _functionDefinition.returnVariables | ranges::views::transform([&](auto const& _retVar) {
return VariableSlot{ return VariableSlot{
std::get<Scope::Variable>(virtualFunctionScope->identifiers.at(_retVar.name)), std::get<Scope::Variable>(virtualFunctionScope->identifiers.at(_retVar.name)),
_retVar.debugData _retVar.debugData
}; };
}) | ranges::to<vector>, }) | ranges::to<std::vector>,
{}, {},
m_functionSideEffects.at(&_functionDefinition).canContinue m_functionSideEffects.at(&_functionDefinition).canContinue
})).second; })).second;
@ -609,7 +608,7 @@ Scope::Variable const& ControlFlowGraphBuilder::lookupVariable(YulString _name)
} }
void ControlFlowGraphBuilder::makeConditionalJump( void ControlFlowGraphBuilder::makeConditionalJump(
shared_ptr<DebugData const> _debugData, std::shared_ptr<DebugData const> _debugData,
StackSlot _condition, StackSlot _condition,
CFG::BasicBlock& _nonZero, CFG::BasicBlock& _nonZero,
CFG::BasicBlock& _zero CFG::BasicBlock& _zero
@ -628,7 +627,7 @@ void ControlFlowGraphBuilder::makeConditionalJump(
} }
void ControlFlowGraphBuilder::jump( void ControlFlowGraphBuilder::jump(
shared_ptr<DebugData const> _debugData, std::shared_ptr<DebugData const> _debugData,
CFG::BasicBlock& _target, CFG::BasicBlock& _target,
bool backwards bool backwards
) )

View File

@ -42,7 +42,6 @@
#include <utility> #include <utility>
#include <variant> #include <variant>
using namespace std;
using namespace solidity; using namespace solidity;
using namespace solidity::yul; using namespace solidity::yul;
using namespace solidity::util; using namespace solidity::util;
@ -56,9 +55,9 @@ CodeTransform::CodeTransform(
BuiltinContext& _builtinContext, BuiltinContext& _builtinContext,
ExternalIdentifierAccess::CodeGenerator _identifierAccessCodeGen, ExternalIdentifierAccess::CodeGenerator _identifierAccessCodeGen,
UseNamedLabels _useNamedLabelsForFunctions, UseNamedLabels _useNamedLabelsForFunctions,
shared_ptr<Context> _context, std::shared_ptr<Context> _context,
vector<TypedName> _delayedReturnVariables, std::vector<TypedName> _delayedReturnVariables,
optional<AbstractAssembly::LabelID> _functionExitLabel std::optional<AbstractAssembly::LabelID> _functionExitLabel
): ):
m_assembly(_assembly), m_assembly(_assembly),
m_info(_analysisInfo), m_info(_analysisInfo),
@ -74,7 +73,7 @@ CodeTransform::CodeTransform(
if (!m_context) if (!m_context)
{ {
// initialize // initialize
m_context = make_shared<Context>(); m_context = std::make_shared<Context>();
if (m_allowStackOpt) if (m_allowStackOpt)
m_context->variableReferences = VariableReferenceCounter::run(m_info, _block); m_context->variableReferences = VariableReferenceCounter::run(m_info, _block);
} }
@ -103,7 +102,7 @@ void CodeTransform::freeUnusedVariables(bool _popUnusedSlotsAtStackTop)
return; return;
for (auto const& identifier: m_scope->identifiers) for (auto const& identifier: m_scope->identifiers)
if (Scope::Variable const* var = get_if<Scope::Variable>(&identifier.second)) if (Scope::Variable const* var = std::get_if<Scope::Variable>(&identifier.second))
if (m_variablesScheduledForDeletion.count(var)) if (m_variablesScheduledForDeletion.count(var))
deleteVariable(*var); deleteVariable(*var);
// Directly in a function body block, we can also delete the function arguments, // Directly in a function body block, we can also delete the function arguments,
@ -112,7 +111,7 @@ void CodeTransform::freeUnusedVariables(bool _popUnusedSlotsAtStackTop)
// effect, so we only do it before that. // effect, so we only do it before that.
if (!returnVariablesAndFunctionExitAreSetup() && !m_scope->functionScope && m_scope->superScope && m_scope->superScope->functionScope) if (!returnVariablesAndFunctionExitAreSetup() && !m_scope->functionScope && m_scope->superScope && m_scope->superScope->functionScope)
for (auto const& identifier: m_scope->superScope->identifiers) for (auto const& identifier: m_scope->superScope->identifiers)
if (Scope::Variable const* var = get_if<Scope::Variable>(&identifier.second)) if (Scope::Variable const* var = std::get_if<Scope::Variable>(&identifier.second))
if (m_variablesScheduledForDeletion.count(var)) if (m_variablesScheduledForDeletion.count(var))
deleteVariable(*var); deleteVariable(*var);
@ -317,7 +316,7 @@ void CodeTransform::operator()(Switch const& _switch)
{ {
visitExpression(*_switch.expression); visitExpression(*_switch.expression);
int expressionHeight = m_assembly.stackHeight(); int expressionHeight = m_assembly.stackHeight();
map<Case const*, AbstractAssembly::LabelID> caseBodies; std::map<Case const*, AbstractAssembly::LabelID> caseBodies;
AbstractAssembly::LabelID end = m_assembly.newLabelId(); AbstractAssembly::LabelID end = m_assembly.newLabelId();
for (Case const& c: _switch.cases) for (Case const& c: _switch.cases)
{ {
@ -447,7 +446,7 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
// This vector holds the desired target positions of all stack slots and is // This vector holds the desired target positions of all stack slots and is
// modified parallel to the actual stack. // modified parallel to the actual stack.
vector<int> stackLayout(static_cast<size_t>(m_assembly.stackHeight()), -1); std::vector<int> stackLayout(static_cast<size_t>(m_assembly.stackHeight()), -1);
stackLayout[0] = static_cast<int>(_function.returnVariables.size()); // Move return label to the top stackLayout[0] = static_cast<int>(_function.returnVariables.size()); // Move return label to the top
for (auto&& [n, returnVariable]: ranges::views::enumerate(_function.returnVariables)) for (auto&& [n, returnVariable]: ranges::views::enumerate(_function.returnVariables))
stackLayout.at(m_context->variableStackHeights.at( stackLayout.at(m_context->variableStackHeights.at(
@ -463,7 +462,7 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
"The function " + "The function " +
_function.name.str() + _function.name.str() +
" has " + " has " +
to_string(stackLayout.size() - 17) + std::to_string(stackLayout.size() - 17) +
" parameters or return variables too many to fit the stack size." " parameters or return variables too many to fit the stack size."
); );
stackError(std::move(error), m_assembly.stackHeight() - static_cast<int>(_function.parameters.size())); stackError(std::move(error), m_assembly.stackHeight() - static_cast<int>(_function.parameters.size()));
@ -479,7 +478,7 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
else else
{ {
m_assembly.appendInstruction(evmasm::swapInstruction(static_cast<unsigned>(stackLayout.size()) - static_cast<unsigned>(stackLayout.back()) - 1u)); m_assembly.appendInstruction(evmasm::swapInstruction(static_cast<unsigned>(stackLayout.size()) - static_cast<unsigned>(stackLayout.back()) - 1u));
swap(stackLayout[static_cast<size_t>(stackLayout.back())], stackLayout.back()); std::swap(stackLayout[static_cast<size_t>(stackLayout.back())], stackLayout.back());
} }
for (size_t i = 0; i < stackLayout.size(); ++i) for (size_t i = 0; i < stackLayout.size(); ++i)
yulAssert(i == static_cast<size_t>(stackLayout[i]), "Error reshuffling stack."); yulAssert(i == static_cast<size_t>(stackLayout[i]), "Error reshuffling stack.");
@ -571,7 +570,7 @@ void CodeTransform::operator()(Block const& _block)
m_scope = m_info.scopes.at(&_block).get(); m_scope = m_info.scopes.at(&_block).get();
for (auto const& statement: _block.statements) for (auto const& statement: _block.statements)
if (auto function = get_if<FunctionDefinition>(&statement)) if (auto function = std::get_if<FunctionDefinition>(&statement))
createFunctionEntryID(*function); createFunctionEntryID(*function);
int blockStartStackHeight = m_assembly.stackHeight(); int blockStartStackHeight = m_assembly.stackHeight();
@ -579,7 +578,7 @@ void CodeTransform::operator()(Block const& _block)
bool isOutermostFunctionBodyBlock = m_scope && m_scope->superScope && m_scope->superScope->functionScope; bool isOutermostFunctionBodyBlock = m_scope && m_scope->superScope && m_scope->superScope->functionScope;
bool performValidation = !m_allowStackOpt || !isOutermostFunctionBodyBlock; bool performValidation = !m_allowStackOpt || !isOutermostFunctionBodyBlock;
finalizeBlock(_block, performValidation ? make_optional(blockStartStackHeight) : nullopt); finalizeBlock(_block, performValidation ? std::make_optional(blockStartStackHeight) : std::nullopt);
m_scope = originalScope; m_scope = originalScope;
} }
@ -588,7 +587,7 @@ void CodeTransform::createFunctionEntryID(FunctionDefinition const& _function)
Scope::Function& scopeFunction = std::get<Scope::Function>(m_scope->identifiers.at(_function.name)); Scope::Function& scopeFunction = std::get<Scope::Function>(m_scope->identifiers.at(_function.name));
yulAssert(!m_context->functionEntryIDs.count(&scopeFunction), ""); yulAssert(!m_context->functionEntryIDs.count(&scopeFunction), "");
optional<size_t> astID; std::optional<size_t> astID;
if (_function.debugData) if (_function.debugData)
astID = _function.debugData->astID; astID = _function.debugData->astID;
@ -659,16 +658,16 @@ void CodeTransform::setupReturnVariablesAndFunctionExit()
namespace namespace
{ {
bool statementNeedsReturnVariableSetup(Statement const& _statement, vector<TypedName> const& _returnVariables) bool statementNeedsReturnVariableSetup(Statement const& _statement, std::vector<TypedName> const& _returnVariables)
{ {
if (holds_alternative<FunctionDefinition>(_statement)) if (std::holds_alternative<FunctionDefinition>(_statement))
return true; return true;
if ( if (
holds_alternative<ExpressionStatement>(_statement) || std::holds_alternative<ExpressionStatement>(_statement) ||
holds_alternative<Assignment>(_statement) std::holds_alternative<Assignment>(_statement)
) )
{ {
map<YulString, size_t> references = VariableReferencesCounter::countReferences(_statement); std::map<YulString, size_t> references = VariableReferencesCounter::countReferences(_statement);
auto isReferenced = [&references](TypedName const& _returnVariable) { auto isReferenced = [&references](TypedName const& _returnVariable) {
return references.count(_returnVariable.name); return references.count(_returnVariable.name);
}; };
@ -680,7 +679,7 @@ bool statementNeedsReturnVariableSetup(Statement const& _statement, vector<Typed
} }
void CodeTransform::visitStatements(vector<Statement> const& _statements) void CodeTransform::visitStatements(std::vector<Statement> const& _statements)
{ {
std::optional<AbstractAssembly::LabelID> jumpTarget = std::nullopt; std::optional<AbstractAssembly::LabelID> jumpTarget = std::nullopt;
@ -716,7 +715,7 @@ void CodeTransform::visitStatements(vector<Statement> const& _statements)
freeUnusedVariables(); freeUnusedVariables();
} }
void CodeTransform::finalizeBlock(Block const& _block, optional<int> blockStartStackHeight) void CodeTransform::finalizeBlock(Block const& _block, std::optional<int> blockStartStackHeight)
{ {
m_assembly.setSourceLocation(originLocationOf(_block)); m_assembly.setSourceLocation(originLocationOf(_block));
@ -725,7 +724,7 @@ void CodeTransform::finalizeBlock(Block const& _block, optional<int> blockStartS
// pop variables // pop variables
yulAssert(m_info.scopes.at(&_block).get() == m_scope, ""); yulAssert(m_info.scopes.at(&_block).get() == m_scope, "");
for (auto const& id: m_scope->identifiers) for (auto const& id: m_scope->identifiers)
if (holds_alternative<Scope::Variable>(id.second)) if (std::holds_alternative<Scope::Variable>(id.second))
{ {
Scope::Variable const& var = std::get<Scope::Variable>(id.second); Scope::Variable const& var = std::get<Scope::Variable>(id.second);
if (m_allowStackOpt) if (m_allowStackOpt)
@ -740,11 +739,11 @@ void CodeTransform::finalizeBlock(Block const& _block, optional<int> blockStartS
if (blockStartStackHeight) if (blockStartStackHeight)
{ {
int deposit = m_assembly.stackHeight() - *blockStartStackHeight; int deposit = m_assembly.stackHeight() - *blockStartStackHeight;
yulAssert(deposit == 0, "Invalid stack height at end of block: " + to_string(deposit)); yulAssert(deposit == 0, "Invalid stack height at end of block: " + std::to_string(deposit));
} }
} }
void CodeTransform::generateMultiAssignment(vector<Identifier> const& _variableNames) void CodeTransform::generateMultiAssignment(std::vector<Identifier> const& _variableNames)
{ {
yulAssert(m_scope, ""); yulAssert(m_scope, "");
for (auto const& variableName: _variableNames | ranges::views::reverse) for (auto const& variableName: _variableNames | ranges::views::reverse)
@ -786,7 +785,7 @@ size_t CodeTransform::variableHeightDiff(Scope::Variable const& _var, YulString
"Variable " + "Variable " +
_varName.str() + _varName.str() +
" is " + " is " +
to_string(heightDiff - limit) + std::to_string(heightDiff - limit) +
" slot(s) too deep inside the stack. " + " slot(s) too deep inside the stack. " +
stackTooDeepString stackTooDeepString
); );
@ -798,7 +797,7 @@ size_t CodeTransform::variableHeightDiff(Scope::Variable const& _var, YulString
int CodeTransform::variableStackHeight(YulString _name) const int CodeTransform::variableStackHeight(YulString _name) const
{ {
Scope::Variable const* var = get_if<Scope::Variable>(m_scope->lookup(_name)); Scope::Variable const* var = std::get_if<Scope::Variable>(m_scope->lookup(_name));
yulAssert(var, ""); yulAssert(var, "");
return static_cast<int>(m_context->variableStackHeights.at(var)); return static_cast<int>(m_context->variableStackHeights.at(var));
} }

View File

@ -38,7 +38,7 @@
#include <regex> #include <regex>
using namespace std; using namespace std::string_literals;
using namespace solidity; using namespace solidity;
using namespace solidity::yul; using namespace solidity::yul;
using namespace solidity::util; using namespace solidity::util;
@ -46,9 +46,9 @@ using namespace solidity::util;
namespace namespace
{ {
pair<YulString, BuiltinFunctionForEVM> createEVMFunction( std::pair<YulString, BuiltinFunctionForEVM> createEVMFunction(
langutil::EVMVersion _evmVersion, langutil::EVMVersion _evmVersion,
string const& _name, std::string const& _name,
evmasm::Instruction _instruction evmasm::Instruction _instruction
) )
{ {
@ -87,12 +87,12 @@ pair<YulString, BuiltinFunctionForEVM> createEVMFunction(
return {name, std::move(f)}; return {name, std::move(f)};
} }
pair<YulString, BuiltinFunctionForEVM> createFunction( std::pair<YulString, BuiltinFunctionForEVM> createFunction(
string _name, std::string _name,
size_t _params, size_t _params,
size_t _returns, size_t _returns,
SideEffects _sideEffects, SideEffects _sideEffects,
vector<optional<LiteralKind>> _literalArguments, std::vector<std::optional<LiteralKind>> _literalArguments,
std::function<void(FunctionCall const&, AbstractAssembly&, BuiltinContext&)> _generateCode std::function<void(FunctionCall const&, AbstractAssembly&, BuiltinContext&)> _generateCode
) )
{ {
@ -111,7 +111,7 @@ pair<YulString, BuiltinFunctionForEVM> createFunction(
return {name, f}; return {name, f};
} }
set<YulString> createReservedIdentifiers(langutil::EVMVersion _evmVersion) std::set<YulString> createReservedIdentifiers(langutil::EVMVersion _evmVersion)
{ {
// TODO remove this in 0.9.0. We allow creating functions or identifiers in Yul with the name // TODO remove this in 0.9.0. We allow creating functions or identifiers in Yul with the name
// basefee for VMs before london. // basefee for VMs before london.
@ -122,20 +122,20 @@ set<YulString> createReservedIdentifiers(langutil::EVMVersion _evmVersion)
// TODO remove this in 0.9.0. We allow creating functions or identifiers in Yul with the name // TODO remove this in 0.9.0. We allow creating functions or identifiers in Yul with the name
// prevrandao for VMs before paris. // prevrandao for VMs before paris.
auto prevRandaoException = [&](string const& _instrName) -> bool auto prevRandaoException = [&](std::string const& _instrName) -> bool
{ {
// Using string comparison as the opcode is the same as for "difficulty" // Using string comparison as the opcode is the same as for "difficulty"
return _instrName == "prevrandao" && _evmVersion < langutil::EVMVersion::paris(); return _instrName == "prevrandao" && _evmVersion < langutil::EVMVersion::paris();
}; };
set<YulString> reserved; std::set<YulString> reserved;
for (auto const& instr: evmasm::c_instructions) for (auto const& instr: evmasm::c_instructions)
{ {
string name = toLower(instr.first); std::string name = toLower(instr.first);
if (!baseFeeException(instr.second) && !prevRandaoException(name)) if (!baseFeeException(instr.second) && !prevRandaoException(name))
reserved.emplace(name); reserved.emplace(name);
} }
reserved += vector<YulString>{ reserved += std::vector<YulString>{
"linkersymbol"_yulstring, "linkersymbol"_yulstring,
"datasize"_yulstring, "datasize"_yulstring,
"dataoffset"_yulstring, "dataoffset"_yulstring,
@ -146,19 +146,19 @@ set<YulString> createReservedIdentifiers(langutil::EVMVersion _evmVersion)
return reserved; return reserved;
} }
map<YulString, BuiltinFunctionForEVM> createBuiltins(langutil::EVMVersion _evmVersion, bool _objectAccess) std::map<YulString, BuiltinFunctionForEVM> createBuiltins(langutil::EVMVersion _evmVersion, bool _objectAccess)
{ {
// Exclude prevrandao as builtin for VMs before paris and difficulty for VMs after paris. // Exclude prevrandao as builtin for VMs before paris and difficulty for VMs after paris.
auto prevRandaoException = [&](string const& _instrName) -> bool auto prevRandaoException = [&](std::string const& _instrName) -> bool
{ {
return (_instrName == "prevrandao" && _evmVersion < langutil::EVMVersion::paris()) || (_instrName == "difficulty" && _evmVersion >= langutil::EVMVersion::paris()); return (_instrName == "prevrandao" && _evmVersion < langutil::EVMVersion::paris()) || (_instrName == "difficulty" && _evmVersion >= langutil::EVMVersion::paris());
}; };
map<YulString, BuiltinFunctionForEVM> builtins; std::map<YulString, BuiltinFunctionForEVM> builtins;
for (auto const& instr: evmasm::c_instructions) for (auto const& instr: evmasm::c_instructions)
{ {
string name = toLower(instr.first); std::string name = toLower(instr.first);
auto const opcode = instr.second; auto const opcode = instr.second;
if ( if (
@ -198,7 +198,7 @@ map<YulString, BuiltinFunctionForEVM> createBuiltins(langutil::EVMVersion _evmVe
BuiltinContext& BuiltinContext&
) { ) {
yulAssert(_call.arguments.size() == 1, ""); yulAssert(_call.arguments.size() == 1, "");
Literal const* literal = get_if<Literal>(&_call.arguments.front()); Literal const* literal = std::get_if<Literal>(&_call.arguments.front());
yulAssert(literal, ""); yulAssert(literal, "");
_assembly.appendConstant(valueOfLiteral(*literal)); _assembly.appendConstant(valueOfLiteral(*literal));
}) })
@ -217,10 +217,10 @@ map<YulString, BuiltinFunctionForEVM> createBuiltins(langutil::EVMVersion _evmVe
_assembly.appendAssemblySize(); _assembly.appendAssemblySize();
else else
{ {
vector<size_t> subIdPath = std::vector<size_t> subIdPath =
_context.subIDs.count(dataName) == 0 ? _context.subIDs.count(dataName) == 0 ?
_context.currentObject->pathToSubObject(dataName) : _context.currentObject->pathToSubObject(dataName) :
vector<size_t>{_context.subIDs.at(dataName)}; std::vector<size_t>{_context.subIDs.at(dataName)};
yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">."); yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">.");
_assembly.appendDataSize(subIdPath); _assembly.appendDataSize(subIdPath);
} }
@ -238,10 +238,10 @@ map<YulString, BuiltinFunctionForEVM> createBuiltins(langutil::EVMVersion _evmVe
_assembly.appendConstant(0); _assembly.appendConstant(0);
else else
{ {
vector<size_t> subIdPath = std::vector<size_t> subIdPath =
_context.subIDs.count(dataName) == 0 ? _context.subIDs.count(dataName) == 0 ?
_context.currentObject->pathToSubObject(dataName) : _context.currentObject->pathToSubObject(dataName) :
vector<size_t>{_context.subIDs.at(dataName)}; std::vector<size_t>{_context.subIDs.at(dataName)};
yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">."); yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">.");
_assembly.appendDataOffset(subIdPath); _assembly.appendDataOffset(subIdPath);
} }
@ -295,9 +295,9 @@ map<YulString, BuiltinFunctionForEVM> createBuiltins(langutil::EVMVersion _evmVe
return builtins; return builtins;
} }
regex const& verbatimPattern() std::regex const& verbatimPattern()
{ {
regex static const pattern{"verbatim_([1-9]?[0-9])i_([1-9]?[0-9])o"}; std::regex static const pattern{"verbatim_([1-9]?[0-9])i_([1-9]?[0-9])o"};
return pattern; return pattern;
} }
@ -316,7 +316,7 @@ BuiltinFunctionForEVM const* EVMDialect::builtin(YulString _name) const
{ {
if (m_objectAccess) if (m_objectAccess)
{ {
smatch match; std::smatch match;
if (regex_match(_name.str(), match, verbatimPattern())) if (regex_match(_name.str(), match, verbatimPattern()))
return verbatimFunction(stoul(match[1]), stoul(match[2])); return verbatimFunction(stoul(match[1]), stoul(match[2]));
} }
@ -337,19 +337,19 @@ bool EVMDialect::reservedIdentifier(YulString _name) const
EVMDialect const& EVMDialect::strictAssemblyForEVM(langutil::EVMVersion _version) EVMDialect const& EVMDialect::strictAssemblyForEVM(langutil::EVMVersion _version)
{ {
static map<langutil::EVMVersion, unique_ptr<EVMDialect const>> dialects; static std::map<langutil::EVMVersion, std::unique_ptr<EVMDialect const>> dialects;
static YulStringRepository::ResetCallback callback{[&] { dialects.clear(); }}; static YulStringRepository::ResetCallback callback{[&] { dialects.clear(); }};
if (!dialects[_version]) if (!dialects[_version])
dialects[_version] = make_unique<EVMDialect>(_version, false); dialects[_version] = std::make_unique<EVMDialect>(_version, false);
return *dialects[_version]; return *dialects[_version];
} }
EVMDialect const& EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion _version) EVMDialect const& EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion _version)
{ {
static map<langutil::EVMVersion, unique_ptr<EVMDialect const>> dialects; static std::map<langutil::EVMVersion, std::unique_ptr<EVMDialect const>> dialects;
static YulStringRepository::ResetCallback callback{[&] { dialects.clear(); }}; static YulStringRepository::ResetCallback callback{[&] { dialects.clear(); }};
if (!dialects[_version]) if (!dialects[_version])
dialects[_version] = make_unique<EVMDialect>(_version, true); dialects[_version] = std::make_unique<EVMDialect>(_version, true);
return *dialects[_version]; return *dialects[_version];
} }
@ -374,16 +374,16 @@ SideEffects EVMDialect::sideEffectsOfInstruction(evmasm::Instruction _instructio
BuiltinFunctionForEVM const* EVMDialect::verbatimFunction(size_t _arguments, size_t _returnVariables) const BuiltinFunctionForEVM const* EVMDialect::verbatimFunction(size_t _arguments, size_t _returnVariables) const
{ {
pair<size_t, size_t> key{_arguments, _returnVariables}; std::pair<size_t, size_t> key{_arguments, _returnVariables};
shared_ptr<BuiltinFunctionForEVM const>& function = m_verbatimFunctions[key]; std::shared_ptr<BuiltinFunctionForEVM const>& function = m_verbatimFunctions[key];
if (!function) if (!function)
{ {
BuiltinFunctionForEVM builtinFunction = createFunction( BuiltinFunctionForEVM builtinFunction = createFunction(
"verbatim_" + to_string(_arguments) + "i_" + to_string(_returnVariables) + "o", "verbatim_" + std::to_string(_arguments) + "i_" + std::to_string(_returnVariables) + "o",
1 + _arguments, 1 + _arguments,
_returnVariables, _returnVariables,
SideEffects::worst(), SideEffects::worst(),
vector<optional<LiteralKind>>{LiteralKind::String} + vector<optional<LiteralKind>>(_arguments), std::vector<std::optional<LiteralKind>>{LiteralKind::String} + std::vector<std::optional<LiteralKind>>(_arguments),
[=]( [=](
FunctionCall const& _call, FunctionCall const& _call,
AbstractAssembly& _assembly, AbstractAssembly& _assembly,
@ -400,7 +400,7 @@ BuiltinFunctionForEVM const* EVMDialect::verbatimFunction(size_t _arguments, siz
} }
).second; ).second;
builtinFunction.isMSize = true; builtinFunction.isMSize = true;
function = make_shared<BuiltinFunctionForEVM const>(std::move(builtinFunction)); function = std::make_shared<BuiltinFunctionForEVM const>(std::move(builtinFunction));
} }
return function.get(); return function.get();
} }
@ -501,9 +501,9 @@ BuiltinFunctionForEVM const* EVMDialectTyped::equalityFunction(YulString _type)
EVMDialectTyped const& EVMDialectTyped::instance(langutil::EVMVersion _version) EVMDialectTyped const& EVMDialectTyped::instance(langutil::EVMVersion _version)
{ {
static map<langutil::EVMVersion, unique_ptr<EVMDialectTyped const>> dialects; static std::map<langutil::EVMVersion, std::unique_ptr<EVMDialectTyped const>> dialects;
static YulStringRepository::ResetCallback callback{[&] { dialects.clear(); }}; static YulStringRepository::ResetCallback callback{[&] { dialects.clear(); }};
if (!dialects[_version]) if (!dialects[_version])
dialects[_version] = make_unique<EVMDialectTyped>(_version, true); dialects[_version] = std::make_unique<EVMDialectTyped>(_version, true);
return *dialects[_version]; return *dialects[_version];
} }

View File

@ -31,7 +31,6 @@
#include <libsolutil/CommonData.h> #include <libsolutil/CommonData.h>
using namespace std;
using namespace solidity; using namespace solidity;
using namespace solidity::yul; using namespace solidity::yul;
using namespace solidity::util; using namespace solidity::util;
@ -52,7 +51,7 @@ bigint GasMeter::combineCosts(std::pair<bigint, bigint> _costs) const
} }
pair<bigint, bigint> GasMeterVisitor::costs( std::pair<bigint, bigint> GasMeterVisitor::costs(
Expression const& _expression, Expression const& _expression,
EVMDialect const& _dialect, EVMDialect const& _dialect,
bool _isCreation bool _isCreation
@ -63,7 +62,7 @@ pair<bigint, bigint> GasMeterVisitor::costs(
return {gmv.m_runGas, gmv.m_dataGas}; return {gmv.m_runGas, gmv.m_dataGas};
} }
pair<bigint, bigint> GasMeterVisitor::instructionCosts( std::pair<bigint, bigint> GasMeterVisitor::instructionCosts(
evmasm::Instruction _instruction, evmasm::Instruction _instruction,
EVMDialect const& _dialect, EVMDialect const& _dialect,
bool _isCreation bool _isCreation

View File

@ -33,7 +33,6 @@
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
using namespace solidity::yul; using namespace solidity::yul;
using namespace std;
void EVMObjectCompiler::compile( void EVMObjectCompiler::compile(
Object& _object, Object& _object,
@ -91,12 +90,12 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize)
); );
if (!stackErrors.empty()) if (!stackErrors.empty())
{ {
vector<FunctionCall*> memoryGuardCalls = FunctionCallFinder::run( std::vector<FunctionCall*> memoryGuardCalls = FunctionCallFinder::run(
*_object.code, *_object.code,
"memoryguard"_yulstring "memoryguard"_yulstring
); );
auto stackError = stackErrors.front(); auto stackError = stackErrors.front();
string msg = stackError.comment() ? *stackError.comment() : ""; std::string msg = stackError.comment() ? *stackError.comment() : "";
if (memoryGuardCalls.empty()) if (memoryGuardCalls.empty())
msg += "\nNo memoryguard was present. " msg += "\nNo memoryguard was present. "
"Consider using memory-safe assembly only and annotating it via " "Consider using memory-safe assembly only and annotating it via "

View File

@ -33,7 +33,6 @@
#include <memory> #include <memory>
#include <functional> #include <functional>
using namespace std;
using namespace solidity; using namespace solidity;
using namespace solidity::yul; using namespace solidity::yul;
using namespace solidity::util; using namespace solidity::util;
@ -122,14 +121,14 @@ void EthAssemblyAdapter::appendAssemblySize()
m_assembly.appendProgramSize(); m_assembly.appendProgramSize();
} }
pair<shared_ptr<AbstractAssembly>, AbstractAssembly::SubID> EthAssemblyAdapter::createSubAssembly(bool _creation, string _name) std::pair<std::shared_ptr<AbstractAssembly>, AbstractAssembly::SubID> EthAssemblyAdapter::createSubAssembly(bool _creation, std::string _name)
{ {
shared_ptr<evmasm::Assembly> assembly{make_shared<evmasm::Assembly>(m_assembly.evmVersion(), _creation, std::move(_name))}; std::shared_ptr<evmasm::Assembly> assembly{std::make_shared<evmasm::Assembly>(m_assembly.evmVersion(), _creation, std::move(_name))};
auto sub = m_assembly.newSub(assembly); auto sub = m_assembly.newSub(assembly);
return {make_shared<EthAssemblyAdapter>(*assembly), static_cast<size_t>(sub.data())}; return {std::make_shared<EthAssemblyAdapter>(*assembly), static_cast<size_t>(sub.data())};
} }
void EthAssemblyAdapter::appendDataOffset(vector<AbstractAssembly::SubID> const& _subPath) void EthAssemblyAdapter::appendDataOffset(std::vector<AbstractAssembly::SubID> const& _subPath)
{ {
if (auto it = m_dataHashBySubId.find(_subPath[0]); it != m_dataHashBySubId.end()) if (auto it = m_dataHashBySubId.find(_subPath[0]); it != m_dataHashBySubId.end())
{ {
@ -141,7 +140,7 @@ void EthAssemblyAdapter::appendDataOffset(vector<AbstractAssembly::SubID> const&
m_assembly.pushSubroutineOffset(m_assembly.encodeSubPath(_subPath)); m_assembly.pushSubroutineOffset(m_assembly.encodeSubPath(_subPath));
} }
void EthAssemblyAdapter::appendDataSize(vector<AbstractAssembly::SubID> const& _subPath) void EthAssemblyAdapter::appendDataSize(std::vector<AbstractAssembly::SubID> const& _subPath)
{ {
if (auto it = m_dataHashBySubId.find(_subPath[0]); it != m_dataHashBySubId.end()) if (auto it = m_dataHashBySubId.find(_subPath[0]); it != m_dataHashBySubId.end())
{ {

View File

@ -28,7 +28,6 @@
#include <range/v3/view/iota.hpp> #include <range/v3/view/iota.hpp>
using namespace std;
using namespace solidity; using namespace solidity;
using namespace solidity::yul; using namespace solidity::yul;
using namespace solidity::util; using namespace solidity::util;
@ -60,12 +59,12 @@ NoOutputAssembly::LabelID NoOutputAssembly::newLabelId()
return 1; return 1;
} }
AbstractAssembly::LabelID NoOutputAssembly::namedLabel(string const&, size_t, size_t, optional<size_t>) AbstractAssembly::LabelID NoOutputAssembly::namedLabel(std::string const&, size_t, size_t, std::optional<size_t>)
{ {
return 1; return 1;
} }
void NoOutputAssembly::appendLinkerSymbol(string const&) void NoOutputAssembly::appendLinkerSymbol(std::string const&)
{ {
yulAssert(false, "Linker symbols not yet implemented."); yulAssert(false, "Linker symbols not yet implemented.");
} }
@ -98,7 +97,7 @@ void NoOutputAssembly::appendAssemblySize()
appendInstruction(evmasm::Instruction::PUSH1); appendInstruction(evmasm::Instruction::PUSH1);
} }
pair<shared_ptr<AbstractAssembly>, AbstractAssembly::SubID> NoOutputAssembly::createSubAssembly(bool, std::string) std::pair<std::shared_ptr<AbstractAssembly>, AbstractAssembly::SubID> NoOutputAssembly::createSubAssembly(bool, std::string)
{ {
yulAssert(false, "Sub assemblies not implemented."); yulAssert(false, "Sub assemblies not implemented.");
return {}; return {};

View File

@ -38,9 +38,8 @@
using namespace solidity; using namespace solidity;
using namespace solidity::yul; using namespace solidity::yul;
using namespace std;
vector<StackTooDeepError> OptimizedEVMCodeTransform::run( std::vector<StackTooDeepError> OptimizedEVMCodeTransform::run(
AbstractAssembly& _assembly, AbstractAssembly& _assembly,
AsmAnalysisInfo& _analysisInfo, AsmAnalysisInfo& _analysisInfo,
Block const& _block, Block const& _block,
@ -81,7 +80,7 @@ void OptimizedEVMCodeTransform::operator()(CFG::FunctionCall const& _call)
// Assert that we got the correct return label on stack. // Assert that we got the correct return label on stack.
if (_call.canContinue) if (_call.canContinue)
{ {
auto const* returnLabelSlot = get_if<FunctionCallReturnLabelSlot>( auto const* returnLabelSlot = std::get_if<FunctionCallReturnLabelSlot>(
&m_stack.at(m_stack.size() - _call.functionCall.get().arguments.size() - 1) &m_stack.at(m_stack.size() - _call.functionCall.get().arguments.size() - 1)
); );
yulAssert(returnLabelSlot && &returnLabelSlot->call.get() == &_call.functionCall.get(), ""); yulAssert(returnLabelSlot && &returnLabelSlot->call.get() == &_call.functionCall.get(), "");
@ -160,7 +159,7 @@ void OptimizedEVMCodeTransform::operator()(CFG::Assignment const& _assignment)
// Invalidate occurrences of the assigned variables. // Invalidate occurrences of the assigned variables.
for (auto& currentSlot: m_stack) for (auto& currentSlot: m_stack)
if (VariableSlot const* varSlot = get_if<VariableSlot>(&currentSlot)) if (VariableSlot const* varSlot = std::get_if<VariableSlot>(&currentSlot))
if (util::contains(_assignment.variables, *varSlot)) if (util::contains(_assignment.variables, *varSlot))
currentSlot = JunkSlot{}; currentSlot = JunkSlot{};
@ -185,8 +184,8 @@ OptimizedEVMCodeTransform::OptimizedEVMCodeTransform(
m_dfg(_dfg), m_dfg(_dfg),
m_stackLayout(_stackLayout), m_stackLayout(_stackLayout),
m_functionLabels([&](){ m_functionLabels([&](){
map<CFG::FunctionInfo const*, AbstractAssembly::LabelID> functionLabels; std::map<CFG::FunctionInfo const*, AbstractAssembly::LabelID> functionLabels;
set<YulString> assignedFunctionNames; std::set<YulString> assignedFunctionNames;
for (Scope::Function const* function: m_dfg.functions) for (Scope::Function const* function: m_dfg.functions)
{ {
CFG::FunctionInfo const& functionInfo = m_dfg.functionInfo.at(function); CFG::FunctionInfo const& functionInfo = m_dfg.functionInfo.at(function);
@ -199,7 +198,7 @@ OptimizedEVMCodeTransform::OptimizedEVMCodeTransform(
function->name.str(), function->name.str(),
function->arguments.size(), function->arguments.size(),
function->returns.size(), function->returns.size(),
functionInfo.debugData ? functionInfo.debugData->astID : nullopt functionInfo.debugData ? functionInfo.debugData->astID : std::nullopt
) : ) :
m_assembly.newLabelId(); m_assembly.newLabelId();
} }
@ -212,7 +211,7 @@ void OptimizedEVMCodeTransform::assertLayoutCompatibility(Stack const& _currentS
{ {
yulAssert(_currentStack.size() == _desiredStack.size(), ""); yulAssert(_currentStack.size() == _desiredStack.size(), "");
for (auto&& [currentSlot, desiredSlot]: ranges::zip_view(_currentStack, _desiredStack)) for (auto&& [currentSlot, desiredSlot]: ranges::zip_view(_currentStack, _desiredStack))
yulAssert(holds_alternative<JunkSlot>(desiredSlot) || currentSlot == desiredSlot, ""); yulAssert(std::holds_alternative<JunkSlot>(desiredSlot) || currentSlot == desiredSlot, "");
} }
AbstractAssembly::LabelID OptimizedEVMCodeTransform::getFunctionLabel(Scope::Function const& _function) AbstractAssembly::LabelID OptimizedEVMCodeTransform::getFunctionLabel(Scope::Function const& _function)
@ -224,15 +223,15 @@ void OptimizedEVMCodeTransform::validateSlot(StackSlot const& _slot, Expression
{ {
std::visit(util::GenericVisitor{ std::visit(util::GenericVisitor{
[&](yul::Literal const& _literal) { [&](yul::Literal const& _literal) {
auto* literalSlot = get_if<LiteralSlot>(&_slot); auto* literalSlot = std::get_if<LiteralSlot>(&_slot);
yulAssert(literalSlot && valueOfLiteral(_literal) == literalSlot->value, ""); yulAssert(literalSlot && valueOfLiteral(_literal) == literalSlot->value, "");
}, },
[&](yul::Identifier const& _identifier) { [&](yul::Identifier const& _identifier) {
auto* variableSlot = get_if<VariableSlot>(&_slot); auto* variableSlot = std::get_if<VariableSlot>(&_slot);
yulAssert(variableSlot && variableSlot->variable.get().name == _identifier.name, ""); yulAssert(variableSlot && variableSlot->variable.get().name == _identifier.name, "");
}, },
[&](yul::FunctionCall const& _call) { [&](yul::FunctionCall const& _call) {
auto* temporarySlot = get_if<TemporarySlot>(&_slot); auto* temporarySlot = std::get_if<TemporarySlot>(&_slot);
yulAssert(temporarySlot && &temporarySlot->call.get() == &_call && temporarySlot->index == 0, ""); yulAssert(temporarySlot && &temporarySlot->call.get() == &_call && temporarySlot->index == 0, "");
} }
}, _expression); }, _expression);
@ -267,10 +266,10 @@ void OptimizedEVMCodeTransform::createStackLayout(std::shared_ptr<DebugData cons
StackSlot const& deepSlot = m_stack.at(m_stack.size() - _i - 1); StackSlot const& deepSlot = m_stack.at(m_stack.size() - _i - 1);
YulString varNameDeep = slotVariableName(deepSlot); YulString varNameDeep = slotVariableName(deepSlot);
YulString varNameTop = slotVariableName(m_stack.back()); YulString varNameTop = slotVariableName(m_stack.back());
string msg = std::string msg =
"Cannot swap " + (varNameDeep.empty() ? "Slot " + stackSlotToString(deepSlot) : "Variable " + varNameDeep.str()) + "Cannot swap " + (varNameDeep.empty() ? "Slot " + stackSlotToString(deepSlot) : "Variable " + varNameDeep.str()) +
" with " + (varNameTop.empty() ? "Slot " + stackSlotToString(m_stack.back()) : "Variable " + varNameTop.str()) + " with " + (varNameTop.empty() ? "Slot " + stackSlotToString(m_stack.back()) : "Variable " + varNameTop.str()) +
": too deep in the stack by " + to_string(deficit) + " slots in " + stackToString(m_stack); ": too deep in the stack by " + std::to_string(deficit) + " slots in " + stackToString(m_stack);
m_stackErrors.emplace_back(StackTooDeepError( m_stackErrors.emplace_back(StackTooDeepError(
m_currentFunctionInfo ? m_currentFunctionInfo->function.name : YulString{}, m_currentFunctionInfo ? m_currentFunctionInfo->function.name : YulString{},
varNameDeep.empty() ? varNameTop : varNameDeep, varNameDeep.empty() ? varNameTop : varNameDeep,
@ -297,9 +296,9 @@ void OptimizedEVMCodeTransform::createStackLayout(std::shared_ptr<DebugData cons
{ {
int deficit = static_cast<int>(*depth - 15); int deficit = static_cast<int>(*depth - 15);
YulString varName = slotVariableName(_slot); YulString varName = slotVariableName(_slot);
string msg = std::string msg =
(varName.empty() ? "Slot " + stackSlotToString(_slot) : "Variable " + varName.str()) (varName.empty() ? "Slot " + stackSlotToString(_slot) : "Variable " + varName.str())
+ " is " + to_string(*depth - 15) + " too deep in the stack " + stackToString(m_stack); + " is " + std::to_string(*depth - 15) + " too deep in the stack " + stackToString(m_stack);
m_stackErrors.emplace_back(StackTooDeepError( m_stackErrors.emplace_back(StackTooDeepError(
m_currentFunctionInfo ? m_currentFunctionInfo->function.name : YulString{}, m_currentFunctionInfo ? m_currentFunctionInfo->function.name : YulString{},
varName, varName,
@ -503,9 +502,9 @@ void OptimizedEVMCodeTransform::operator()(CFG::BasicBlock const& _block)
[&](CFG::BasicBlock::Terminated const&) [&](CFG::BasicBlock::Terminated const&)
{ {
yulAssert(!_block.operations.empty()); yulAssert(!_block.operations.empty());
if (CFG::BuiltinCall const* builtinCall = get_if<CFG::BuiltinCall>(&_block.operations.back().operation)) if (CFG::BuiltinCall const* builtinCall = std::get_if<CFG::BuiltinCall>(&_block.operations.back().operation))
yulAssert(builtinCall->builtin.get().controlFlowSideEffects.terminatesOrReverts(), ""); yulAssert(builtinCall->builtin.get().controlFlowSideEffects.terminatesOrReverts(), "");
else if (CFG::FunctionCall const* functionCall = get_if<CFG::FunctionCall>(&_block.operations.back().operation)) else if (CFG::FunctionCall const* functionCall = std::get_if<CFG::FunctionCall>(&_block.operations.back().operation))
yulAssert(!functionCall->canContinue); yulAssert(!functionCall->canContinue);
else else
yulAssert(false); yulAssert(false);

View File

@ -46,7 +46,6 @@
using namespace solidity; using namespace solidity;
using namespace solidity::yul; using namespace solidity::yul;
using namespace std;
StackLayout StackLayoutGenerator::run(CFG const& _cfg) StackLayout StackLayoutGenerator::run(CFG const& _cfg)
{ {
@ -59,9 +58,9 @@ StackLayout StackLayoutGenerator::run(CFG const& _cfg)
return stackLayout; return stackLayout;
} }
map<YulString, vector<StackLayoutGenerator::StackTooDeep>> StackLayoutGenerator::reportStackTooDeep(CFG const& _cfg) std::map<YulString, std::vector<StackLayoutGenerator::StackTooDeep>> StackLayoutGenerator::reportStackTooDeep(CFG const& _cfg)
{ {
map<YulString, vector<StackLayoutGenerator::StackTooDeep>> stackTooDeepErrors; std::map<YulString, std::vector<StackLayoutGenerator::StackTooDeep>> stackTooDeepErrors;
stackTooDeepErrors[YulString{}] = reportStackTooDeep(_cfg, YulString{}); stackTooDeepErrors[YulString{}] = reportStackTooDeep(_cfg, YulString{});
for (auto const& function: _cfg.functions) for (auto const& function: _cfg.functions)
if (auto errors = reportStackTooDeep(_cfg, function->name); !errors.empty()) if (auto errors = reportStackTooDeep(_cfg, function->name); !errors.empty())
@ -69,7 +68,7 @@ map<YulString, vector<StackLayoutGenerator::StackTooDeep>> StackLayoutGenerator:
return stackTooDeepErrors; return stackTooDeepErrors;
} }
vector<StackLayoutGenerator::StackTooDeep> StackLayoutGenerator::reportStackTooDeep(CFG const& _cfg, YulString _functionName) std::vector<StackLayoutGenerator::StackTooDeep> StackLayoutGenerator::reportStackTooDeep(CFG const& _cfg, YulString _functionName)
{ {
StackLayout stackLayout; StackLayout stackLayout;
CFG::FunctionInfo const* functionInfo = nullptr; CFG::FunctionInfo const* functionInfo = nullptr;
@ -98,14 +97,14 @@ StackLayoutGenerator::StackLayoutGenerator(StackLayout& _layout, CFG::FunctionIn
namespace namespace
{ {
/// @returns all stack too deep errors that would occur when shuffling @a _source to @a _target. /// @returns all stack too deep errors that would occur when shuffling @a _source to @a _target.
vector<StackLayoutGenerator::StackTooDeep> findStackTooDeep(Stack const& _source, Stack const& _target) std::vector<StackLayoutGenerator::StackTooDeep> findStackTooDeep(Stack const& _source, Stack const& _target)
{ {
Stack currentStack = _source; Stack currentStack = _source;
vector<StackLayoutGenerator::StackTooDeep> stackTooDeepErrors; std::vector<StackLayoutGenerator::StackTooDeep> stackTooDeepErrors;
auto getVariableChoices = [](auto&& _range) { auto getVariableChoices = [](auto&& _range) {
vector<YulString> result; std::vector<YulString> result;
for (auto const& slot: _range) for (auto const& slot: _range)
if (auto const* variableSlot = get_if<VariableSlot>(&slot)) if (auto const* variableSlot = std::get_if<VariableSlot>(&slot))
if (!util::contains(result, variableSlot->variable.get().name)) if (!util::contains(result, variableSlot->variable.get().name))
result.push_back(variableSlot->variable.get().name); result.push_back(variableSlot->variable.get().name);
return result; return result;
@ -160,7 +159,7 @@ Stack createIdealLayout(Stack const& _operationOutput, Stack const& _post, Calla
// PreviousSlot{0}, ..., PreviousSlot{n}, [output<0>], ..., [output<m>] // PreviousSlot{0}, ..., PreviousSlot{n}, [output<0>], ..., [output<m>]
auto layout = ranges::views::iota(0u, preOperationLayoutSize) | auto layout = ranges::views::iota(0u, preOperationLayoutSize) |
ranges::views::transform([](size_t _index) { return PreviousSlot{_index}; }) | ranges::views::transform([](size_t _index) { return PreviousSlot{_index}; }) |
ranges::to<vector<variant<PreviousSlot, StackSlot>>>; ranges::to<std::vector<std::variant<PreviousSlot, StackSlot>>>;
layout += _operationOutput; layout += _operationOutput;
// Shortcut for trivial case. // Shortcut for trivial case.
@ -171,23 +170,23 @@ Stack createIdealLayout(Stack const& _operationOutput, Stack const& _post, Calla
// that are aware of PreviousSlot's. // that are aware of PreviousSlot's.
struct ShuffleOperations struct ShuffleOperations
{ {
vector<variant<PreviousSlot, StackSlot>>& layout; std::vector<std::variant<PreviousSlot, StackSlot>>& layout;
Stack const& post; Stack const& post;
std::set<StackSlot> outputs; std::set<StackSlot> outputs;
Multiplicity multiplicity; Multiplicity multiplicity;
Callable generateSlotOnTheFly; Callable generateSlotOnTheFly;
ShuffleOperations( ShuffleOperations(
vector<variant<PreviousSlot, StackSlot>>& _layout, std::vector<std::variant<PreviousSlot, StackSlot>>& _layout,
Stack const& _post, Stack const& _post,
Callable _generateSlotOnTheFly Callable _generateSlotOnTheFly
): layout(_layout), post(_post), generateSlotOnTheFly(_generateSlotOnTheFly) ): layout(_layout), post(_post), generateSlotOnTheFly(_generateSlotOnTheFly)
{ {
for (auto const& layoutSlot: layout) for (auto const& layoutSlot: layout)
if (StackSlot const* slot = get_if<StackSlot>(&layoutSlot)) if (StackSlot const* slot = std::get_if<StackSlot>(&layoutSlot))
outputs.insert(*slot); outputs.insert(*slot);
for (auto const& layoutSlot: layout) for (auto const& layoutSlot: layout)
if (StackSlot const* slot = get_if<StackSlot>(&layoutSlot)) if (StackSlot const* slot = std::get_if<StackSlot>(&layoutSlot))
--multiplicity[*slot]; --multiplicity[*slot];
for (auto&& slot: post) for (auto&& slot: post)
if (outputs.count(slot) || generateSlotOnTheFly(slot)) if (outputs.count(slot) || generateSlotOnTheFly(slot))
@ -235,7 +234,7 @@ Stack createIdealLayout(Stack const& _operationOutput, Stack const& _post, Calla
} }
void swap(size_t _i) void swap(size_t _i)
{ {
yulAssert(!holds_alternative<PreviousSlot>(layout.at(layout.size() - _i - 1)) || !holds_alternative<PreviousSlot>(layout.back()), ""); yulAssert(!std::holds_alternative<PreviousSlot>(layout.at(layout.size() - _i - 1)) || !std::holds_alternative<PreviousSlot>(layout.back()), "");
std::swap(layout.at(layout.size() - _i - 1), layout.back()); std::swap(layout.at(layout.size() - _i - 1), layout.back());
} }
size_t sourceSize() { return layout.size(); } size_t sourceSize() { return layout.size(); }
@ -250,7 +249,7 @@ Stack createIdealLayout(Stack const& _operationOutput, Stack const& _post, Calla
// output in place. The resulting permutation of the PreviousSlot yields the ideal positions of slots // output in place. The resulting permutation of the PreviousSlot yields the ideal positions of slots
// before the operation, i.e. if PreviousSlot{2} is at a position at which _post contains VariableSlot{"tmp"}, // before the operation, i.e. if PreviousSlot{2} is at a position at which _post contains VariableSlot{"tmp"},
// then we want the variable tmp in the slot at offset 2 in the layout before the operation. // then we want the variable tmp in the slot at offset 2 in the layout before the operation.
vector<optional<StackSlot>> idealLayout(_post.size(), nullopt); std::vector<std::optional<StackSlot>> idealLayout(_post.size(), std::nullopt);
for (auto&& [slot, idealPosition]: ranges::zip_view(_post, layout)) for (auto&& [slot, idealPosition]: ranges::zip_view(_post, layout))
if (PreviousSlot* previousSlot = std::get_if<PreviousSlot>(&idealPosition)) if (PreviousSlot* previousSlot = std::get_if<PreviousSlot>(&idealPosition))
idealLayout.at(previousSlot->slot) = slot; idealLayout.at(previousSlot->slot) = slot;
@ -261,7 +260,7 @@ Stack createIdealLayout(Stack const& _operationOutput, Stack const& _post, Calla
yulAssert(idealLayout.size() == preOperationLayoutSize, ""); yulAssert(idealLayout.size() == preOperationLayoutSize, "");
return idealLayout | ranges::views::transform([](optional<StackSlot> s) { return idealLayout | ranges::views::transform([](std::optional<StackSlot> s) {
yulAssert(s, ""); yulAssert(s, "");
return *s; return *s;
}) | ranges::to<Stack>; }) | ranges::to<Stack>;
@ -271,7 +270,7 @@ Stack createIdealLayout(Stack const& _operationOutput, Stack const& _post, Calla
Stack StackLayoutGenerator::propagateStackThroughOperation(Stack _exitStack, CFG::Operation const& _operation, bool _aggressiveStackCompression) Stack StackLayoutGenerator::propagateStackThroughOperation(Stack _exitStack, CFG::Operation const& _operation, bool _aggressiveStackCompression)
{ {
// Enable aggressive stack compression for recursive calls. // Enable aggressive stack compression for recursive calls.
if (auto const* functionCall = get_if<CFG::FunctionCall>(&_operation.operation)) if (auto const* functionCall = std::get_if<CFG::FunctionCall>(&_operation.operation))
if (functionCall->recursive) if (functionCall->recursive)
_aggressiveStackCompression = true; _aggressiveStackCompression = true;
@ -285,9 +284,9 @@ Stack StackLayoutGenerator::propagateStackThroughOperation(Stack _exitStack, CFG
Stack stack = createIdealLayout(_operation.output, _exitStack, generateSlotOnTheFly); Stack stack = createIdealLayout(_operation.output, _exitStack, generateSlotOnTheFly);
// Make sure the resulting previous slots do not overlap with any assignmed variables. // Make sure the resulting previous slots do not overlap with any assignmed variables.
if (auto const* assignment = get_if<CFG::Assignment>(&_operation.operation)) if (auto const* assignment = std::get_if<CFG::Assignment>(&_operation.operation))
for (auto& stackSlot: stack) for (auto& stackSlot: stack)
if (auto const* varSlot = get_if<VariableSlot>(&stackSlot)) if (auto const* varSlot = std::get_if<VariableSlot>(&stackSlot))
yulAssert(!util::contains(assignment->variables, *varSlot), ""); yulAssert(!util::contains(assignment->variables, *varSlot), "");
// Since stack+_operation.output can be easily shuffled to _exitLayout, the desired layout before the operation // Since stack+_operation.output can be easily shuffled to _exitLayout, the desired layout before the operation
@ -335,11 +334,11 @@ Stack StackLayoutGenerator::propagateStackThroughBlock(Stack _exitStack, CFG::Ba
void StackLayoutGenerator::processEntryPoint(CFG::BasicBlock const& _entry, CFG::FunctionInfo const* _functionInfo) void StackLayoutGenerator::processEntryPoint(CFG::BasicBlock const& _entry, CFG::FunctionInfo const* _functionInfo)
{ {
list<CFG::BasicBlock const*> toVisit{&_entry}; std::list<CFG::BasicBlock const*> toVisit{&_entry};
set<CFG::BasicBlock const*> visited; std::set<CFG::BasicBlock const*> visited;
// TODO: check whether visiting only a subset of these in the outer iteration below is enough. // TODO: check whether visiting only a subset of these in the outer iteration below is enough.
list<pair<CFG::BasicBlock const*, CFG::BasicBlock const*>> backwardsJumps = collectBackwardsJumps(_entry); std::list<std::pair<CFG::BasicBlock const*, CFG::BasicBlock const*>> backwardsJumps = collectBackwardsJumps(_entry);
while (!toVisit.empty()) while (!toVisit.empty())
{ {
@ -407,10 +406,10 @@ void StackLayoutGenerator::processEntryPoint(CFG::BasicBlock const& _entry, CFG:
fillInJunk(_entry, _functionInfo); fillInJunk(_entry, _functionInfo);
} }
optional<Stack> StackLayoutGenerator::getExitLayoutOrStageDependencies( std::optional<Stack> StackLayoutGenerator::getExitLayoutOrStageDependencies(
CFG::BasicBlock const& _block, CFG::BasicBlock const& _block,
set<CFG::BasicBlock const*> const& _visited, std::set<CFG::BasicBlock const*> const& _visited,
list<CFG::BasicBlock const*>& _toVisit std::list<CFG::BasicBlock const*>& _toVisit
) const ) const
{ {
return std::visit(util::GenericVisitor{ return std::visit(util::GenericVisitor{
@ -434,7 +433,7 @@ optional<Stack> StackLayoutGenerator::getExitLayoutOrStageDependencies(
return m_layout.blockInfos.at(_jump.target).entryLayout; return m_layout.blockInfos.at(_jump.target).entryLayout;
// Otherwise stage the jump target for visit and defer the current block. // Otherwise stage the jump target for visit and defer the current block.
_toVisit.emplace_front(_jump.target); _toVisit.emplace_front(_jump.target);
return nullopt; return std::nullopt;
}, },
[&](CFG::BasicBlock::ConditionalJump const& _conditionalJump) -> std::optional<Stack> [&](CFG::BasicBlock::ConditionalJump const& _conditionalJump) -> std::optional<Stack>
{ {
@ -456,7 +455,7 @@ optional<Stack> StackLayoutGenerator::getExitLayoutOrStageDependencies(
_toVisit.emplace_front(_conditionalJump.zero); _toVisit.emplace_front(_conditionalJump.zero);
if (!nonZeroVisited) if (!nonZeroVisited)
_toVisit.emplace_front(_conditionalJump.nonZero); _toVisit.emplace_front(_conditionalJump.nonZero);
return nullopt; return std::nullopt;
}, },
[&](CFG::BasicBlock::FunctionReturn const& _functionReturn) -> std::optional<Stack> [&](CFG::BasicBlock::FunctionReturn const& _functionReturn) -> std::optional<Stack>
{ {
@ -476,9 +475,9 @@ optional<Stack> StackLayoutGenerator::getExitLayoutOrStageDependencies(
}, _block.exit); }, _block.exit);
} }
list<pair<CFG::BasicBlock const*, CFG::BasicBlock const*>> StackLayoutGenerator::collectBackwardsJumps(CFG::BasicBlock const& _entry) const std::list<std::pair<CFG::BasicBlock const*, CFG::BasicBlock const*>> StackLayoutGenerator::collectBackwardsJumps(CFG::BasicBlock const& _entry) const
{ {
list<pair<CFG::BasicBlock const*, CFG::BasicBlock const*>> backwardsJumps; std::list<std::pair<CFG::BasicBlock const*, CFG::BasicBlock const*>> backwardsJumps;
util::BreadthFirstSearch<CFG::BasicBlock const*>{{&_entry}}.run([&](CFG::BasicBlock const* _block, auto _addChild) { util::BreadthFirstSearch<CFG::BasicBlock const*>{{&_entry}}.run([&](CFG::BasicBlock const* _block, auto _addChild) {
std::visit(util::GenericVisitor{ std::visit(util::GenericVisitor{
[&](CFG::BasicBlock::MainExit const&) {}, [&](CFG::BasicBlock::MainExit const&) {},
@ -576,7 +575,7 @@ Stack StackLayoutGenerator::combineStack(Stack const& _stack1, Stack const& _sta
if (!util::contains(candidate, slot)) if (!util::contains(candidate, slot))
candidate.emplace_back(slot); candidate.emplace_back(slot);
cxx20::erase_if(candidate, [](StackSlot const& slot) { cxx20::erase_if(candidate, [](StackSlot const& slot) {
return holds_alternative<LiteralSlot>(slot) || holds_alternative<FunctionCallReturnLabelSlot>(slot); return std::holds_alternative<LiteralSlot>(slot) || std::holds_alternative<FunctionCallReturnLabelSlot>(slot);
}); });
auto evaluate = [&](Stack const& _candidate) -> size_t { auto evaluate = [&](Stack const& _candidate) -> size_t {
@ -633,9 +632,9 @@ Stack StackLayoutGenerator::combineStack(Stack const& _stack1, Stack const& _sta
return commonPrefix + bestCandidate; return commonPrefix + bestCandidate;
} }
vector<StackLayoutGenerator::StackTooDeep> StackLayoutGenerator::reportStackTooDeep(CFG::BasicBlock const& _entry) const std::vector<StackLayoutGenerator::StackTooDeep> StackLayoutGenerator::reportStackTooDeep(CFG::BasicBlock const& _entry) const
{ {
vector<StackTooDeep> stackTooDeepErrors; std::vector<StackTooDeep> stackTooDeepErrors;
util::BreadthFirstSearch<CFG::BasicBlock const*> breadthFirstSearch{{&_entry}}; util::BreadthFirstSearch<CFG::BasicBlock const*> breadthFirstSearch{{&_entry}};
breadthFirstSearch.run([&](CFG::BasicBlock const* _block, auto _addChild) { breadthFirstSearch.run([&](CFG::BasicBlock const* _block, auto _addChild) {
Stack currentStack = m_layout.blockInfos.at(_block).entryLayout; Stack currentStack = m_layout.blockInfos.at(_block).entryLayout;
@ -683,7 +682,7 @@ vector<StackLayoutGenerator::StackTooDeep> StackLayoutGenerator::reportStackTooD
Stack StackLayoutGenerator::compressStack(Stack _stack) Stack StackLayoutGenerator::compressStack(Stack _stack)
{ {
optional<size_t> firstDupOffset; std::optional<size_t> firstDupOffset;
do do
{ {
if (firstDupOffset) if (firstDupOffset)
@ -768,8 +767,8 @@ void StackLayoutGenerator::fillInJunk(CFG::BasicBlock const& _block, CFG::Functi
{ {
// This has to be a previously unassigned return variable. // This has to be a previously unassigned return variable.
// We at least sanity-check that it is among the return variables at all. // We at least sanity-check that it is among the return variables at all.
yulAssert(m_currentFunctionInfo && holds_alternative<VariableSlot>(_slot)); yulAssert(m_currentFunctionInfo && std::holds_alternative<VariableSlot>(_slot));
yulAssert(util::contains(m_currentFunctionInfo->returnVariables, get<VariableSlot>(_slot))); yulAssert(util::contains(m_currentFunctionInfo->returnVariables, std::get<VariableSlot>(_slot)));
// Strictly speaking the cost of the PUSH0 depends on the targeted EVM version, but the difference // Strictly speaking the cost of the PUSH0 depends on the targeted EVM version, but the difference
// will not matter here. // will not matter here.
opGas += evmasm::GasMeter::runGas(evmasm::pushInstruction(0), langutil::EVMVersion());; opGas += evmasm::GasMeter::runGas(evmasm::pushInstruction(0), langutil::EVMVersion());;

View File

@ -34,6 +34,7 @@ NAMESPACE_STD_FREE_FILES=(
libsolidity/lsp/* libsolidity/lsp/*
libsolidity/parsing/* libsolidity/parsing/*
libsolutil/* libsolutil/*
libyul/backends/evm/*
solc/* solc/*
) )