Merge pull request #11944 from ethereum/debug-info-selection

Debug info selection
This commit is contained in:
chriseth
2021-10-12 16:39:50 +02:00
committed by GitHub
109 changed files with 2427 additions and 91 deletions
+5 -1
View File
@@ -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)
@@ -30,6 +30,7 @@
#include <libsolidity/codegen/ir/Common.h>
#include <liblangutil/CharStreamProvider.h>
#include <liblangutil/DebugInfoSelection.h>
#include <liblangutil/EVMVersion.h>
#include <libsolutil/Common.h>
@@ -74,6 +75,7 @@ public:
RevertStrings _revertStrings,
OptimiserSettings _optimiserSettings,
std::map<std::string, unsigned> _sourceIndices,
langutil::DebugInfoSelection const& _debugInfoSelection,
langutil::CharStreamProvider const* _soliditySourceProvider
):
m_evmVersion(_evmVersion),
@@ -81,6 +83,7 @@ public:
m_revertStrings(_revertStrings),
m_optimiserSettings(std::move(_optimiserSettings)),
m_sourceIndices(std::move(_sourceIndices)),
m_debugInfoSelection(_debugInfoSelection),
m_soliditySourceProvider(_soliditySourceProvider)
{}
@@ -174,6 +177,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 +224,7 @@ private:
std::set<ContractDefinition const*, ASTNode::CompareByID> m_subObjects;
langutil::DebugInfoSelection m_debugInfoSelection = {};
langutil::CharStreamProvider const* m_soliditySourceProvider = nullptr;
};
+41 -17
View File
@@ -95,7 +95,12 @@ pair<string, string> IRGenerator::run(
{
string const ir = yul::reindent(generate(_contract, _cborMetadata, _otherYulSources));
yul::AssemblyStack asmStack(m_evmVersion, yul::AssemblyStack::Language::StrictAssembly, m_optimiserSettings);
yul::AssemblyStack asmStack(
m_evmVersion,
yul::AssemblyStack::Language::StrictAssembly,
m_optimiserSettings,
m_context.debugInfoSelection()
);
if (!asmStack.parseAndAnalyze("", ir))
{
string errorMessage;
@@ -340,8 +345,7 @@ string IRGenerator::generateFunction(FunctionDefinition const& _function)
return m_context.functionCollector().createFunction(functionName, [&]() {
m_context.resetLocalVariables();
Whiskers t(R"(
/// @ast-id <astID>
<sourceLocationComment>
<astIDComment><sourceLocationComment>
function <functionName>(<params>)<?+retParams> -> <retParams></+retParams> {
<retInit>
<body>
@@ -349,7 +353,10 @@ string IRGenerator::generateFunction(FunctionDefinition const& _function)
<contractSourceLocationComment>
)");
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 +416,7 @@ string IRGenerator::generateModifier(
return m_context.functionCollector().createFunction(functionName, [&]() {
m_context.resetLocalVariables();
Whiskers t(R"(
/// @ast-id <astID>
<sourceLocationComment>
<astIDComment><sourceLocationComment>
function <functionName>(<params>)<?+retParams> -> <retParams></+retParams> {
<assignRetParams>
<evalArgs>
@@ -418,6 +424,7 @@ string IRGenerator::generateModifier(
}
<contractSourceLocationComment>
)");
t("functionName", functionName);
vector<string> retParamsIn;
for (auto const& varDecl: _function.returnParameters())
@@ -440,7 +447,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 +557,18 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl)
solAssert(paramTypes.empty(), "");
solUnimplementedAssert(type->sizeOnStack() == 1);
return Whiskers(R"(
/// @ast-id <astID>
<sourceLocationComment>
<astIDComment><sourceLocationComment>
function <functionName>() -> rval {
rval := loadimmutable("<id>")
}
<contractSourceLocationComment>
)")
("astID", to_string(_varDecl.id()))
(
"astIDComment",
m_context.debugInfoSelection().astID ?
"/// @ast-id " + to_string(_varDecl.id()) + "\n" :
""
)
("sourceLocationComment", dispenseLocationComment(_varDecl))
(
"contractSourceLocationComment",
@@ -567,14 +582,18 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl)
{
solAssert(paramTypes.empty(), "");
return Whiskers(R"(
/// @ast-id <astID>
<sourceLocationComment>
<astIDComment><sourceLocationComment>
function <functionName>() -> <ret> {
<ret> := <constantValueFunction>()
}
<contractSourceLocationComment>
)")
("astID", to_string(_varDecl.id()))
(
"astIDComment",
m_context.debugInfoSelection().astID ?
"/// @ast-id " + to_string(_varDecl.id()) + "\n" :
""
)
("sourceLocationComment", dispenseLocationComment(_varDecl))
(
"contractSourceLocationComment",
@@ -691,8 +710,7 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl)
}
return Whiskers(R"(
/// @ast-id <astID>
<sourceLocationComment>
<astIDComment><sourceLocationComment>
function <functionName>(<params>) -> <retVariables> {
<code>
}
@@ -702,7 +720,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 +852,7 @@ void IRGenerator::generateConstructors(ContractDefinition const& _contract)
for (ASTPointer<VariableDeclaration> 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", "");
@@ -1085,6 +1108,7 @@ void IRGenerator::resetContext(ContractDefinition const& _contract, ExecutionCon
m_context.revertStrings(),
m_optimiserSettings,
m_context.sourceIndices(),
m_context.debugInfoSelection(),
m_context.soliditySourceProvider()
);
newContext.copyFunctionIDsFrom(m_context);
+2
View File
@@ -49,6 +49,7 @@ public:
RevertStrings _revertStrings,
OptimiserSettings _optimiserSettings,
std::map<std::string, unsigned> _sourceIndices,
langutil::DebugInfoSelection const& _debugInfoSelection,
langutil::CharStreamProvider const* _soliditySourceProvider
):
m_evmVersion(_evmVersion),
@@ -59,6 +60,7 @@ public:
_revertStrings,
std::move(_optimiserSettings),
std::move(_sourceIndices),
_debugInfoSelection,
_soliditySourceProvider
),
m_utils(_evmVersion, m_context.revertStrings(), m_context.functionCollector())
+21 -4
View File
@@ -271,6 +271,13 @@ void CompilerStack::setMetadataHash(MetadataHash _metadataHash)
m_metadataHash = _metadataHash;
}
void CompilerStack::selectDebugInfo(DebugInfoSelection _debugInfoSelection)
{
if (m_stackState >= CompilationSuccessful)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Must select debug info components before compilation."));
m_debugInfoSelection = _debugInfoSelection;
}
void CompilerStack::addSMTLib2Response(h256 const& _hash, string const& _response)
{
if (m_stackState >= ParsedAndImported)
@@ -882,7 +889,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(m_debugInfoSelection, _sourceCodes);
else
return string();
}
@@ -1319,7 +1326,7 @@ void CompilerStack::generateIR(ContractDefinition const& _contract)
for (auto const& pair: m_contracts)
otherYulSources.emplace(pair.second.contract, pair.second.yulIR);
IRGenerator generator(m_evmVersion, m_revertStrings, m_optimiserSettings, sourceIndices(), this);
IRGenerator generator(m_evmVersion, m_revertStrings, m_optimiserSettings, sourceIndices(), m_debugInfoSelection, this);
tie(compiledContract.yulIR, compiledContract.yulIROptimized) = generator.run(
_contract,
createCBORMetadata(compiledContract, /* _forIR */ true),
@@ -1342,7 +1349,12 @@ void CompilerStack::generateEVMFromIR(ContractDefinition const& _contract)
return;
// Re-parse the Yul IR in EVM dialect
yul::AssemblyStack stack(m_evmVersion, yul::AssemblyStack::Language::StrictAssembly, m_optimiserSettings);
yul::AssemblyStack stack(
m_evmVersion,
yul::AssemblyStack::Language::StrictAssembly,
m_optimiserSettings,
m_debugInfoSelection
);
stack.parseAndAnalyze("", compiledContract.yulIROptimized);
stack.optimize();
@@ -1369,7 +1381,12 @@ void CompilerStack::generateEwasm(ContractDefinition const& _contract)
return;
// Re-parse the Yul IR in EVM dialect
yul::AssemblyStack stack(m_evmVersion, yul::AssemblyStack::Language::StrictAssembly, m_optimiserSettings);
yul::AssemblyStack stack(
m_evmVersion,
yul::AssemblyStack::Language::StrictAssembly,
m_optimiserSettings,
m_debugInfoSelection
);
stack.parseAndAnalyze("", compiledContract.yulIROptimized);
stack.optimize();
+6 -1
View File
@@ -35,10 +35,11 @@
#include <libsmtutil/SolverInterface.h>
#include <liblangutil/CharStreamProvider.h>
#include <liblangutil/DebugInfoSelection.h>
#include <liblangutil/ErrorReporter.h>
#include <liblangutil/EVMVersion.h>
#include <liblangutil/SourceLocation.h>
#include <liblangutil/CharStreamProvider.h>
#include <libevmasm/LinkerObject.h>
@@ -203,6 +204,9 @@ public:
/// @param _metadataHash can be IPFS, Bzzr1, None
void setMetadataHash(MetadataHash _metadataHash);
/// Select components of debug info that should be included in comments in generated assembly.
void selectDebugInfo(langutil::DebugInfoSelection _debugInfoSelection);
/// Sets the sources. Must be set before parsing.
void setSources(StringMap _sources);
@@ -505,6 +509,7 @@ private:
langutil::ErrorReporter m_errorReporter;
bool m_metadataLiteralSources = false;
MetadataHash m_metadataHash = MetadataHash::IPFS;
langutil::DebugInfoSelection m_debugInfoSelection = langutil::DebugInfoSelection::Default();
bool m_parserErrorRecovery = false;
State m_stackState = Empty;
bool m_importedSources = false;
+37 -3
View File
@@ -28,9 +28,13 @@
#include <libyul/AssemblyStack.h>
#include <libyul/Exceptions.h>
#include <libyul/optimiser/Suite.h>
#include <liblangutil/SourceReferenceFormatter.h>
#include <libevmasm/Instruction.h>
#include <libsmtutil/Exceptions.h>
#include <liblangutil/SourceReferenceFormatter.h>
#include <libsolutil/JSON.h>
#include <libsolutil/Keccak256.h>
#include <libsolutil/CommonData.h>
@@ -793,7 +797,7 @@ std::variant<StandardCompiler::InputsAndSettings, Json::Value> StandardCompiler:
if (settings.isMember("debug"))
{
if (auto result = checkKeys(settings["debug"], {"revertStrings"}, "settings.debug"))
if (auto result = checkKeys(settings["debug"], {"revertStrings", "debugInfo"}, "settings.debug"))
return *result;
if (settings["debug"].isMember("revertStrings"))
@@ -810,6 +814,31 @@ std::variant<StandardCompiler::InputsAndSettings, Json::Value> StandardCompiler:
);
ret.revertStrings = *revertStrings;
}
if (settings["debug"].isMember("debugInfo"))
{
if (!settings["debug"]["debugInfo"].isArray())
return formatFatalError("JSONError", "settings.debug.debugInfo must be an array.");
vector<string> components;
for (Json::Value const& arrayValue: settings["debug"]["debugInfo"])
components.push_back(arrayValue.asString());
optional<DebugInfoSelection> debugInfoSelection = DebugInfoSelection::fromComponents(
components,
true /* _acceptWildcards */
);
if (!debugInfoSelection.has_value())
return formatFatalError("JSONError", "Invalid value in settings.debug.debugInfo.");
if (debugInfoSelection->snippet && !debugInfoSelection->location)
return formatFatalError(
"JSONError",
"To use 'snippet' with settings.debug.debugInfo you must select also 'location'."
);
ret.debugInfoSelection = debugInfoSelection.value();
}
}
if (settings.isMember("remappings") && !settings["remappings"].isArray())
@@ -1029,6 +1058,8 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
compilerStack.setRemappings(move(_inputsAndSettings.remappings));
compilerStack.setOptimiserSettings(std::move(_inputsAndSettings.optimiserSettings));
compilerStack.setRevertStringBehaviour(_inputsAndSettings.revertStrings);
if (_inputsAndSettings.debugInfoSelection.has_value())
compilerStack.selectDebugInfo(_inputsAndSettings.debugInfoSelection.value());
compilerStack.setLibraries(_inputsAndSettings.libraries);
compilerStack.useMetadataLiteralSources(_inputsAndSettings.metadataLiteralSources);
compilerStack.setMetadataHash(_inputsAndSettings.metadataHash);
@@ -1358,7 +1389,10 @@ Json::Value StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings)
AssemblyStack stack(
_inputsAndSettings.evmVersion,
AssemblyStack::Language::StrictAssembly,
_inputsAndSettings.optimiserSettings
_inputsAndSettings.optimiserSettings,
_inputsAndSettings.debugInfoSelection.has_value() ?
_inputsAndSettings.debugInfoSelection.value() :
DebugInfoSelection::Default()
);
string const& sourceName = _inputsAndSettings.sources.begin()->first;
string const& sourceContents = _inputsAndSettings.sources.begin()->second;
+3
View File
@@ -26,6 +26,8 @@
#include <libsolidity/interface/CompilerStack.h>
#include <libsolutil/JSON.h>
#include <liblangutil/DebugInfoSelection.h>
#include <optional>
#include <utility>
#include <variant>
@@ -78,6 +80,7 @@ private:
std::vector<ImportRemapper::Remapping> remappings;
RevertStrings revertStrings = RevertStrings::Default;
OptimiserSettings optimiserSettings = OptimiserSettings::minimal();
std::optional<langutil::DebugInfoSelection> debugInfoSelection;
std::map<std::string, util::h160> libraries;
bool metadataLiteralSources = false;
CompilerStack::MetadataHash metadataHash = CompilerStack::MetadataHash::IPFS;