Skip to content

Commit 1832fbd

Browse files
committed
Enable ethdebug debug info and output selection.
1 parent 0535cdd commit 1832fbd

File tree

55 files changed

+2308
-18
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+2308
-18
lines changed

libevmasm/AbstractAssemblyStack.h

+4
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ class AbstractAssemblyStack
4040
virtual std::string const* sourceMapping(std::string const& _contractName) const = 0;
4141
virtual std::string const* runtimeSourceMapping(std::string const& _contractName) const = 0;
4242

43+
virtual Json ethdebug(std::string const& _contractName) const = 0;
44+
virtual Json ethdebugRuntime(std::string const& _contractName) const = 0;
45+
virtual Json ethdebug() const = 0;
46+
4347
virtual Json assemblyJSON(std::string const& _contractName) const = 0;
4448
virtual std::string assemblyString(std::string const& _contractName, StringMap const& _sourceCodes) const = 0;
4549

libevmasm/Assembly.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ std::string Assembly::assemblyString(
444444
{
445445
std::ostringstream tmp;
446446
assemblyStream(tmp, _debugInfoSelection, "", _sourceCodes);
447-
return tmp.str();
447+
return (_debugInfoSelection.ethdebug ? "/// ethdebug: enabled\n" : "") + tmp.str();
448448
}
449449

450450
Json Assembly::assemblyJSON(std::map<std::string, unsigned> const& _sourceIndices, bool _includeSourceList) const

libevmasm/EVMAssemblyStack.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,25 @@ std::string const* EVMAssemblyStack::runtimeSourceMapping(std::string const& _co
103103
return &m_runtimeSourceMapping;
104104
}
105105

106+
Json EVMAssemblyStack::ethdebug(std::string const& _contractName) const
107+
{
108+
solAssert(_contractName == m_name);
109+
solAssert(m_ethdebug != nullptr);
110+
return *m_ethdebug;
111+
}
112+
113+
Json EVMAssemblyStack::ethdebugRuntime(std::string const& _contractName) const
114+
{
115+
solAssert(_contractName == m_name);
116+
solAssert(m_ethdebugRuntime != nullptr);
117+
return *m_ethdebugRuntime;
118+
}
119+
120+
Json EVMAssemblyStack::ethdebug() const
121+
{
122+
return {};
123+
}
124+
106125
Json EVMAssemblyStack::assemblyJSON(std::string const& _contractName) const
107126
{
108127
solAssert(_contractName == m_name);

libevmasm/EVMAssemblyStack.h

+6
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ class EVMAssemblyStack: public AbstractAssemblyStack
5959
std::string const* sourceMapping(std::string const& _contractName) const override;
6060
std::string const* runtimeSourceMapping(std::string const& _contractName) const override;
6161

62+
Json ethdebug(std::string const& _contractName) const override;
63+
Json ethdebugRuntime(std::string const& _contractName) const override;
64+
Json ethdebug() const override;
65+
6266
Json assemblyJSON(std::string const& _contractName) const override;
6367
std::string assemblyString(std::string const& _contractName, StringMap const& _sourceCodes) const override;
6468

@@ -87,6 +91,8 @@ class EVMAssemblyStack: public AbstractAssemblyStack
8791
langutil::DebugInfoSelection m_debugInfoSelection = langutil::DebugInfoSelection::Default();
8892
std::string m_sourceMapping;
8993
std::string m_runtimeSourceMapping;
94+
std::unique_ptr<Json> m_ethdebug;
95+
std::unique_ptr<Json> m_ethdebugRuntime;
9096
};
9197

9298
} // namespace solidity::evmasm

liblangutil/DebugInfoSelection.cpp

+10-2
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,22 @@ DebugInfoSelection const DebugInfoSelection::Only(bool DebugInfoSelection::* _me
4949
return result;
5050
}
5151

52+
DebugInfoSelection const DebugInfoSelection::AllExcept(std::vector<bool DebugInfoSelection::*> const& _members) noexcept
53+
{
54+
DebugInfoSelection result = All();
55+
for (bool DebugInfoSelection::* member: _members)
56+
result.*member = false;
57+
return result;
58+
}
59+
5260
std::optional<DebugInfoSelection> DebugInfoSelection::fromString(std::string_view _input)
5361
{
5462
// TODO: Make more stuff constexpr and make it a static_assert().
5563
solAssert(componentMap().count("all") == 0, "");
5664
solAssert(componentMap().count("none") == 0, "");
5765

5866
if (_input == "all")
59-
return All();
67+
return AllExceptExperimental();
6068
if (_input == "none")
6169
return None();
6270

@@ -74,7 +82,7 @@ std::optional<DebugInfoSelection> DebugInfoSelection::fromComponents(
7482
for (auto const& component: _componentNames)
7583
{
7684
if (component == "*")
77-
return (_acceptWildcards ? std::make_optional(DebugInfoSelection::All()) : std::nullopt);
85+
return (_acceptWildcards ? std::make_optional(AllExceptExperimental()) : std::nullopt);
7886

7987
if (!selection.enable(component))
8088
return std::nullopt;

liblangutil/DebugInfoSelection.h

+14-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ struct DebugInfoSelection
4242
static DebugInfoSelection const All(bool _value = true) noexcept;
4343
static DebugInfoSelection const None() noexcept { return All(false); }
4444
static DebugInfoSelection const Only(bool DebugInfoSelection::* _member) noexcept;
45-
static DebugInfoSelection const Default() noexcept { return All(); }
45+
static DebugInfoSelection const Default() noexcept { return AllExceptExperimental(); }
46+
static DebugInfoSelection const AllExcept(std::vector<bool DebugInfoSelection::*> const& _members) noexcept;
47+
static DebugInfoSelection const AllExceptExperimental() noexcept { return AllExcept({&DebugInfoSelection::ethdebug}); }
4648

4749
static std::optional<DebugInfoSelection> fromString(std::string_view _input);
4850
static std::optional<DebugInfoSelection> fromComponents(
@@ -72,13 +74,24 @@ struct DebugInfoSelection
7274
{"location", &DebugInfoSelection::location},
7375
{"snippet", &DebugInfoSelection::snippet},
7476
{"ast-id", &DebugInfoSelection::astID},
77+
{"ethdebug", &DebugInfoSelection::ethdebug},
7578
};
7679
return components;
7780
}
7881

82+
std::vector<std::string> selectedNames() const
83+
{
84+
std::vector<std::string> result;
85+
for (auto const& component: componentMap())
86+
if (this->*(component.second))
87+
result.push_back(component.first);
88+
return result;
89+
}
90+
7991
bool location = false; ///< Include source location. E.g. `@src 3:50:100`
8092
bool snippet = false; ///< Include source code snippet next to location. E.g. `@src 3:50:100 "contract C {..."`
8193
bool astID = false; ///< Include ID of the Solidity AST node. E.g. `@ast-id 15`
94+
bool ethdebug = false; ///< Include ethdebug related debug information.
8295
};
8396

8497
std::ostream& operator<<(std::ostream& _stream, DebugInfoSelection const& _selection);

libsolidity/codegen/ir/IRGenerator.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ std::string IRGenerator::generate(
120120
);
121121
};
122122

