Skip to content

Commit

Permalink
f
Browse files Browse the repository at this point in the history
  • Loading branch information
clonker committed Aug 22, 2024
1 parent 604b5a1 commit a5e3f71
Show file tree
Hide file tree
Showing 17 changed files with 121 additions and 77 deletions.
2 changes: 1 addition & 1 deletion libsolidity/ast/ASTJsonExporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -665,7 +665,7 @@ bool ASTJsonExporter::visit(InlineAssembly const& _node)
externalReferencesJson.emplace_back(std::move(it));

std::vector<std::pair<std::string, Json>> attributes = {
std::make_pair("AST", Json(yul::AsmJsonConverter(sourceIndexFromLocation(_node.location()))(_node.operations().root()))),
std::make_pair("AST", Json(yul::AsmJsonConverter(_node.dialect(), sourceIndexFromLocation(_node.location()))(_node.operations().root()))),
std::make_pair("externalReferences", std::move(externalReferencesJson)),
std::make_pair("evmVersion", dynamic_cast<solidity::yul::EVMDialect const&>(_node.dialect()).evmVersion().name())
};
Expand Down
13 changes: 4 additions & 9 deletions libsolidity/experimental/codegen/IRGeneratorForStatements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,8 @@ struct CopyTranslate: public yul::ASTCopier
{
CopyTranslate(
IRGenerationContext const& _context,
yul::Dialect const& _dialect,
std::map<yul::Identifier const*, InlineAssemblyAnnotation::ExternalIdentifierInfo> _references
): m_context(_context), m_dialect(_dialect), m_references(std::move(_references)) {}
): m_context(_context), m_references(std::move(_references)) {}

using ASTCopier::operator();

Expand All @@ -72,10 +71,7 @@ struct CopyTranslate: public yul::ASTCopier

yul::YulName translateIdentifier(yul::YulName _name) override
{
if (m_dialect.builtin(_name))
return _name;
else
return yul::YulName{"usr$" + _name.str()};
return yul::YulName{"usr$" + _name.str()};
}

yul::Identifier translate(yul::Identifier const& _identifier) override
Expand Down Expand Up @@ -106,7 +102,6 @@ struct CopyTranslate: public yul::ASTCopier
}

IRGenerationContext const& m_context;
yul::Dialect const& m_dialect;
std::map<yul::Identifier const*, InlineAssemblyAnnotation::ExternalIdentifierInfo> m_references;
};

Expand All @@ -129,10 +124,10 @@ bool IRGeneratorForStatements::visit(TupleExpression const& _tupleExpression)

bool IRGeneratorForStatements::visit(InlineAssembly const& _assembly)
{
CopyTranslate bodyCopier{m_context, _assembly.dialect(), _assembly.annotation().externalReferences};
CopyTranslate bodyCopier{m_context, _assembly.annotation().externalReferences};
yul::Statement modified = bodyCopier(_assembly.operations().root());
solAssert(std::holds_alternative<yul::Block>(modified));
m_code << yul::AsmPrinter()(std::get<yul::Block>(modified)) << "\n";
m_code << yul::AsmPrinter(_assembly.dialect())(std::get<yul::Block>(modified)) << "\n";
return false;
}

Expand Down
2 changes: 1 addition & 1 deletion libsolidity/interface/CompilerStack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -849,7 +849,7 @@ Json CompilerStack::generatedSources(std::string const& _contractName, bool _run
yul::EVMDialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion);
std::shared_ptr<yul::AST> parserResult = yul::Parser{errorReporter, dialect}.parse(charStream);
solAssert(parserResult, "");
sources[0]["ast"] = yul::AsmJsonConverter{sourceIndex}(parserResult->root());
sources[0]["ast"] = yul::AsmJsonConverter{dialect, sourceIndex}(parserResult->root());
sources[0]["name"] = sourceName;
sources[0]["id"] = sourceIndex;
sources[0]["language"] = "Yul";
Expand Down
35 changes: 28 additions & 7 deletions libyul/Utilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,15 @@

#include <libyul/Utilities.h>

#include <libyul/backends/evm/EVMDialect.h>

