Skip to content

Commit

Permalink
Yul: Object contains dialect
Browse files Browse the repository at this point in the history
  • Loading branch information
clonker committed Oct 25, 2024
1 parent abc46f3 commit a59ec52
Show file tree
Hide file tree
Showing 28 changed files with 61 additions and 44 deletions.
2 changes: 1 addition & 1 deletion libsolidity/ast/ASTJsonExporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ bool ASTJsonExporter::visit(InlineAssembly const& _node)
auto const& evmDialect = dynamic_cast<solidity::yul::EVMDialect const&>(_node.dialect());

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(evmDialect, sourceIndexFromLocation(_node.location()))(_node.operations().root()))),
std::make_pair("externalReferences", std::move(externalReferencesJson)),
std::make_pair("evmVersion", evmDialect.evmVersion().name())
};
Expand Down
6 changes: 3 additions & 3 deletions libsolidity/codegen/CompilerContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ void CompilerContext::appendInlineAssembly(
// so we essentially only optimize the ABI functions.
if (_optimiserSettings.runYulOptimiser && _localVariables.empty())
{
yul::Object obj;
yul::Object obj{dialect};
obj.setCode(parserResult, std::make_shared<yul::AsmAnalysisInfo>(analysisInfo));

solAssert(!dialect.providesObjectAccess());
Expand All @@ -491,8 +491,8 @@ void CompilerContext::appendInlineAssembly(
{
// Store as generated sources, but first re-parse to update the source references.
solAssert(m_generatedYulUtilityCode.empty(), "");
m_generatedYulUtilityCode = yul::AsmPrinter()(obj.code()->root());
std::string code = yul::AsmPrinter{}(obj.code()->root());
m_generatedYulUtilityCode = yul::AsmPrinter(obj.dialect())(obj.code()->root());
std::string code = yul::AsmPrinter{obj.dialect()}(obj.code()->root());
langutil::CharStream charStream(m_generatedYulUtilityCode, _sourceName);
obj.setCode(yul::Parser(errorReporter, dialect).parse(charStream));
obj.analysisInfo = std::make_shared<yul::AsmAnalysisInfo>(yul::AsmAnalyzer::analyzeStrictAssertCorrect(dialect, obj));
Expand Down
2 changes: 1 addition & 1 deletion libsolidity/codegen/ContractCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -932,7 +932,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly)

// Only used in the scope below, but required to live outside to keep the
// std::shared_ptr's alive
yul::Object object = {};
yul::Object object{_inlineAssembly.dialect()};

// The optimiser cannot handle external references
if (
Expand Down
2 changes: 1 addition & 1 deletion libsolidity/codegen/ir/IRGeneratorForStatements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2258,7 +2258,7 @@ bool IRGeneratorForStatements::visit(InlineAssembly const& _inlineAsm)

solAssert(std::holds_alternative<yul::Block>(modified));

appendCode() << yul::AsmPrinter()(std::get<yul::Block>(modified)) << "\n";
appendCode() << yul::AsmPrinter(_inlineAsm.dialect())(std::get<yul::Block>(modified)) << "\n";
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ bool IRGeneratorForStatements::visit(InlineAssembly const& _assembly)
CopyTranslate bodyCopier{m_context, _assembly.dialect(), _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 @@ -900,7 +900,7 @@ Json CompilerStack::generatedSources(std::string const& _contractName, bool _run
yul::EVMDialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion, m_eofVersion);
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
4 changes: 3 additions & 1 deletion libyul/AsmJsonConverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
namespace solidity::yul
{

struct Dialect;

/**
* Converter of the yul AST into JSON format
*/
Expand All @@ -41,7 +43,7 @@ class AsmJsonConverter: public boost::static_visitor<Json>
public:
/// Create a converter to JSON for any block of inline assembly
/// @a _sourceIndex to be used to abbreviate source name in the source locations
explicit AsmJsonConverter(std::optional<size_t> _sourceIndex): m_sourceIndex(_sourceIndex) {}
explicit AsmJsonConverter(Dialect const&, std::optional<size_t> _sourceIndex): m_sourceIndex(_sourceIndex) {}

Json operator()(Block const& _node) const;
Json operator()(NameWithDebugData const& _node) const;
Expand Down
3 changes: 3 additions & 0 deletions libyul/AsmPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
namespace solidity::yul
{

struct Dialect;

/**
* Converts a parsed Yul AST into readable string representation.
* Ignores source locations.
Expand All @@ -45,6 +47,7 @@ class AsmPrinter
{
public:
explicit AsmPrinter(
Dialect const&,
std::optional<std::map<unsigned, std::shared_ptr<std::string const>>> _sourceIndexToName = {},
langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(),
langutil::CharStreamProvider const* _soliditySourceProvider = nullptr
Expand Down
3 changes: 2 additions & 1 deletion libyul/Object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ std::string Object::toString(
yulAssert(debugData, "No debug data");

std::string inner = "code " + AsmPrinter(
m_dialect,
debugData->sourceNames,
_debugInfoSelection,
_soliditySourceProvider
Expand Down Expand Up @@ -96,7 +97,7 @@ Json Object::toJson() const

Json codeJson;
codeJson["nodeType"] = "YulCode";
codeJson["block"] = AsmJsonConverter(0 /* sourceIndex */)(code()->root());
codeJson["block"] = AsmJsonConverter(m_dialect, 0 /* sourceIndex */)(code()->root());

Json subObjectsJson = Json::array();
for (std::shared_ptr<ObjectNode> const& subObject: subObjects)
Expand Down
8 changes: 6 additions & 2 deletions libyul/Object.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ struct AsmAnalysisInfo;

using SourceNameMap = std::map<unsigned, std::shared_ptr<std::string const>>;

struct Object;
class Object;

/**
* Generic base class for both Yul objects and Yul data.
Expand Down Expand Up @@ -88,9 +88,10 @@ struct ObjectDebugData
/**
* Yul code and data object container.
*/
struct Object: public ObjectNode
class Object: public ObjectNode
{
public:
explicit Object(Dialect const& _dialect): m_dialect(_dialect) {}
/// @returns a (parseable) string representation.
std::string toString(
langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(),
Expand Down Expand Up @@ -139,7 +140,10 @@ struct Object: public ObjectNode
/// @returns the name of the special metadata data object.
static std::string metadataName() { return ".metadata"; }

Dialect const& dialect() const { return m_dialect; }

private:
Dialect const& m_dialect;
std::shared_ptr<AST const> m_code;
};

Expand Down
1 change: 1 addition & 0 deletions libyul/ObjectOptimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ std::optional<h256> ObjectOptimizer::calculateCacheKey(
)
{
AsmPrinter asmPrinter(
languageToDialect(_settings.language, _settings.evmVersion, _settings.eofVersion),
_debugData.sourceNames,
DebugInfoSelection::All()
);
Expand Down
4 changes: 2 additions & 2 deletions libyul/ObjectParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ std::shared_ptr<Object> ObjectParser::parse(std::shared_ptr<Scanner> const& _sca
if (currentToken() == Token::LBrace)
{
// Special case: Code-only form.
object = std::make_shared<Object>();
object = std::make_shared<Object>(m_dialect);
object->name = "object";
auto sourceNameMapping = tryParseSourceNameMapping();
object->debugData = std::make_shared<ObjectDebugData>(ObjectDebugData{sourceNameMapping});
Expand All @@ -74,7 +74,7 @@ std::shared_ptr<Object> ObjectParser::parseObject(Object* _containingObject)
{
RecursionGuard guard(*this);

std::shared_ptr<Object> ret = std::make_shared<Object>();
std::shared_ptr<Object> ret = std::make_shared<Object>(m_dialect);

auto sourceNameMapping = tryParseSourceNameMapping();
ret->debugData = std::make_shared<ObjectDebugData>(ObjectDebugData{sourceNameMapping});
Expand Down
2 changes: 1 addition & 1 deletion libyul/backends/evm/EVMDialect.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ namespace solidity::yul
{

struct FunctionCall;
struct Object;
class Object;

/**
* Context used during code generation.
Expand Down
2 changes: 1 addition & 1 deletion libyul/backends/evm/EVMObjectCompiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

namespace solidity::yul
{
struct Object;
class Object;
class AbstractAssembly;
class EVMDialect;

Expand Down
2 changes: 1 addition & 1 deletion libyul/optimiser/StackCompressor.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ namespace solidity::yul
{

struct Dialect;
struct Object;
class Object;
struct FunctionDefinition;

/**
Expand Down
2 changes: 1 addition & 1 deletion libyul/optimiser/StackLimitEvader.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
namespace solidity::yul
{

struct Object;
class Object;

/**
* Optimisation stage that assigns memory offsets to variables that would become unreachable if
Expand Down
2 changes: 1 addition & 1 deletion libyul/optimiser/Suite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ void OptimiserSuite::runSequence(std::vector<std::string> const& _steps, Block&
else
{
std::cout << "== Running " << step << " changed the AST." << std::endl;
std::cout << AsmPrinter{}(_ast) << std::endl;
std::cout << AsmPrinter{m_context.dialect}(_ast) << std::endl;
copy = std::make_unique<Block>(std::get<Block>(ASTCopier{}(_ast)));
}
}
Expand Down
2 changes: 1 addition & 1 deletion libyul/optimiser/Suite.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ namespace solidity::yul
struct AsmAnalysisInfo;
struct Dialect;
class GasMeter;
struct Object;
class Object;

/**
* Optimiser suite that combines all steps and also provides the settings for the heuristics.
Expand Down
4 changes: 2 additions & 2 deletions test/libyul/Common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,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
4 changes: 2 additions & 2 deletions test/libyul/Common.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ namespace solidity::yul
{
struct AsmAnalysisInfo;
struct Block;
struct Object;
class Object;
struct Dialect;
class AST;
}
Expand All @@ -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, std::optional<uint8_t> _eofVersion);

Expand Down
12 changes: 6 additions & 6 deletions test/libyul/CompilabilityChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@ namespace
{
std::string check(std::string const& _input)
{
Object obj;
auto const& dialect = EVMDialect::strictAssemblyForEVM(
solidity::test::CommonOptions::get().evmVersion(),
solidity::test::CommonOptions::get().eofVersion()
);
Object obj{dialect};
auto parsingResult = yul::test::parse(_input);
obj.setCode(parsingResult.first, parsingResult.second);
BOOST_REQUIRE(obj.hasCode());
auto functions = CompilabilityChecker(
EVMDialect::strictAssemblyForEVM(
solidity::test::CommonOptions::get().evmVersion(),
solidity::test::CommonOptions::get().eofVersion()
), obj, true).stackDeficit;
auto functions = CompilabilityChecker(dialect, obj, true).stackDeficit;
std::string out;
for (auto const& function: functions)
out += function.first.str() + ": " + std::to_string(function.second) + " ";
Expand Down
9 changes: 6 additions & 3 deletions test/libyul/ControlFlowSideEffectsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,18 @@ ControlFlowSideEffectsTest::ControlFlowSideEffectsTest(std::string const& _filen

TestCase::TestResult ControlFlowSideEffectsTest::run(std::ostream& _stream, std::string const& _linePrefix, bool _formatted)
{
Object obj;
auto const& dialect = EVMDialect::strictAssemblyForEVMObjects(
solidity::test::CommonOptions::get().evmVersion(),
solidity::test::CommonOptions::get().eofVersion()
);
Object obj{dialect};
auto parsingResult = yul::test::parse(m_source);
obj.setCode(parsingResult.first, parsingResult.second);
if (!obj.hasCode())
BOOST_THROW_EXCEPTION(std::runtime_error("Parsing input failed."));

ControlFlowSideEffectsCollector sideEffects(
EVMDialect::strictAssemblyForEVMObjects(solidity::test::CommonOptions::get().evmVersion(),
solidity::test::CommonOptions::get().eofVersion()),
dialect,
obj.code()->root()
);
m_obtainedResult.clear();
Expand Down
9 changes: 6 additions & 3 deletions test/libyul/FunctionSideEffects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,18 @@ FunctionSideEffects::FunctionSideEffects(std::string const& _filename):

TestCase::TestResult FunctionSideEffects::run(std::ostream& _stream, std::string const& _linePrefix, bool _formatted)
{
Object obj;
auto const& dialect = EVMDialect::strictAssemblyForEVMObjects(
solidity::test::CommonOptions::get().evmVersion(),
solidity::test::CommonOptions::get().eofVersion()
);
Object obj{dialect};
auto parsingResult = yul::test::parse(m_source);
obj.setCode(parsingResult.first, parsingResult.second);
if (!obj.hasCode())
BOOST_THROW_EXCEPTION(std::runtime_error("Parsing input failed."));

std::map<YulName, SideEffects> functionSideEffects = SideEffectsPropagator::sideEffects(
EVMDialect::strictAssemblyForEVMObjects(solidity::test::CommonOptions::get().evmVersion(),
solidity::test::CommonOptions::get().eofVersion()),
dialect,
CallGraphGenerator::callGraph(obj.code()->root())
);

Expand Down
2 changes: 1 addition & 1 deletion test/libyul/YulOptimizerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ TestCase::TestResult YulOptimizerTest::run(std::ostream& _stream, std::string co
auto optimizedObject = tester.optimizedObject();
std::string printedOptimizedObject;
if (optimizedObject->subObjects.empty())
printedOptimizedObject = AsmPrinter{}(optimizedObject->code()->root());
printedOptimizedObject = AsmPrinter{optimizedObject->dialect()}(optimizedObject->code()->root());
else
printedOptimizedObject = optimizedObject->toString();

Expand Down
2 changes: 1 addition & 1 deletion test/libyul/YulOptimizerTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ using ErrorList = std::vector<std::shared_ptr<Error const>>;
namespace solidity::yul
{
struct AsmAnalysisInfo;
struct Object;
class Object;
struct Dialect;
}

Expand Down
2 changes: 1 addition & 1 deletion test/libyul/YulOptimizerTestCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
namespace solidity::yul
{
struct AsmAnalysisInfo;
struct Object;
class Object;
struct Dialect;
class AST;
}
Expand Down
6 changes: 3 additions & 3 deletions test/tools/yulopti.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ class YulOpti
parse(_source);
disambiguate();
OptimiserSuite{m_context}.runSequence(_steps, *m_astRoot);
std::cout << AsmPrinter{}(*m_astRoot) << std::endl;
std::cout << AsmPrinter{m_dialect}(*m_astRoot) << std::endl;
}

void runInteractive(std::string _source, bool _disambiguated = false)
Expand Down Expand Up @@ -217,7 +217,7 @@ class YulOpti
break;
case ';':
{
Object obj;
Object obj{m_dialect};
obj.setCode(std::make_shared<AST>(std::get<yul::Block>(ASTCopier{}(*m_astRoot))));
*m_astRoot = std::get<1>(StackCompressor::run(m_dialect, obj, true, 16));
break;
Expand All @@ -228,7 +228,7 @@ class YulOpti
*m_astRoot
);
}
_source = AsmPrinter{}(*m_astRoot);
_source = AsmPrinter{m_dialect}(*m_astRoot);
}
catch (...)
{
Expand Down
4 changes: 2 additions & 2 deletions tools/yulPhaser/Program.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,12 @@ void Program::optimise(std::vector<std::string> const& _optimisationSteps)

std::ostream& phaser::operator<<(std::ostream& _stream, Program const& _program)
{
return _stream << AsmPrinter()(_program.m_ast->root());
return _stream << AsmPrinter(_program.m_dialect)(_program.m_ast->root());
}

std::string Program::toJson() const
{
Json serializedAst = AsmJsonConverter(0)(m_ast->root());
Json serializedAst = AsmJsonConverter(m_dialect, 0)(m_ast->root());
return jsonPrettyPrint(removeNullMembers(std::move(serializedAst)));
}

Expand Down

0 comments on commit a59ec52

Please sign in to comment.