123-
Whiskers t(R"(
123+
Whiskers t(R"(<?isEthdebugEnabled>/// ethdebug: enabled</isEthdebugEnabled>
124124
/// @use-src <useSrcMapCreation>
125125
object "<CreationObject>" {
126126
code {
@@ -164,6 +164,7 @@ std::string IRGenerator::generate(
164164
for (VariableDeclaration const* var: ContractType(_contract).immutableVariables())
165165
m_context.registerImmutableVariable(*var);
166166

167+
t("isEthdebugEnabled", m_context.debugInfoSelection().ethdebug);
167168
t("CreationObject", IRNames::creationObject(_contract));
168169
t("sourceLocationCommentCreation", dispenseLocationComment(_contract));
169170
t("library", _contract.isLibrary());

libsolidity/interface/CompilerStack.cpp

+33
Original file line numberDiff line numberDiff line change
@@ -1181,6 +1181,39 @@ Json CompilerStack::interfaceSymbols(std::string const& _contractName) const
11811181
return interfaceSymbols;
11821182
}
11831183

1184+
Json CompilerStack::ethdebug() const
1185+
{
1186+
solAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful.");
1187+
solAssert(!m_contracts.empty());
1188+
Json result = Json::object();
1189+
result["sources"] = sourceNames();
1190+
return result;
1191+
}
1192+
1193+
Json CompilerStack::ethdebug(std::string const& _contractName) const
1194+
{
1195+
return ethdebug(contract(_contractName), /* runtime */ false);
1196+
}
1197+
1198+
Json CompilerStack::ethdebugRuntime(std::string const& _contractName) const
1199+
{
1200+
return ethdebug(contract(_contractName), /* runtime */ true);
1201+
}
1202+
1203+
Json CompilerStack::ethdebug(Contract const& _contract, bool _runtime) const
1204+
{
1205+
solAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful.");
1206+
solAssert(_contract.contract);
1207+
solUnimplementedAssert(!isExperimentalSolidity());
1208+
if (_runtime)
1209+
{
1210+
Json result = Json::object();
1211+
return result;
1212+
}
1213+
Json result = Json::object();
1214+
return result;
1215+
}
1216+
11841217
bytes CompilerStack::cborMetadata(std::string const& _contractName, bool _forIR) const
11851218
{
11861219
solAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful.");

libsolidity/interface/CompilerStack.h

+17
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,18 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac
391391
/// @returns a JSON object with the three members ``methods``, ``events``, ``errors``. Each is a map, mapping identifiers (hashes) to function names.
392392
Json interfaceSymbols(std::string const& _contractName) const;
393393

394+
/// @returns a JSON representing the ethdebug data of the specified contract.
395+
/// Prerequisite: Successful call to parse or compile.
396+
Json ethdebug(std::string const& _contractName) const override;
397+
398+
/// @returns a JSON representing the ethdebug data of the specified contract.
399+
/// Prerequisite: Successful call to parse or compile.
400+
Json ethdebugRuntime(std::string const& _contractName) const override;
401+
402+
/// @returns a JSON representing the top-level ethdebug data (types, etc.).
403+
/// Prerequisite: Successful call to parse or compile.
404+
Json ethdebug() const override;
405+
394406
/// @returns the Contract Metadata matching the pipeline selected using the viaIR setting.
395407
std::string const& metadata(std::string const& _contractName) const { return metadata(contract(_contractName)); }
396408

@@ -571,6 +583,11 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac
571583
/// This will generate the metadata and store it in the Contract object if it is not present yet.
572584
std::string const& metadata(Contract const& _contract) const;
573585

586+
/// @returns the Contract ethdebug data.
587+
/// This will generate the JSON object and store it in the Contract object if it is not present yet.
588+
/// Prerequisite: Successful call to parse or compile.
589+
Json ethdebug(Contract const& _contract, bool _runtime) const;
590+
574591
/// @returns the offset of the entry point of the given function into the list of assembly items
575592
/// or zero if it is not found or does not exist.
576593
size_t functionEntryPoint(

0 commit comments

Comments
 (0)