#include <libyul/AST.h>
#include <libyul/Dialect.h>
#include <libyul/Exceptions.h>

#include <libsolutil/CommonData.h>
#include <libsolutil/FixedHash.h>
#include <libsolutil/Visitor.h>

#include <boost/algorithm/string.hpp>

Expand Down Expand Up @@ -241,12 +244,30 @@ bool SwitchCaseCompareByLiteralValue::operator()(Case const* _lhs, Case const* _

std::string_view yul::resolveFunctionName(FunctionName const& _functionName, Dialect const& _dialect)
{
if (std::holds_alternative<Identifier>(_functionName))
return std::get<Identifier>(_functionName).name.str();
else if (std::holds_alternative<Builtin>(_functionName))
return _dialect.builtinFunction(std::get<Builtin>(_functionName).handle).name;
else if (std::holds_alternative<Verbatim>(_functionName))
return _dialect.verbatimFunction(std::get<Verbatim>(_functionName).handle).name;
yulAssert(false);
GenericVisitor visitor{
[&](Identifier const& _identifier) { return _identifier.name.str(); },
[&](Builtin const& _builtin) { return _dialect.builtinFunction(_builtin.handle).name; },
[&](Verbatim const& _verbatim) { return _dialect.verbatimFunction(_verbatim.handle).name; }
};
return std::visit(visitor, _functionName);
}

BuiltinFunction const* yul::resolveBuiltinFunction(FunctionName const& _functionName, Dialect const& _dialect)
{
GenericVisitor visitor{
[&](Identifier const&) -> BuiltinFunction const* { return nullptr; },
[&](Builtin const& _builtin) -> BuiltinFunction const* { return &_dialect.builtinFunction(_builtin.handle); },
[&](Verbatim const& _verbatim) -> BuiltinFunction const* { return &_dialect.verbatimFunction(_verbatim.handle); }
};
return std::visit(visitor, _functionName);
}

BuiltinFunctionForEVM const* yul::resolveBuiltinFunctionForEVM(FunctionName const& _functionName, EVMDialect const& _dialect)
{
GenericVisitor visitor{
[&](Identifier const&) -> BuiltinFunctionForEVM const* { return nullptr; },
[&](Builtin const& _builtin) -> BuiltinFunctionForEVM const* { return &_dialect.builtinFunction(_builtin.handle); },
[&](Verbatim const& _verbatim) -> BuiltinFunctionForEVM const* { return &_dialect.verbatimFunction(_verbatim.handle); }
};
return std::visit(visitor, _functionName);
}
6 changes: 6 additions & 0 deletions libyul/Utilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ namespace solidity::yul
{

struct Dialect;
struct EVMDialect;
struct BuiltinFunction;
struct BuiltinFunctionForEVM;

std::string reindent(std::string const& _code);

Expand Down Expand Up @@ -87,4 +90,7 @@ struct SwitchCaseCompareByLiteralValue

std::string_view resolveFunctionName(FunctionName const& _functionName, Dialect const& _dialect);

BuiltinFunction const* resolveBuiltinFunction(FunctionName const& _functionName, Dialect const& _dialect);
BuiltinFunctionForEVM const* resolveBuiltinFunctionForEVM(FunctionName const& _functionName, EVMDialect const& _dialect);

}
1 change: 0 additions & 1 deletion libyul/backends/evm/EVMDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,6 @@ EVMDialect::EVMDialect(langutil::EVMVersion _evmVersion, bool _objectAccess):

std::optional<BuiltinHandle> EVMDialect::builtin(std::string_view _name) const
{
static auto constexpr comparator = [](auto const& lhs, auto const& rhs) { return lhs.name.str() < rhs.str(); };
auto it = std::find_if(m_functions.begin(), m_functions.end(), [&_name](auto const& builtin) { return builtin && builtin.value().name == _name; });
if (it != m_functions.end() && *it && it->value().name == _name)
return BuiltinHandle{static_cast<size_t>(std::distance(m_functions.begin(), it))};
Expand Down
6 changes: 4 additions & 2 deletions test/libsolidity/MemoryGuardTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,11 @@ TestCase::TestResult MemoryGuardTest::run(std::ostream& _stream, std::string con
m_obtainedResult.clear();
for (std::string contractName: compiler().contractNames())
{
auto const& dialect = EVMDialect::strictAssemblyForEVMObjects(CommonOptions::get().evmVersion());
ErrorList errors;
auto [object, analysisInfo] = yul::test::parse(
compiler().yulIR(contractName),
EVMDialect::strictAssemblyForEVMObjects(CommonOptions::get().evmVersion()),
dialect,
errors
);

Expand All @@ -76,7 +77,8 @@ TestCase::TestResult MemoryGuardTest::run(std::ostream& _stream, std::string con
auto handleObject = [&](std::string const& _kind, Object const& _object) {
m_obtainedResult += contractName + "(" + _kind + ") " + (findFunctionCalls(
_object.code()->root(),
"memoryguard"_yulname
"memoryguard",
dialect
).empty() ? "false" : "true") + "\n";
};
handleObject("creation", *object);
Expand Down
2 changes: 1 addition & 1 deletion test/libsolidity/SemanticTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ SemanticTest::SemanticTest(
}
}

std::map<std::string, Builtin> SemanticTest::makeBuiltins()
std::map<std::string, frontend::test::Builtin> SemanticTest::makeBuiltins()
{
return {
{
Expand Down
2 changes: 1 addition & 1 deletion test/libsolidity/SemanticTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class SemanticTest: public SolidityExecutionFramework, public EVMVersionRestrict
bool _formatted
);
bool checkGasCostExpectation(TestFunctionCall& io_test, bool _compileViaYul) const;
std::map<std::string, Builtin> makeBuiltins();
std::map<std::string, frontend::test::Builtin> makeBuiltins();
std::vector<SideEffectHook> makeSideEffectHooks() const;
std::vector<std::string> eventSideEffectHook(FunctionCall const&) const;
std::optional<AnnotatedEventSignature> matchEvent(util::h256 const& hash) const;
Expand Down
4 changes: 2 additions & 2 deletions test/libyul/Common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,9 @@ yul::Block yul::test::disambiguate(std::string const& _source)
return std::get<Block>(Disambiguator(defaultDialect(), *result.second, {})(result.first->root()));
}

std::string yul::test::format(std::string const& _source)
std::string yul::test::format(std::string const& _source, Dialect const& _dialect)
{
return yul::AsmPrinter()(parse(_source).first->root());
return yul::AsmPrinter(_dialect)(parse(_source).first->root());
}

namespace
Expand Down
2 changes: 1 addition & 1 deletion test/libyul/Common.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ std::pair<std::shared_ptr<Object>, std::shared_ptr<AsmAnalysisInfo>>
parse(std::string const& _source, Dialect const& _dialect, langutil::ErrorList& _errors);

Block disambiguate(std::string const& _source);
std::string format(std::string const& _source);
std::string format(std::string const& _source, Dialect const& _dialect);

solidity::yul::Dialect const& dialect(std::string const& _name, langutil::EVMVersion _evmVersion);

Expand Down
14 changes: 7 additions & 7 deletions test/libyul/ControlFlowGraphTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ static std::string variableSlotToString(VariableSlot const& _slot)
class ControlFlowGraphPrinter
{
public:
ControlFlowGraphPrinter(std::ostream& _stream):
m_stream(_stream)
ControlFlowGraphPrinter(std::ostream& _stream, Dialect const& _dialect):
m_stream(_stream), m_dialect(_dialect)
{
}
void operator()(CFG::BasicBlock const& _block, bool _isMainEntry = true)
Expand Down Expand Up @@ -129,16 +129,15 @@ class ControlFlowGraphPrinter
m_stream << _call.function.get().name.str() << ": ";
},
[&](CFG::BuiltinCall const& _call) {
m_stream << _call.functionCall.get().functionName.name.str() << ": ";

m_stream << _call.builtin.get().name << ": ";
},
[&](CFG::Assignment const& _assignment) {
m_stream << "Assignment(";
m_stream << joinHumanReadable(_assignment.variables | ranges::views::transform(variableSlotToString));
m_stream << "): ";
}
}, operation.operation);
m_stream << stackToString(operation.input) << " => " << stackToString(operation.output) << "\\l\\\n";
m_stream << stackToString(operation.input, m_dialect) << " => " << stackToString(operation.output, m_dialect) << "\\l\\\n";
}
m_stream << "\"];\n";
std::visit(util::GenericVisitor{
Expand All @@ -160,7 +159,7 @@ class ControlFlowGraphPrinter
{
m_stream << "Block" << getBlockId(_block) << " -> Block" << getBlockId(_block) << "Exit;\n";
m_stream << "Block" << getBlockId(_block) << "Exit [label=\"{ ";
m_stream << stackSlotToString(_conditionalJump.condition);
m_stream << stackSlotToString(_conditionalJump.condition, m_dialect);
m_stream << "| { <0> Zero | <1> NonZero }}\" shape=Mrecord];\n";
m_stream << "Block" << getBlockId(_block);
m_stream << "Exit:0 -> Block" << getBlockId(*_conditionalJump.zero) << ";\n";
Expand Down Expand Up @@ -189,6 +188,7 @@ class ControlFlowGraphPrinter
return id;
}
std::ostream& m_stream;
Dialect const& m_dialect;
std::map<CFG::BasicBlock const*, size_t> m_blockIds;
size_t m_blockCount = 0;
std::list<CFG::BasicBlock const*> m_blocksToPrint;
Expand All @@ -209,7 +209,7 @@ TestCase::TestResult ControlFlowGraphTest::run(std::ostream& _stream, std::strin
std::unique_ptr<CFG> cfg = ControlFlowGraphBuilder::build(*analysisInfo, *m_dialect, object->code()->root());

output << "digraph CFG {\nnodesep=0.7;\nnode[shape=box];\n\n";
ControlFlowGraphPrinter printer{output};
ControlFlowGraphPrinter printer{output, *m_dialect};
printer(*cfg->entry);
for (auto function: cfg->functions)
printer(cfg->functionInfo.at(function));
Expand Down
15 changes: 12 additions & 3 deletions test/libyul/FunctionSideEffects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <libyul/backends/evm/EVMDialect.h>

#include <libsolutil/StringUtils.h>
#include <libsolutil/Visitor.h>

#include <boost/algorithm/string.hpp>

Expand Down Expand Up @@ -88,14 +89,22 @@ TestCase::TestResult FunctionSideEffects::run(std::ostream& _stream, std::string
if (!obj.hasCode())
BOOST_THROW_EXCEPTION(std::runtime_error("Parsing input failed."));

std::map<YulName, SideEffects> functionSideEffects = SideEffectsPropagator::sideEffects(
EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()),
auto const& dialect = EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion());
std::map<CallGraph::FunctionNameIdentifier, SideEffects> functionSideEffects = SideEffectsPropagator::sideEffects(
dialect,
CallGraphGenerator::callGraph(obj.code()->root())
);

std::map<std::string, std::string> functionSideEffectsStr;
for (auto const& fun: functionSideEffects)
functionSideEffectsStr[fun.first.str()] = toString(fun.second);
{
auto const& functionNameStr = std::visit(GenericVisitor{
[](YulName const& _name) { return _name.str(); },
[&](BuiltinHandle const& _builtin) { return dialect.builtinFunction(_builtin).name; },
[&](VerbatimHandle const& _verbatim) { return dialect.verbatimFunction(_verbatim).name; }
}, fun.first);
functionSideEffectsStr[functionNameStr] = toString(fun.second);
}

m_obtainedResult.clear();
for (auto const& fun: functionSideEffectsStr)
Expand Down
21 changes: 11 additions & 10 deletions test/libyul/StackLayoutGeneratorTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ static std::string variableSlotToString(VariableSlot const& _slot)
class StackLayoutPrinter
{
public:
StackLayoutPrinter(std::ostream& _stream, StackLayout const& _stackLayout):
m_stream(_stream), m_stackLayout(_stackLayout)
StackLayoutPrinter(std::ostream& _stream, StackLayout const& _stackLayout, Dialect const& _dialect):
m_stream(_stream), m_stackLayout(_stackLayout), m_dialect(_dialect)
{
}
void operator()(CFG::BasicBlock const& _block, bool _isMainEntry = true)
Expand Down Expand Up @@ -99,7 +99,7 @@ class StackLayoutPrinter
m_stream << "\\l\\\n";
Stack functionEntryStack = {FunctionReturnLabelSlot{_info.function}};
functionEntryStack += _info.parameters | ranges::views::reverse;
m_stream << stackToString(functionEntryStack) << "\"];\n";
m_stream << stackToString(functionEntryStack, m_dialect) << "\"];\n";
m_stream << "FunctionEntry_" << _info.function.name.str() << " -> Block" << getBlockId(*_info.entry) << ";\n";
(*this)(*_info.entry, false);
}
Expand Down Expand Up @@ -130,17 +130,17 @@ class StackLayoutPrinter
}, entry->exit);

auto const& blockInfo = m_stackLayout.blockInfos.at(&_block);
m_stream << stackToString(blockInfo.entryLayout) << "\\l\\\n";
m_stream << stackToString(blockInfo.entryLayout, m_dialect) << "\\l\\\n";
for (auto const& operation: _block.operations)
{
auto entryLayout = m_stackLayout.operationEntryLayout.at(&operation);
m_stream << stackToString(m_stackLayout.operationEntryLayout.at(&operation)) << "\\l\\\n";
m_stream << stackToString(m_stackLayout.operationEntryLayout.at(&operation), m_dialect) << "\\l\\\n";
std::visit(util::GenericVisitor{
[&](CFG::FunctionCall const& _call) {
m_stream << _call.function.get().name.str();
},
[&](CFG::BuiltinCall const& _call) {
m_stream << _call.functionCall.get().functionName.name.str();
m_stream << _call.builtin.get().name;

},
[&](CFG::Assignment const& _assignment) {
Expand All @@ -154,9 +154,9 @@ class StackLayoutPrinter
for (size_t i = 0; i < operation.input.size(); ++i)
entryLayout.pop_back();
entryLayout += operation.output;
m_stream << stackToString(entryLayout) << "\\l\\\n";
m_stream << stackToString(entryLayout, m_dialect) << "\\l\\\n";
}
m_stream << stackToString(blockInfo.exitLayout) << "\\l\\\n";
m_stream << stackToString(blockInfo.exitLayout, m_dialect) << "\\l\\\n";
m_stream << "\"];\n";
std::visit(util::GenericVisitor{
[&](CFG::BasicBlock::MainExit const&)
Expand All @@ -177,7 +177,7 @@ class StackLayoutPrinter
{
m_stream << "Block" << getBlockId(_block) << " -> Block" << getBlockId(_block) << "Exit;\n";
m_stream << "Block" << getBlockId(_block) << "Exit [label=\"{ ";
m_stream << stackSlotToString(_conditionalJump.condition);
m_stream << stackSlotToString(_conditionalJump.condition, m_dialect);
m_stream << "| { <0> Zero | <1> NonZero }}\" shape=Mrecord];\n";
m_stream << "Block" << getBlockId(_block);
m_stream << "Exit:0 -> Block" << getBlockId(*_conditionalJump.zero) << ";\n";
Expand Down Expand Up @@ -207,6 +207,7 @@ class StackLayoutPrinter
}
std::ostream& m_stream;
StackLayout const& m_stackLayout;
Dialect const& m_dialect;
std::map<CFG::BasicBlock const*, size_t> m_blockIds;
size_t m_blockCount = 0;
std::list<CFG::BasicBlock const*> m_blocksToPrint;
Expand All @@ -228,7 +229,7 @@ TestCase::TestResult StackLayoutGeneratorTest::run(std::ostream& _stream, std::s
StackLayout stackLayout = StackLayoutGenerator::run(*cfg);

output << "digraph CFG {\nnodesep=0.7;\nnode[shape=box];\n\n";
StackLayoutPrinter printer{output, stackLayout};
StackLayoutPrinter printer{output, stackLayout, *m_dialect};
printer(*cfg->entry);
for (auto function: cfg->functions)
printer(cfg->functionInfo.at(function));
Expand Down
Loading

0 comments on commit a5e3f71

Please sign in to comment.