From f7c4ed849d4fdcc28c09da18ef69d9dbaf3711b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 3 Sep 2021 19:38:59 +0200 Subject: [PATCH] Handle DebugInfoSelection in the code printing Yul and EVM assembly --- libevmasm/Assembly.cpp | 49 +++++++++++++------ libevmasm/Assembly.h | 3 ++ libsolidity/codegen/ir/Common.cpp | 6 ++- libsolidity/codegen/ir/IRGenerationContext.h | 3 ++ libsolidity/codegen/ir/IRGenerator.cpp | 50 +++++++++++++------- libsolidity/interface/CompilerStack.cpp | 2 +- libyul/AsmPrinter.cpp | 16 +++++-- libyul/AsmPrinter.h | 2 + 8 files changed, 96 insertions(+), 35 deletions(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 7884dd191..82bf2be71 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -96,13 +96,13 @@ public: m_out(_out), m_prefix(_prefix), m_sourceCodes(_sourceCodes), m_assembly(_assembly) {} - void feed(AssemblyItem const& _item) + void feed(AssemblyItem const& _item, DebugInfoSelection const& _debugInfoSelection) { if (_item.location().isValid() && _item.location() != m_location) { flush(); m_location = _item.location(); - printLocation(); + printLocation(_debugInfoSelection); } string expression = _item.toAssemblyText(m_assembly); @@ -142,16 +142,29 @@ public: m_pending.clear(); } - void printLocation() + void printLocation(DebugInfoSelection const& _debugInfoSelection) { - if (!m_location.isValid()) + if (!m_location.isValid() || (!_debugInfoSelection.location && !_debugInfoSelection.snippet)) return; + m_out << m_prefix << " /*"; - if (m_location.sourceName) - m_out << " " + escapeAndQuoteString(*m_location.sourceName); - if (m_location.hasText()) - m_out << ":" << to_string(m_location.start) + ":" + to_string(m_location.end); - m_out << " " << locationFromSources(m_sourceCodes, m_location); + + if (_debugInfoSelection.location) + { + if (m_location.sourceName) + m_out << " " + escapeAndQuoteString(*m_location.sourceName); + if (m_location.hasText()) + m_out << ":" << to_string(m_location.start) + ":" + to_string(m_location.end); + } + + if (_debugInfoSelection.snippet) + { + if (_debugInfoSelection.location) + m_out << " "; + + m_out << locationFromSources(m_sourceCodes, m_location); + } + m_out << " */" << endl; } @@ -167,12 +180,17 @@ private: } -void Assembly::assemblyStream(ostream& _out, string const& _prefix, StringMap const& _sourceCodes) const +void Assembly::assemblyStream( + ostream& _out, + DebugInfoSelection const& _debugInfoSelection, + string const& _prefix, + StringMap const& _sourceCodes +) const { Functionalizer f(_out, _prefix, _sourceCodes, *this); for (auto const& i: m_items) - f.feed(i); + f.feed(i, _debugInfoSelection); f.flush(); if (!m_data.empty() || !m_subs.empty()) @@ -185,7 +203,7 @@ void Assembly::assemblyStream(ostream& _out, string const& _prefix, StringMap co for (size_t i = 0; i < m_subs.size(); ++i) { _out << endl << _prefix << "sub_" << i << ": assembly {\n"; - m_subs[i]->assemblyStream(_out, _prefix + " ", _sourceCodes); + m_subs[i]->assemblyStream(_out, _debugInfoSelection, _prefix + " ", _sourceCodes); _out << _prefix << "}" << endl; } } @@ -194,10 +212,13 @@ void Assembly::assemblyStream(ostream& _out, string const& _prefix, StringMap co _out << endl << _prefix << "auxdata: 0x" << util::toHex(m_auxiliaryData) << endl; } -string Assembly::assemblyString(StringMap const& _sourceCodes) const +string Assembly::assemblyString( + DebugInfoSelection const& _debugInfoSelection, + StringMap const& _sourceCodes +) const { ostringstream tmp; - assemblyStream(tmp, "", _sourceCodes); + assemblyStream(tmp, _debugInfoSelection, "", _sourceCodes); return tmp.str(); } diff --git a/libevmasm/Assembly.h b/libevmasm/Assembly.h index 1d91c2f90..b532834f5 100644 --- a/libevmasm/Assembly.h +++ b/libevmasm/Assembly.h @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -142,10 +143,12 @@ public: /// Create a text representation of the assembly. std::string assemblyString( + langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(), StringMap const& _sourceCodes = StringMap() ) const; void assemblyStream( std::ostream& _out, + langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(), std::string const& _prefix = "", StringMap const& _sourceCodes = StringMap() ) const; diff --git a/libsolidity/codegen/ir/Common.cpp b/libsolidity/codegen/ir/Common.cpp index 49a6be5e5..e75e5ef27 100644 --- a/libsolidity/codegen/ir/Common.cpp +++ b/libsolidity/codegen/ir/Common.cpp @@ -135,11 +135,15 @@ string dispenseLocationComment(langutil::SourceLocation const& _location, IRGene { solAssert(_location.sourceName, ""); _context.markSourceUsed(*_location.sourceName); - return "/// " + AsmPrinter::formatSourceLocation( + + string debugInfo = AsmPrinter::formatSourceLocation( _location, _context.sourceIndices(), + _context.debugInfoSelection(), _context.soliditySourceProvider() ); + + return debugInfo.empty() ? "" : "/// " + debugInfo; } string dispenseLocationComment(ASTNode const& _node, IRGenerationContext& _context) diff --git a/libsolidity/codegen/ir/IRGenerationContext.h b/libsolidity/codegen/ir/IRGenerationContext.h index fdc617220..8ceb8448f 100644 --- a/libsolidity/codegen/ir/IRGenerationContext.h +++ b/libsolidity/codegen/ir/IRGenerationContext.h @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -174,6 +175,7 @@ public: bool immutableRegistered(VariableDeclaration const& _varDecl) const { return m_immutableVariables.count(&_varDecl); } + langutil::DebugInfoSelection debugInfoSelection() const { return m_debugInfoSelection; } langutil::CharStreamProvider const* soliditySourceProvider() const { return m_soliditySourceProvider; } private: @@ -220,6 +222,7 @@ private: std::set m_subObjects; + langutil::DebugInfoSelection m_debugInfoSelection = langutil::DebugInfoSelection::Default(); langutil::CharStreamProvider const* m_soliditySourceProvider = nullptr; }; diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index c1bfce4e3..1f8fe32a0 100644 --- a/libsolidity/codegen/ir/IRGenerator.cpp +++ b/libsolidity/codegen/ir/IRGenerator.cpp @@ -340,8 +340,7 @@ string IRGenerator::generateFunction(FunctionDefinition const& _function) return m_context.functionCollector().createFunction(functionName, [&]() { m_context.resetLocalVariables(); Whiskers t(R"( - /// @ast-id - + function () -> { @@ -349,7 +348,10 @@ string IRGenerator::generateFunction(FunctionDefinition const& _function) )"); - t("astID", to_string(_function.id())); + if (m_context.debugInfoSelection().astID) + t("astIDComment", "/// @ast-id " + to_string(_function.id()) + "\n"); + else + t("astIDComment", ""); t("sourceLocationComment", dispenseLocationComment(_function)); t( "contractSourceLocationComment", @@ -409,8 +411,7 @@ string IRGenerator::generateModifier( return m_context.functionCollector().createFunction(functionName, [&]() { m_context.resetLocalVariables(); Whiskers t(R"( - /// @ast-id - + function () -> { @@ -418,6 +419,7 @@ string IRGenerator::generateModifier( } )"); + t("functionName", functionName); vector retParamsIn; for (auto const& varDecl: _function.returnParameters()) @@ -440,7 +442,11 @@ string IRGenerator::generateModifier( _modifierInvocation.name().annotation().referencedDeclaration ); solAssert(modifier, ""); - t("astID", to_string(modifier->id())); + + if (m_context.debugInfoSelection().astID) + t("astIDComment", "/// @ast-id " + to_string(modifier->id()) + "\n"); + else + t("astIDComment", ""); t("sourceLocationComment", dispenseLocationComment(*modifier)); t( "contractSourceLocationComment", @@ -546,14 +552,18 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl) solAssert(paramTypes.empty(), ""); solUnimplementedAssert(type->sizeOnStack() == 1); return Whiskers(R"( - /// @ast-id - + function () -> rval { rval := loadimmutable("") } )") - ("astID", to_string(_varDecl.id())) + ( + "astIDComment", + m_context.debugInfoSelection().astID ? + "/// @ast-id " + to_string(_varDecl.id()) + "\n" : + "" + ) ("sourceLocationComment", dispenseLocationComment(_varDecl)) ( "contractSourceLocationComment", @@ -567,14 +577,18 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl) { solAssert(paramTypes.empty(), ""); return Whiskers(R"( - /// @ast-id - + function () -> { := () } )") - ("astID", to_string(_varDecl.id())) + ( + "astIDComment", + m_context.debugInfoSelection().astID ? + "/// @ast-id " + to_string(_varDecl.id()) + "\n" : + "" + ) ("sourceLocationComment", dispenseLocationComment(_varDecl)) ( "contractSourceLocationComment", @@ -691,8 +705,7 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl) } return Whiskers(R"( - /// @ast-id - + function () -> { } @@ -702,7 +715,12 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl) ("params", joinHumanReadable(parameters)) ("retVariables", joinHumanReadable(returnVariables)) ("code", std::move(code)) - ("astID", to_string(_varDecl.id())) + ( + "astIDComment", + m_context.debugInfoSelection().astID ? + "/// @ast-id " + to_string(_varDecl.id()) + "\n" : + "" + ) ("sourceLocationComment", dispenseLocationComment(_varDecl)) ( "contractSourceLocationComment", @@ -829,7 +847,7 @@ void IRGenerator::generateConstructors(ContractDefinition const& _contract) for (ASTPointer const& varDecl: contract->constructor()->parameters()) params += m_context.addLocalVariable(*varDecl).stackSlots(); - if (contract->constructor()) + if (m_context.debugInfoSelection().astID && contract->constructor()) t("astIDComment", "/// @ast-id " + to_string(contract->constructor()->id()) + "\n"); else t("astIDComment", ""); diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index e49c15387..8ef1abf32 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -882,7 +882,7 @@ string CompilerStack::assemblyString(string const& _contractName, StringMap cons Contract const& currentContract = contract(_contractName); if (currentContract.evmAssembly) - return currentContract.evmAssembly->assemblyString(_sourceCodes); + return currentContract.evmAssembly->assemblyString(DebugInfoSelection::Default(), _sourceCodes); else return string(); } diff --git a/libyul/AsmPrinter.cpp b/libyul/AsmPrinter.cpp index 68f21bcd7..8cf5d6c11 100644 --- a/libyul/AsmPrinter.cpp +++ b/libyul/AsmPrinter.cpp @@ -261,10 +261,16 @@ string AsmPrinter::appendTypeName(YulString _type, bool _isBoolLiteral) const string AsmPrinter::formatSourceLocation( SourceLocation const& _location, map const& _nameToSourceIndex, + DebugInfoSelection const& _debugInfoSelection, CharStreamProvider const* _soliditySourceProvider ) { yulAssert(!_nameToSourceIndex.empty(), ""); + if (_debugInfoSelection.snippet) + yulAssert(_debugInfoSelection.location, "@src tag must always contain the source location"); + + if (_debugInfoSelection.none()) + return ""; string sourceIndex = "-1"; string solidityCodeSnippet = ""; @@ -272,7 +278,7 @@ string AsmPrinter::formatSourceLocation( { sourceIndex = to_string(_nameToSourceIndex.at(*_location.sourceName)); - if (_soliditySourceProvider) + if (_debugInfoSelection.snippet && _soliditySourceProvider) { solidityCodeSnippet = escapeAndQuoteString( _soliditySourceProvider->charStream(*_location.sourceName).singleLineSnippet(_location) @@ -298,12 +304,15 @@ string AsmPrinter::formatSourceLocation( string AsmPrinter::formatDebugData(shared_ptr const& _debugData, bool _statement) { - if (!_debugData) + DebugInfoSelection debugInfoSelection = DebugInfoSelection::Default(); + + if (!_debugData || debugInfoSelection.none()) return ""; vector items; if (auto id = _debugData->astID) - items.emplace_back("@ast-id " + to_string(*id)); + if (debugInfoSelection.astID) + items.emplace_back("@ast-id " + to_string(*id)); if ( m_lastLocation != _debugData->originLocation && @@ -315,6 +324,7 @@ string AsmPrinter::formatDebugData(shared_ptr const& _debugData items.emplace_back(formatSourceLocation( _debugData->originLocation, m_nameToSourceIndex, + debugInfoSelection, m_soliditySourceProvider )); } diff --git a/libyul/AsmPrinter.h b/libyul/AsmPrinter.h index 3bb683191..94890fa15 100644 --- a/libyul/AsmPrinter.h +++ b/libyul/AsmPrinter.h @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -83,6 +84,7 @@ public: static std::string formatSourceLocation( langutil::SourceLocation const& _location, std::map const& _nameToSourceIndex, + langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(), langutil::CharStreamProvider const* m_soliditySourceProvider = nullptr );