mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #11944 from ethereum/debug-info-selection
Debug info selection
This commit is contained in:
commit
adc58c67b4
@ -6,8 +6,10 @@ Language Features:
|
||||
|
||||
Compiler Features:
|
||||
* Commandline Interface: Accept nested brackets in step sequences passed to ``--yul-optimizations``.
|
||||
* Commandline Interface: Add ``--debug-info`` option for selecting how much extra debug information should be included in the produced EVM assembly and Yul code.
|
||||
* SMTChecker: Output values for ``block.*``, ``msg.*`` and ``tx.*`` variables that are present in the called functions.
|
||||
* Standard JSON: Accept nested brackets in step sequences passed to ``settings.optimizer.details.yulDetails.optimizerSteps``.
|
||||
* Standard JSON: Add ``settings.debug.debugInfo`` option for selecting how much extra debug information should be included in the produced EVM assembly and Yul code.
|
||||
|
||||
|
||||
Bugfixes:
|
||||
|
@ -308,7 +308,18 @@ Input Description
|
||||
// "strip" removes all revert strings (if possible, i.e. if literals are used) keeping side-effects
|
||||
// "debug" injects strings for compiler-generated internal reverts, implemented for ABI encoders V1 and V2 for now.
|
||||
// "verboseDebug" even appends further information to user-supplied revert strings (not yet implemented)
|
||||
"revertStrings": "default"
|
||||
"revertStrings": "default",
|
||||
// Optional: How much extra debug information to include in comments in the produced EVM
|
||||
// assembly and Yul code. Available components are:
|
||||
// - `location`: Annotations of the form `@src <index>:<start>:<end>` indicating the
|
||||
// location of the corresponding element in the original Solidity file, where:
|
||||
// - `<index>` is the file index matching the `@use-src` annotation,
|
||||
// - `<start>` is the index of the first byte at that location,
|
||||
// - `<end>` is the index of the first byte after that location.
|
||||
// - `snippet`: A single-line code snippet from the location indicated by `@src`.
|
||||
// The snippet is quoted and follows the corresponding `@src` annotation.
|
||||
// - `*`: Wildcard value that can be used to request everything.
|
||||
"debugInfo": ["location", "snippet"]
|
||||
},
|
||||
// Metadata settings (optional)
|
||||
"metadata": {
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <libevmasm/LinkerObject.h>
|
||||
#include <libevmasm/Exceptions.h>
|
||||
|
||||
#include <liblangutil/DebugInfoSelection.h>
|
||||
#include <liblangutil/EVMVersion.h>
|
||||
|
||||
#include <libsolutil/Common.h>
|
||||
@ -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;
|
||||
|
@ -3,6 +3,8 @@ set(sources
|
||||
Common.h
|
||||
CharStream.cpp
|
||||
CharStream.h
|
||||
DebugInfoSelection.cpp
|
||||
DebugInfoSelection.h
|
||||
ErrorReporter.cpp
|
||||
ErrorReporter.h
|
||||
EVMVersion.h
|
||||
|
157
liblangutil/DebugInfoSelection.cpp
Normal file
157
liblangutil/DebugInfoSelection.cpp
Normal file
@ -0,0 +1,157 @@
|
||||
/*
|
||||
This file is part of solidity.
|
||||
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
|
||||
#include <liblangutil/DebugInfoSelection.h>
|
||||
|
||||
#include <liblangutil/Exceptions.h>
|
||||
|
||||
#include <libsolutil/StringUtils.h>
|
||||
|
||||
#include <boost/algorithm/string/trim.hpp>
|
||||
|
||||
#include <range/v3/range/conversion.hpp>
|
||||
#include <range/v3/view/map.hpp>
|
||||
#include <range/v3/view/split.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
using namespace solidity;
|
||||
using namespace solidity::langutil;
|
||||
using namespace solidity::util;
|
||||
|
||||
DebugInfoSelection const DebugInfoSelection::All(bool _value) noexcept
|
||||
{
|
||||
DebugInfoSelection result;
|
||||
for (bool DebugInfoSelection::* member: componentMap() | ranges::views::values)
|
||||
result.*member = _value;
|
||||
return result;
|
||||
}
|
||||
|
||||
DebugInfoSelection const DebugInfoSelection::Only(bool DebugInfoSelection::* _member) noexcept
|
||||
{
|
||||
DebugInfoSelection result{};
|
||||
result.*_member = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
optional<DebugInfoSelection> DebugInfoSelection::fromString(string_view _input)
|
||||
{
|
||||
// TODO: Make more stuff constexpr and make it a static_assert().
|
||||
solAssert(componentMap().count("all") == 0, "");
|
||||
solAssert(componentMap().count("none") == 0, "");
|
||||
|
||||
if (_input == "all")
|
||||
return All();
|
||||
if (_input == "none")
|
||||
return None();
|
||||
|
||||
return fromComponents(_input | ranges::views::split(',') | ranges::to<vector<string>>);
|
||||
}
|
||||
|
||||
optional<DebugInfoSelection> DebugInfoSelection::fromComponents(
|
||||
vector<string> const& _componentNames,
|
||||
bool _acceptWildcards
|
||||
)
|
||||
{
|
||||
solAssert(componentMap().count("*") == 0, "");
|
||||
|
||||
DebugInfoSelection selection;
|
||||
for (auto const& component: _componentNames)
|
||||
{
|
||||
if (component == "*")
|
||||
return (_acceptWildcards ? make_optional(DebugInfoSelection::All()) : nullopt);
|
||||
|
||||
if (!selection.enable(component))
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
return selection;
|
||||
}
|
||||
|
||||
bool DebugInfoSelection::enable(string _component)
|
||||
{
|
||||
auto memberIt = componentMap().find(boost::trim_copy(_component));
|
||||
if (memberIt == componentMap().end())
|
||||
return false;
|
||||
|
||||
this->*(memberIt->second) = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DebugInfoSelection::any() const noexcept
|
||||
{
|
||||
for (bool DebugInfoSelection::* member: componentMap() | ranges::views::values)
|
||||
if (this->*member)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DebugInfoSelection::all() const noexcept
|
||||
{
|
||||
for (bool DebugInfoSelection::* member: componentMap() | ranges::views::values)
|
||||
if (!(this->*member))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
DebugInfoSelection& DebugInfoSelection::operator&=(DebugInfoSelection const& _other)
|
||||
{
|
||||
for (bool DebugInfoSelection::* member: componentMap() | ranges::views::values)
|
||||
this->*member &= _other.*member;
|
||||
return *this;
|
||||
}
|
||||
|
||||
DebugInfoSelection& DebugInfoSelection::operator|=(DebugInfoSelection const& _other)
|
||||
{
|
||||
for (bool DebugInfoSelection::* member: componentMap() | ranges::views::values)
|
||||
this->*member |= _other.*member;
|
||||
return *this;
|
||||
}
|
||||
|
||||
DebugInfoSelection DebugInfoSelection::operator&(DebugInfoSelection _other) const noexcept
|
||||
{
|
||||
_other &= *this;
|
||||
return _other;
|
||||
}
|
||||
|
||||
DebugInfoSelection DebugInfoSelection::operator|(DebugInfoSelection _other) const noexcept
|
||||
{
|
||||
_other |= *this;
|
||||
return _other;
|
||||
}
|
||||
|
||||
bool DebugInfoSelection::operator==(DebugInfoSelection const& _other) const noexcept
|
||||
{
|
||||
for (bool DebugInfoSelection::* member: componentMap() | ranges::views::values)
|
||||
if (this->*member != _other.*member)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
ostream& langutil::operator<<(ostream& _stream, DebugInfoSelection const& _selection)
|
||||
{
|
||||
vector<string> selectedComponentNames;
|
||||
for (auto const& [name, member]: _selection.componentMap())
|
||||
if (_selection.*member)
|
||||
selectedComponentNames.push_back(name);
|
||||
|
||||
return _stream << joinHumanReadable(selectedComponentNames, ",");
|
||||
}
|
86
liblangutil/DebugInfoSelection.h
Normal file
86
liblangutil/DebugInfoSelection.h
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
This file is part of solidity.
|
||||
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
/**
|
||||
* Handles selections of debug info components.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
namespace solidity::langutil
|
||||
{
|
||||
|
||||
/**
|
||||
* Represents a set of flags corresponding to components of debug info selected for some purpose.
|
||||
*
|
||||
* Provides extra functionality for enumerating the components and serializing/deserializing the
|
||||
* selection to/from a comma-separated string.
|
||||
*/
|
||||
struct DebugInfoSelection
|
||||
{
|
||||
static DebugInfoSelection const All(bool _value = true) noexcept;
|
||||
static DebugInfoSelection const None() noexcept { return All(false); }
|
||||
static DebugInfoSelection const Only(bool DebugInfoSelection::* _member) noexcept;
|
||||
static DebugInfoSelection const Default() noexcept { return All(); }
|
||||
|
||||
static std::optional<DebugInfoSelection> fromString(std::string_view _input);
|
||||
static std::optional<DebugInfoSelection> fromComponents(
|
||||
std::vector<std::string> const& _componentNames,
|
||||
bool _acceptWildcards = false
|
||||
);
|
||||
bool enable(std::string _component);
|
||||
|
||||
bool all() const noexcept;
|
||||
bool any() const noexcept;
|
||||
bool none() const noexcept { return !any(); }
|
||||
bool only(bool DebugInfoSelection::* _member) const noexcept { return *this == Only(_member); }
|
||||
|
||||
DebugInfoSelection& operator&=(DebugInfoSelection const& _other);
|
||||
DebugInfoSelection& operator|=(DebugInfoSelection const& _other);
|
||||
DebugInfoSelection operator&(DebugInfoSelection _other) const noexcept;
|
||||
DebugInfoSelection operator|(DebugInfoSelection _other) const noexcept;
|
||||
|
||||
bool operator!=(DebugInfoSelection const& _other) const noexcept { return !(*this == _other); }
|
||||
bool operator==(DebugInfoSelection const& _other) const noexcept;
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& _stream, DebugInfoSelection const& _selection);
|
||||
|
||||
static auto const& componentMap()
|
||||
{
|
||||
static std::map<std::string, bool DebugInfoSelection::*> const components = {
|
||||
{"location", &DebugInfoSelection::location},
|
||||
{"snippet", &DebugInfoSelection::snippet},
|
||||
{"ast-id", &DebugInfoSelection::astID},
|
||||
};
|
||||
return components;
|
||||
}
|
||||
|
||||
bool location = false; ///< Include source location. E.g. `@src 3:50:100`
|
||||
bool snippet = false; ///< Include source code snippet next to location. E.g. `@src 3:50:100 "contract C {..."`
|
||||
bool astID = false; ///< Include ID of the Solidity AST node. E.g. `@ast-id 15`
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& _stream, DebugInfoSelection const& _selection);
|
||||
|
||||
}
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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())
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -261,10 +261,16 @@ string AsmPrinter::appendTypeName(YulString _type, bool _isBoolLiteral) const
|
||||
string AsmPrinter::formatSourceLocation(
|
||||
SourceLocation const& _location,
|
||||
map<string, unsigned> 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,13 @@ string AsmPrinter::formatSourceLocation(
|
||||
|
||||
string AsmPrinter::formatDebugData(shared_ptr<DebugData const> const& _debugData, bool _statement)
|
||||
{
|
||||
if (!_debugData)
|
||||
if (!_debugData || m_debugInfoSelection.none())
|
||||
return "";
|
||||
|
||||
vector<string> items;
|
||||
if (auto id = _debugData->astID)
|
||||
items.emplace_back("@ast-id " + to_string(*id));
|
||||
if (m_debugInfoSelection.astID)
|
||||
items.emplace_back("@ast-id " + to_string(*id));
|
||||
|
||||
if (
|
||||
m_lastLocation != _debugData->originLocation &&
|
||||
@ -315,6 +322,7 @@ string AsmPrinter::formatDebugData(shared_ptr<DebugData const> const& _debugData
|
||||
items.emplace_back(formatSourceLocation(
|
||||
_debugData->originLocation,
|
||||
m_nameToSourceIndex,
|
||||
m_debugInfoSelection,
|
||||
m_soliditySourceProvider
|
||||
));
|
||||
}
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <libsolutil/CommonData.h>
|
||||
|
||||
#include <liblangutil/CharStreamProvider.h>
|
||||
#include <liblangutil/DebugInfoSelection.h>
|
||||
#include <liblangutil/SourceLocation.h>
|
||||
|
||||
#include <map>
|
||||
@ -48,9 +49,11 @@ public:
|
||||
explicit AsmPrinter(
|
||||
Dialect const* _dialect = nullptr,
|
||||
std::optional<std::map<unsigned, std::shared_ptr<std::string const>>> _sourceIndexToName = {},
|
||||
langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(),
|
||||
langutil::CharStreamProvider const* _soliditySourceProvider = nullptr
|
||||
):
|
||||
m_dialect(_dialect),
|
||||
m_debugInfoSelection(_debugInfoSelection),
|
||||
m_soliditySourceProvider(_soliditySourceProvider)
|
||||
{
|
||||
if (_sourceIndexToName)
|
||||
@ -58,12 +61,12 @@ public:
|
||||
m_nameToSourceIndex[*name] = index;
|
||||
}
|
||||
|
||||
|
||||
explicit AsmPrinter(
|
||||
Dialect const& _dialect,
|
||||
std::optional<std::map<unsigned, std::shared_ptr<std::string const>>> _sourceIndexToName = {},
|
||||
langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(),
|
||||
langutil::CharStreamProvider const* _soliditySourceProvider = nullptr
|
||||
): AsmPrinter(&_dialect, _sourceIndexToName, _soliditySourceProvider) {}
|
||||
): AsmPrinter(&_dialect, _sourceIndexToName, _debugInfoSelection, _soliditySourceProvider) {}
|
||||
|
||||
std::string operator()(Literal const& _literal);
|
||||
std::string operator()(Identifier const& _identifier);
|
||||
@ -83,6 +86,7 @@ public:
|
||||
static std::string formatSourceLocation(
|
||||
langutil::SourceLocation const& _location,
|
||||
std::map<std::string, unsigned> const& _nameToSourceIndex,
|
||||
langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(),
|
||||
langutil::CharStreamProvider const* m_soliditySourceProvider = nullptr
|
||||
);
|
||||
|
||||
@ -100,6 +104,7 @@ private:
|
||||
Dialect const* const m_dialect = nullptr;
|
||||
std::map<std::string, unsigned> m_nameToSourceIndex;
|
||||
langutil::SourceLocation m_lastLocation = {};
|
||||
langutil::DebugInfoSelection m_debugInfoSelection = {};
|
||||
langutil::CharStreamProvider const* m_soliditySourceProvider = nullptr;
|
||||
};
|
||||
|
||||
|
@ -249,7 +249,7 @@ AssemblyStack::assembleWithDeployed(optional<string_view> _deployName) const
|
||||
MachineAssemblyObject creationObject;
|
||||
creationObject.bytecode = make_shared<evmasm::LinkerObject>(creationAssembly->assemble());
|
||||
yulAssert(creationObject.bytecode->immutableReferences.empty(), "Leftover immutables.");
|
||||
creationObject.assembly = creationAssembly->assemblyString();
|
||||
creationObject.assembly = creationAssembly->assemblyString(m_debugInfoSelection);
|
||||
creationObject.sourceMappings = make_unique<string>(
|
||||
evmasm::AssemblyItem::computeSourceMapping(
|
||||
creationAssembly->items(),
|
||||
@ -261,7 +261,7 @@ AssemblyStack::assembleWithDeployed(optional<string_view> _deployName) const
|
||||
if (deployedAssembly)
|
||||
{
|
||||
deployedObject.bytecode = make_shared<evmasm::LinkerObject>(deployedAssembly->assemble());
|
||||
deployedObject.assembly = deployedAssembly->assemblyString();
|
||||
deployedObject.assembly = deployedAssembly->assemblyString(m_debugInfoSelection);
|
||||
deployedObject.sourceMappings = make_unique<string>(
|
||||
evmasm::AssemblyItem::computeSourceMapping(
|
||||
deployedAssembly->items(),
|
||||
@ -314,11 +314,13 @@ AssemblyStack::assembleEVMWithDeployed(optional<string_view> _deployName) const
|
||||
return {make_shared<evmasm::Assembly>(assembly), {}};
|
||||
}
|
||||
|
||||
string AssemblyStack::print(CharStreamProvider const* _soliditySourceProvider) const
|
||||
string AssemblyStack::print(
|
||||
CharStreamProvider const* _soliditySourceProvider
|
||||
) const
|
||||
{
|
||||
yulAssert(m_parserResult, "");
|
||||
yulAssert(m_parserResult->code, "");
|
||||
return m_parserResult->toString(&languageToDialect(m_language, m_evmVersion), _soliditySourceProvider) + "\n";
|
||||
return m_parserResult->toString(&languageToDialect(m_language, m_evmVersion), m_debugInfoSelection, _soliditySourceProvider) + "\n";
|
||||
}
|
||||
|
||||
shared_ptr<Object> AssemblyStack::parserResult() const
|
||||
|
@ -22,9 +22,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <liblangutil/CharStreamProvider.h>
|
||||
#include <liblangutil/DebugInfoSelection.h>
|
||||
#include <liblangutil/ErrorReporter.h>
|
||||
#include <liblangutil/EVMVersion.h>
|
||||
#include <liblangutil/CharStreamProvider.h>
|
||||
|
||||
#include <libyul/Object.h>
|
||||
#include <libyul/ObjectParser.h>
|
||||
@ -69,12 +70,24 @@ public:
|
||||
enum class Machine { EVM, Ewasm };
|
||||
|
||||
AssemblyStack():
|
||||
AssemblyStack(langutil::EVMVersion{}, Language::Assembly, solidity::frontend::OptimiserSettings::none())
|
||||
AssemblyStack(
|
||||
langutil::EVMVersion{},
|
||||
Language::Assembly,
|
||||
solidity::frontend::OptimiserSettings::none(),
|
||||
langutil::DebugInfoSelection::Default()
|
||||
)
|
||||
{}
|
||||
AssemblyStack(langutil::EVMVersion _evmVersion, Language _language, solidity::frontend::OptimiserSettings _optimiserSettings):
|
||||
|
||||
AssemblyStack(
|
||||
langutil::EVMVersion _evmVersion,
|
||||
Language _language,
|
||||
solidity::frontend::OptimiserSettings _optimiserSettings,
|
||||
langutil::DebugInfoSelection const& _debugInfoSelection
|
||||
):
|
||||
m_language(_language),
|
||||
m_evmVersion(_evmVersion),
|
||||
m_optimiserSettings(std::move(_optimiserSettings)),
|
||||
m_debugInfoSelection(_debugInfoSelection),
|
||||
m_errorReporter(m_errors)
|
||||
{}
|
||||
|
||||
@ -116,7 +129,9 @@ public:
|
||||
langutil::ErrorList const& errors() const { return m_errors; }
|
||||
|
||||
/// Pretty-print the input after having parsed it.
|
||||
std::string print(langutil::CharStreamProvider const* _soliditySourceProvider = nullptr) const;
|
||||
std::string print(
|
||||
langutil::CharStreamProvider const* _soliditySourceProvider = nullptr
|
||||
) const;
|
||||
|
||||
/// Return the parsed and analyzed object.
|
||||
std::shared_ptr<Object> parserResult() const;
|
||||
@ -132,6 +147,7 @@ private:
|
||||
Language m_language = Language::Assembly;
|
||||
langutil::EVMVersion m_evmVersion;
|
||||
solidity::frontend::OptimiserSettings m_optimiserSettings;
|
||||
langutil::DebugInfoSelection m_debugInfoSelection{};
|
||||
|
||||
std::unique_ptr<langutil::CharStream> m_charStream;
|
||||
|
||||
|
@ -51,13 +51,14 @@ string indent(std::string const& _input)
|
||||
|
||||
}
|
||||
|
||||
string Data::toString(Dialect const*, CharStreamProvider const*) const
|
||||
string Data::toString(Dialect const*, DebugInfoSelection const&, CharStreamProvider const*) const
|
||||
{
|
||||
return "data \"" + name.str() + "\" hex\"" + util::toHex(data) + "\"";
|
||||
}
|
||||
|
||||
string Object::toString(
|
||||
Dialect const* _dialect,
|
||||
DebugInfoSelection const& _debugInfoSelection,
|
||||
CharStreamProvider const* _soliditySourceProvider
|
||||
) const
|
||||
{
|
||||
@ -74,10 +75,15 @@ string Object::toString(
|
||||
})) +
|
||||
"\n";
|
||||
|
||||
string inner = "code " + AsmPrinter{_dialect, debugData->sourceNames, _soliditySourceProvider}(*code);
|
||||
string inner = "code " + AsmPrinter(
|
||||
_dialect,
|
||||
debugData->sourceNames,
|
||||
_debugInfoSelection,
|
||||
_soliditySourceProvider
|
||||
)(*code);
|
||||
|
||||
for (auto const& obj: subObjects)
|
||||
inner += "\n" + obj->toString(_dialect, _soliditySourceProvider);
|
||||
inner += "\n" + obj->toString(_dialect, _debugInfoSelection, _soliditySourceProvider);
|
||||
|
||||
return useSrcComment + "object \"" + name.str() + "\" {\n" + indent(inner) + "\n}";
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <libyul/YulString.h>
|
||||
|
||||
#include <liblangutil/CharStreamProvider.h>
|
||||
#include <liblangutil/DebugInfoSelection.h>
|
||||
|
||||
#include <libsolutil/Common.h>
|
||||
|
||||
@ -54,6 +55,7 @@ struct ObjectNode
|
||||
YulString name;
|
||||
virtual std::string toString(
|
||||
Dialect const* _dialect,
|
||||
langutil::DebugInfoSelection const& _debugInfoSelection,
|
||||
langutil::CharStreamProvider const* _soliditySourceProvider
|
||||
) const = 0;
|
||||
};
|
||||
@ -69,6 +71,7 @@ struct Data: public ObjectNode
|
||||
|
||||
std::string toString(
|
||||
Dialect const* _dialect,
|
||||
langutil::DebugInfoSelection const& _debugInfoSelection,
|
||||
langutil::CharStreamProvider const* _soliditySourceProvider
|
||||
) const override;
|
||||
};
|
||||
@ -89,6 +92,7 @@ public:
|
||||
/// @returns a (parseable) string representation.
|
||||
std::string toString(
|
||||
Dialect const* _dialect,
|
||||
langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(),
|
||||
langutil::CharStreamProvider const* _soliditySourceProvider = nullptr
|
||||
) const;
|
||||
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include <libyul/AST.h>
|
||||
#include <libyul/Exceptions.h>
|
||||
#include <libyul/Utilities.h>
|
||||
#include <libyul/AsmPrinter.h>
|
||||
|
||||
#include <libsolutil/cxx20.h>
|
||||
#include <libsolutil/Visitor.h>
|
||||
|
@ -631,6 +631,8 @@ bool CommandLineInterface::compile()
|
||||
m_compiler->setViaIR(m_options.output.experimentalViaIR);
|
||||
m_compiler->setEVMVersion(m_options.output.evmVersion);
|
||||
m_compiler->setRevertStringBehaviour(m_options.output.revertStrings);
|
||||
if (m_options.output.debugInfoSelection.has_value())
|
||||
m_compiler->selectDebugInfo(m_options.output.debugInfoSelection.value());
|
||||
// TODO: Perhaps we should not compile unless requested
|
||||
|
||||
m_compiler->enableIRGeneration(m_options.compiler.outputs.ir || m_options.compiler.outputs.irOptimized);
|
||||
@ -972,7 +974,10 @@ bool CommandLineInterface::assemble(yul::AssemblyStack::Language _language, yul:
|
||||
auto& stack = assemblyStacks[src.first] = yul::AssemblyStack(
|
||||
m_options.output.evmVersion,
|
||||
_language,
|
||||
m_options.optimiserSettings()
|
||||
m_options.optimiserSettings(),
|
||||
m_options.output.debugInfoSelection.has_value() ?
|
||||
m_options.output.debugInfoSelection.value() :
|
||||
DebugInfoSelection::Default()
|
||||
);
|
||||
|
||||
if (!stack.parseAndAnalyze(src.first, src.second))
|
||||
|
@ -67,6 +67,7 @@ static string const g_strImportAst = "import-ast";
|
||||
static string const g_strInputFile = "input-file";
|
||||
static string const g_strYul = "yul";
|
||||
static string const g_strYulDialect = "yul-dialect";
|
||||
static string const g_strDebugInfo = "debug-info";
|
||||
static string const g_strIPFS = "ipfs";
|
||||
static string const g_strLicense = "license";
|
||||
static string const g_strLibraries = "libraries";
|
||||
@ -252,6 +253,7 @@ bool CommandLineOptions::operator==(CommandLineOptions const& _other) const noex
|
||||
output.evmVersion == _other.output.evmVersion &&
|
||||
output.experimentalViaIR == _other.output.experimentalViaIR &&
|
||||
output.revertStrings == _other.output.revertStrings &&
|
||||
output.debugInfoSelection == _other.output.debugInfoSelection &&
|
||||
output.stopAfter == _other.output.stopAfter &&
|
||||
input.mode == _other.input.mode &&
|
||||
assembly.targetMachine == _other.assembly.targetMachine &&
|
||||
@ -595,6 +597,13 @@ General Information)").c_str(),
|
||||
po::value<string>()->value_name(joinHumanReadable(g_revertStringsArgs, ",")),
|
||||
"Strip revert (and require) reason strings or add additional debugging information."
|
||||
)
|
||||
(
|
||||
g_strDebugInfo.c_str(),
|
||||
po::value<string>()->default_value(toString(DebugInfoSelection::Default())),
|
||||
("Debug info components to be included in the produced EVM assembly and Yul code. "
|
||||
"Value can be all, none or a comma-separated list containing one or more of the "
|
||||
"following components: " + joinHumanReadable(DebugInfoSelection::componentMap() | ranges::views::keys) + ".").c_str()
|
||||
)
|
||||
(
|
||||
g_strStopAfter.c_str(),
|
||||
po::value<string>()->value_name("stage"),
|
||||
@ -935,6 +944,12 @@ bool CommandLineParser::processArgs()
|
||||
serr() << "Option --" << option << " is only valid in compiler and assembler modes." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_args[g_strDebugInfo].defaulted())
|
||||
{
|
||||
serr() << "Option --" << g_strDebugInfo << " is only valid in compiler and assembler modes." << endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_args.count(g_strColor) > 0)
|
||||
@ -961,6 +976,23 @@ bool CommandLineParser::processArgs()
|
||||
m_options.output.revertStrings = *revertStrings;
|
||||
}
|
||||
|
||||
if (!m_args[g_strDebugInfo].defaulted())
|
||||
{
|
||||
string optionValue = m_args[g_strDebugInfo].as<string>();
|
||||
m_options.output.debugInfoSelection = DebugInfoSelection::fromString(optionValue);
|
||||
if (!m_options.output.debugInfoSelection.has_value())
|
||||
{
|
||||
serr() << "Invalid value for --" << g_strDebugInfo << " option: " << optionValue << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_options.output.debugInfoSelection->snippet && !m_options.output.debugInfoSelection->location)
|
||||
{
|
||||
serr() << "To use 'snippet' with --" << g_strDebugInfo << " you must select also 'location'." << endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!parseCombinedJsonOption())
|
||||
return false;
|
||||
|
||||
|
@ -24,8 +24,12 @@
|
||||
#include <libsolidity/interface/DebugSettings.h>
|
||||
#include <libsolidity/interface/FileReader.h>
|
||||
#include <libsolidity/interface/ImportRemapper.h>
|
||||
|
||||
#include <libyul/AssemblyStack.h>
|
||||
|
||||
#include <liblangutil/DebugInfoSelection.h>
|
||||
#include <liblangutil/EVMVersion.h>
|
||||
|
||||
#include <libsolutil/JSON.h>
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
@ -174,6 +178,7 @@ struct CommandLineOptions
|
||||
langutil::EVMVersion evmVersion;
|
||||
bool experimentalViaIR = false;
|
||||
RevertStrings revertStrings = RevertStrings::Default;
|
||||
std::optional<langutil::DebugInfoSelection> debugInfoSelection;
|
||||
CompilerStack::State stopAfter = CompilerStack::State::CompilationSuccessful;
|
||||
} output;
|
||||
|
||||
|
@ -0,0 +1 @@
|
||||
--ir --ir-optimized --asm --optimize --debug-info all
|
@ -0,0 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
pragma solidity >=0.0;
|
||||
|
||||
contract C {
|
||||
function f() public {}
|
||||
}
|
213
test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_all/output
Normal file
213
test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_all/output
Normal file
@ -0,0 +1,213 @@
|
||||
|
||||
======= debug_info_in_yul_and_evm_asm_print_all/input.sol:C =======
|
||||
EVM assembly:
|
||||
/* "debug_info_in_yul_and_evm_asm_print_all/input.sol":60:101 contract C {... */
|
||||
mstore(0x40, 0x80)
|
||||
callvalue
|
||||
dup1
|
||||
iszero
|
||||
tag_1
|
||||
jumpi
|
||||
0x00
|
||||
dup1
|
||||
revert
|
||||
tag_1:
|
||||
pop
|
||||
dataSize(sub_0)
|
||||
dup1
|
||||
dataOffset(sub_0)
|
||||
0x00
|
||||
codecopy
|
||||
0x00
|
||||
return
|
||||
stop
|
||||
|
||||
sub_0: assembly {
|
||||
/* "debug_info_in_yul_and_evm_asm_print_all/input.sol":60:101 contract C {... */
|
||||
mstore(0x40, 0x80)
|
||||
callvalue
|
||||
dup1
|
||||
iszero
|
||||
tag_1
|
||||
jumpi
|
||||
0x00
|
||||
dup1
|
||||
revert
|
||||
tag_1:
|
||||
pop
|
||||
jumpi(tag_2, lt(calldatasize, 0x04))
|
||||
shr(0xe0, calldataload(0x00))
|
||||
dup1
|
||||
0x26121ff0
|
||||
eq
|
||||
tag_3
|
||||
jumpi
|
||||
tag_2:
|
||||
0x00
|
||||
dup1
|
||||
revert
|
||||
/* "debug_info_in_yul_and_evm_asm_print_all/input.sol":77:99 function f() public {} */
|
||||
tag_3:
|
||||
stop
|
||||
|
||||
auxdata: <AUXDATA REMOVED>
|
||||
}
|
||||
|
||||
IR:
|
||||
/*=====================================================*
|
||||
* WARNING *
|
||||
* Solidity to Yul compilation is still EXPERIMENTAL *
|
||||
* It can result in LOSS OF FUNDS or worse *
|
||||
* !USE AT YOUR OWN RISK! *
|
||||
*=====================================================*/
|
||||
|
||||
|
||||
/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_all/input.sol"
|
||||
object "C_6" {
|
||||
code {
|
||||
/// @src 0:60:101 "contract C {..."
|
||||
mstore(64, 128)
|
||||
if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }
|
||||
|
||||
constructor_C_6()
|
||||
|
||||
let _1 := allocate_unbounded()
|
||||
codecopy(_1, dataoffset("C_6_deployed"), datasize("C_6_deployed"))
|
||||
|
||||
return(_1, datasize("C_6_deployed"))
|
||||
|
||||
function allocate_unbounded() -> memPtr {
|
||||
memPtr := mload(64)
|
||||
}
|
||||
|
||||
function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {
|
||||
revert(0, 0)
|
||||
}
|
||||
|
||||
/// @src 0:60:101 "contract C {..."
|
||||
function constructor_C_6() {
|
||||
|
||||
/// @src 0:60:101 "contract C {..."
|
||||
|
||||
}
|
||||
/// @src 0:60:101 "contract C {..."
|
||||
|
||||
}
|
||||
/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_all/input.sol"
|
||||
object "C_6_deployed" {
|
||||
code {
|
||||
/// @src 0:60:101 "contract C {..."
|
||||
mstore(64, 128)
|
||||
|
||||
if iszero(lt(calldatasize(), 4))
|
||||
{
|
||||
let selector := shift_right_224_unsigned(calldataload(0))
|
||||
switch selector
|
||||
|
||||
case 0x26121ff0
|
||||
{
|
||||
// f()
|
||||
|
||||
if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }
|
||||
abi_decode_tuple_(4, calldatasize())
|
||||
fun_f_5()
|
||||
let memPos := allocate_unbounded()
|
||||
let memEnd := abi_encode_tuple__to__fromStack(memPos )
|
||||
return(memPos, sub(memEnd, memPos))
|
||||
}
|
||||
|
||||
default {}
|
||||
}
|
||||
if iszero(calldatasize()) { }
|
||||
revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()
|
||||
|
||||
function shift_right_224_unsigned(value) -> newValue {
|
||||
newValue :=
|
||||
|
||||
shr(224, value)
|
||||
|
||||
}
|
||||
|
||||
function allocate_unbounded() -> memPtr {
|
||||
memPtr := mload(64)
|
||||
}
|
||||
|
||||
function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {
|
||||
revert(0, 0)
|
||||
}
|
||||
|
||||
function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {
|
||||
revert(0, 0)
|
||||
}
|
||||
|
||||
function abi_decode_tuple_(headStart, dataEnd) {
|
||||
if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }
|
||||
|
||||
}
|
||||
|
||||
function abi_encode_tuple__to__fromStack(headStart ) -> tail {
|
||||
tail := add(headStart, 0)
|
||||
|
||||
}
|
||||
|
||||
function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {
|
||||
revert(0, 0)
|
||||
}
|
||||
|
||||
/// @ast-id 5
|
||||
/// @src 0:77:99 "function f() public {}"
|
||||
function fun_f_5() {
|
||||
|
||||
}
|
||||
/// @src 0:60:101 "contract C {..."
|
||||
|
||||
}
|
||||
|
||||
data ".metadata" hex"<BYTECODE REMOVED>"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Optimized IR:
|
||||
/*=====================================================*
|
||||
* WARNING *
|
||||
* Solidity to Yul compilation is still EXPERIMENTAL *
|
||||
* It can result in LOSS OF FUNDS or worse *
|
||||
* !USE AT YOUR OWN RISK! *
|
||||
*=====================================================*/
|
||||
|
||||
/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_all/input.sol"
|
||||
object "C_6" {
|
||||
code {
|
||||
{
|
||||
/// @src 0:60:101 "contract C {..."
|
||||
mstore(64, 128)
|
||||
if callvalue() { revert(0, 0) }
|
||||
let _1 := datasize("C_6_deployed")
|
||||
codecopy(128, dataoffset("C_6_deployed"), _1)
|
||||
return(128, _1)
|
||||
}
|
||||
}
|
||||
/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_all/input.sol"
|
||||
object "C_6_deployed" {
|
||||
code {
|
||||
{
|
||||
/// @src 0:60:101 "contract C {..."
|
||||
mstore(64, 128)
|
||||
if iszero(lt(calldatasize(), 4))
|
||||
{
|
||||
let _1 := 0
|
||||
if eq(0x26121ff0, shr(224, calldataload(_1)))
|
||||
{
|
||||
if callvalue() { revert(_1, _1) }
|
||||
if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) }
|
||||
return(128, _1)
|
||||
}
|
||||
}
|
||||
revert(0, 0)
|
||||
}
|
||||
}
|
||||
data ".metadata" hex"<BYTECODE REMOVED>"
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
--ir --ir-optimized --asm --optimize --debug-info location,all,none
|
@ -0,0 +1 @@
|
||||
Invalid value for --debug-info option: location,all,none
|
@ -0,0 +1 @@
|
||||
1
|
@ -0,0 +1 @@
|
||||
--ir --ir-optimized --asm --optimize --debug-info location
|
@ -0,0 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
pragma solidity >=0.0;
|
||||
|
||||
contract C {
|
||||
function f() public {}
|
||||
}
|
@ -0,0 +1,212 @@
|
||||
|
||||
======= debug_info_in_yul_and_evm_asm_print_location_only/input.sol:C =======
|
||||
EVM assembly:
|
||||
/* "debug_info_in_yul_and_evm_asm_print_location_only/input.sol":60:101 */
|
||||
mstore(0x40, 0x80)
|
||||
callvalue
|
||||
dup1
|
||||
iszero
|
||||
tag_1
|
||||
jumpi
|
||||
0x00
|
||||
dup1
|
||||
revert
|
||||
tag_1:
|
||||
pop
|
||||
dataSize(sub_0)
|
||||
dup1
|
||||
dataOffset(sub_0)
|
||||
0x00
|
||||
codecopy
|
||||
0x00
|
||||
return
|
||||
stop
|
||||
|
||||
sub_0: assembly {
|
||||
/* "debug_info_in_yul_and_evm_asm_print_location_only/input.sol":60:101 */
|
||||
mstore(0x40, 0x80)
|
||||
callvalue
|
||||
dup1
|
||||
iszero
|
||||
tag_1
|
||||
jumpi
|
||||
0x00
|
||||
dup1
|
||||
revert
|
||||
tag_1:
|
||||
pop
|
||||
jumpi(tag_2, lt(calldatasize, 0x04))
|
||||
shr(0xe0, calldataload(0x00))
|
||||
dup1
|
||||
0x26121ff0
|
||||
eq
|
||||
tag_3
|
||||
jumpi
|
||||
tag_2:
|
||||
0x00
|
||||
dup1
|
||||
revert
|
||||
/* "debug_info_in_yul_and_evm_asm_print_location_only/input.sol":77:99 */
|
||||
tag_3:
|
||||
stop
|
||||
|
||||
auxdata: <AUXDATA REMOVED>
|
||||
}
|
||||
|
||||
IR:
|
||||
/*=====================================================*
|
||||
* WARNING *
|
||||
* Solidity to Yul compilation is still EXPERIMENTAL *
|
||||
* It can result in LOSS OF FUNDS or worse *
|
||||
* !USE AT YOUR OWN RISK! *
|
||||
*=====================================================*/
|
||||
|
||||
|
||||
/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_location_only/input.sol"
|
||||
object "C_6" {
|
||||
code {
|
||||
/// @src 0:60:101
|
||||
mstore(64, 128)
|
||||
if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }
|
||||
|
||||
constructor_C_6()
|
||||
|
||||
let _1 := allocate_unbounded()
|
||||
codecopy(_1, dataoffset("C_6_deployed"), datasize("C_6_deployed"))
|
||||
|
||||
return(_1, datasize("C_6_deployed"))
|
||||
|
||||
function allocate_unbounded() -> memPtr {
|
||||
memPtr := mload(64)
|
||||
}
|
||||
|
||||
function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {
|
||||
revert(0, 0)
|
||||
}
|
||||
|
||||
/// @src 0:60:101
|
||||
function constructor_C_6() {
|
||||
|
||||
/// @src 0:60:101
|
||||
|
||||
}
|
||||
/// @src 0:60:101
|
||||
|
||||
}
|
||||
/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_location_only/input.sol"
|
||||
object "C_6_deployed" {
|
||||
code {
|
||||
/// @src 0:60:101
|
||||
mstore(64, 128)
|
||||
|
||||
if iszero(lt(calldatasize(), 4))
|
||||
{
|
||||
let selector := shift_right_224_unsigned(calldataload(0))
|
||||
switch selector
|
||||
|
||||
case 0x26121ff0
|
||||
{
|
||||
// f()
|
||||
|
||||
if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }
|
||||
abi_decode_tuple_(4, calldatasize())
|
||||
fun_f_5()
|
||||
let memPos := allocate_unbounded()
|
||||
let memEnd := abi_encode_tuple__to__fromStack(memPos )
|
||||
return(memPos, sub(memEnd, memPos))
|
||||
}
|
||||
|
||||
default {}
|
||||
}
|
||||
if iszero(calldatasize()) { }
|
||||
revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()
|
||||
|
||||
function shift_right_224_unsigned(value) -> newValue {
|
||||
newValue :=
|
||||
|
||||
shr(224, value)
|
||||
|
||||
}
|
||||
|
||||
function allocate_unbounded() -> memPtr {
|
||||
memPtr := mload(64)
|
||||
}
|
||||
|
||||
function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {
|
||||
revert(0, 0)
|
||||
}
|
||||
|
||||
function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {
|
||||
revert(0, 0)
|
||||
}
|
||||
|
||||
function abi_decode_tuple_(headStart, dataEnd) {
|
||||
if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }
|
||||
|
||||
}
|
||||
|
||||
function abi_encode_tuple__to__fromStack(headStart ) -> tail {
|
||||
tail := add(headStart, 0)
|
||||
|
||||
}
|
||||
|
||||
function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {
|
||||
revert(0, 0)
|
||||
}
|
||||
|
||||
/// @src 0:77:99
|
||||
function fun_f_5() {
|
||||
|
||||
}
|
||||
/// @src 0:60:101
|
||||
|
||||
}
|
||||
|
||||
data ".metadata" hex"<BYTECODE REMOVED>"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Optimized IR:
|
||||
/*=====================================================*
|
||||
* WARNING *
|
||||
* Solidity to Yul compilation is still EXPERIMENTAL *
|
||||
* It can result in LOSS OF FUNDS or worse *
|
||||
* !USE AT YOUR OWN RISK! *
|
||||
*=====================================================*/
|
||||
|
||||
/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_location_only/input.sol"
|
||||
object "C_6" {
|
||||
code {
|
||||
{
|
||||
/// @src 0:60:101
|
||||
mstore(64, 128)
|
||||
if callvalue() { revert(0, 0) }
|
||||
let _1 := datasize("C_6_deployed")
|
||||
codecopy(128, dataoffset("C_6_deployed"), _1)
|
||||
return(128, _1)
|
||||
}
|
||||
}
|
||||
/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_location_only/input.sol"
|
||||
object "C_6_deployed" {
|
||||
code {
|
||||
{
|
||||
/// @src 0:60:101
|
||||
mstore(64, 128)
|
||||
if iszero(lt(calldatasize(), 4))
|
||||
{
|
||||
let _1 := 0
|
||||
if eq(0x26121ff0, shr(224, calldataload(_1)))
|
||||
{
|
||||
if callvalue() { revert(_1, _1) }
|
||||
if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) }
|
||||
return(128, _1)
|
||||
}
|
||||
}
|
||||
revert(0, 0)
|
||||
}
|
||||
}
|
||||
data ".metadata" hex"<BYTECODE REMOVED>"
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
--ir --ir-optimized --asm --optimize --debug-info none
|
@ -0,0 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
pragma solidity >=0.0;
|
||||
|
||||
contract C {
|
||||
function f() public {}
|
||||
}
|
@ -0,0 +1,201 @@
|
||||
|
||||
======= debug_info_in_yul_and_evm_asm_print_none/input.sol:C =======
|
||||
EVM assembly:
|
||||
mstore(0x40, 0x80)
|
||||
callvalue
|
||||
dup1
|
||||
iszero
|
||||
tag_1
|
||||
jumpi
|
||||
0x00
|
||||
dup1
|
||||
revert
|
||||
tag_1:
|
||||
pop
|
||||
dataSize(sub_0)
|
||||
dup1
|
||||
dataOffset(sub_0)
|
||||
0x00
|
||||
codecopy
|
||||
0x00
|
||||
return
|
||||
stop
|
||||
|
||||
sub_0: assembly {
|
||||
mstore(0x40, 0x80)
|
||||
callvalue
|
||||
dup1
|
||||
iszero
|
||||
tag_1
|
||||
jumpi
|
||||
0x00
|
||||
dup1
|
||||
revert
|
||||
tag_1:
|
||||
pop
|
||||
jumpi(tag_2, lt(calldatasize, 0x04))
|
||||
shr(0xe0, calldataload(0x00))
|
||||
dup1
|
||||
0x26121ff0
|
||||
eq
|
||||
tag_3
|
||||
jumpi
|
||||
tag_2:
|
||||
0x00
|
||||
dup1
|
||||
revert
|
||||
tag_3:
|
||||
stop
|
||||
|
||||
auxdata: <AUXDATA REMOVED>
|
||||
}
|
||||
|
||||
IR:
|
||||
/*=====================================================*
|
||||
* WARNING *
|
||||
* Solidity to Yul compilation is still EXPERIMENTAL *
|
||||
* It can result in LOSS OF FUNDS or worse *
|
||||
* !USE AT YOUR OWN RISK! *
|
||||
*=====================================================*/
|
||||
|
||||
|
||||
/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_none/input.sol"
|
||||
object "C_6" {
|
||||
code {
|
||||
|
||||
mstore(64, 128)
|
||||
if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }
|
||||
|
||||
constructor_C_6()
|
||||
|
||||
let _1 := allocate_unbounded()
|
||||
codecopy(_1, dataoffset("C_6_deployed"), datasize("C_6_deployed"))
|
||||
|
||||
return(_1, datasize("C_6_deployed"))
|
||||
|
||||
function allocate_unbounded() -> memPtr {
|
||||
memPtr := mload(64)
|
||||
}
|
||||
|
||||
function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {
|
||||
revert(0, 0)
|
||||
}
|
||||
|
||||
function constructor_C_6() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_none/input.sol"
|
||||
object "C_6_deployed" {
|
||||
code {
|
||||
|
||||
mstore(64, 128)
|
||||
|
||||
if iszero(lt(calldatasize(), 4))
|
||||
{
|
||||
let selector := shift_right_224_unsigned(calldataload(0))
|
||||
switch selector
|
||||
|
||||
case 0x26121ff0
|
||||
{
|
||||
// f()
|
||||
|
||||
if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }
|
||||
abi_decode_tuple_(4, calldatasize())
|
||||
fun_f_5()
|
||||
let memPos := allocate_unbounded()
|
||||
let memEnd := abi_encode_tuple__to__fromStack(memPos )
|
||||
return(memPos, sub(memEnd, memPos))
|
||||
}
|
||||
|
||||
default {}
|
||||
}
|
||||
if iszero(calldatasize()) { }
|
||||
revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()
|
||||
|
||||
function shift_right_224_unsigned(value) -> newValue {
|
||||
newValue :=
|
||||
|
||||
shr(224, value)
|
||||
|
||||
}
|
||||
|
||||
function allocate_unbounded() -> memPtr {
|
||||
memPtr := mload(64)
|
||||
}
|
||||
|
||||
function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {
|
||||
revert(0, 0)
|
||||
}
|
||||
|
||||
function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {
|
||||
revert(0, 0)
|
||||
}
|
||||
|
||||
function abi_decode_tuple_(headStart, dataEnd) {
|
||||
if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }
|
||||
|
||||
}
|
||||
|
||||
function abi_encode_tuple__to__fromStack(headStart ) -> tail {
|
||||
tail := add(headStart, 0)
|
||||
|
||||
}
|
||||
|
||||
function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {
|
||||
revert(0, 0)
|
||||
}
|
||||
|
||||
function fun_f_5() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
data ".metadata" hex"<BYTECODE REMOVED>"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Optimized IR:
|
||||
/*=====================================================*
|
||||
* WARNING *
|
||||
* Solidity to Yul compilation is still EXPERIMENTAL *
|
||||
* It can result in LOSS OF FUNDS or worse *
|
||||
* !USE AT YOUR OWN RISK! *
|
||||
*=====================================================*/
|
||||
|
||||
/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_none/input.sol"
|
||||
object "C_6" {
|
||||
code {
|
||||
{
|
||||
mstore(64, 128)
|
||||
if callvalue() { revert(0, 0) }
|
||||
let _1 := datasize("C_6_deployed")
|
||||
codecopy(128, dataoffset("C_6_deployed"), _1)
|
||||
return(128, _1)
|
||||
}
|
||||
}
|
||||
/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_none/input.sol"
|
||||
object "C_6_deployed" {
|
||||
code {
|
||||
{
|
||||
mstore(64, 128)
|
||||
if iszero(lt(calldatasize(), 4))
|
||||
{
|
||||
let _1 := 0
|
||||
if eq(0x26121ff0, shr(224, calldataload(_1)))
|
||||
{
|
||||
if callvalue() { revert(_1, _1) }
|
||||
if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) }
|
||||
return(128, _1)
|
||||
}
|
||||
}
|
||||
revert(0, 0)
|
||||
}
|
||||
}
|
||||
data ".metadata" hex"<BYTECODE REMOVED>"
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
--ir --ir-optimized --asm --optimize --debug-info snippet
|
@ -0,0 +1 @@
|
||||
To use 'snippet' with --debug-info you must select also 'location'.
|
@ -0,0 +1 @@
|
||||
1
|
@ -0,0 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
pragma solidity >=0.0;
|
||||
|
||||
contract C {
|
||||
function f() public {}
|
||||
}
|
@ -0,0 +1 @@
|
||||
--pretty-json --json-indent 4 --allow-paths .
|
@ -0,0 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
pragma solidity >=0.0;
|
||||
|
||||
contract C {
|
||||
function f() public {}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
{
|
||||
"language": "Solidity",
|
||||
"sources": {
|
||||
"C": {"urls": ["standard_debug_info_in_yul_and_evm_asm_print_all/in.sol"]}
|
||||
},
|
||||
"settings": {
|
||||
"debug": {"debugInfo": ["*"]},
|
||||
"optimizer": {"enabled": true},
|
||||
"outputSelection": {
|
||||
"*": {"*": ["ir", "irOptimized", "evm.assembly"]}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,230 @@
|
||||
{
|
||||
"contracts":
|
||||
{
|
||||
"C":
|
||||
{
|
||||
"C":
|
||||
{
|
||||
"evm":
|
||||
{
|
||||
"assembly": " /* \"C\":60:101 contract C {... */
|
||||
mstore(0x40, 0x80)
|
||||
callvalue
|
||||
dup1
|
||||
iszero
|
||||
tag_1
|
||||
jumpi
|
||||
0x00
|
||||
dup1
|
||||
revert
|
||||
tag_1:
|
||||
pop
|
||||
dataSize(sub_0)
|
||||
dup1
|
||||
dataOffset(sub_0)
|
||||
0x00
|
||||
codecopy
|
||||
0x00
|
||||
return
|
||||
stop
|
||||
|
||||
sub_0: assembly {
|
||||
/* \"C\":60:101 contract C {... */
|
||||
mstore(0x40, 0x80)
|
||||
callvalue
|
||||
dup1
|
||||
iszero
|
||||
tag_1
|
||||
jumpi
|
||||
0x00
|
||||
dup1
|
||||
revert
|
||||
tag_1:
|
||||
pop
|
||||
jumpi(tag_2, lt(calldatasize, 0x04))
|
||||
shr(0xe0, calldataload(0x00))
|
||||
dup1
|
||||
0x26121ff0
|
||||
eq
|
||||
tag_3
|
||||
jumpi
|
||||
tag_2:
|
||||
0x00
|
||||
dup1
|
||||
revert
|
||||
/* \"C\":77:99 function f() public {} */
|
||||
tag_3:
|
||||
stop
|
||||
|
||||
auxdata: <AUXDATA REMOVED>
|
||||
}
|
||||
"
|
||||
},
|
||||
"ir": "/*=====================================================*
|
||||
* WARNING *
|
||||
* Solidity to Yul compilation is still EXPERIMENTAL *
|
||||
* It can result in LOSS OF FUNDS or worse *
|
||||
* !USE AT YOUR OWN RISK! *
|
||||
*=====================================================*/
|
||||
|
||||
|
||||
/// @use-src 0:\"C\"
|
||||
object \"C_6\" {
|
||||
code {
|
||||
/// @src 0:60:101 \"contract C {...\"
|
||||
mstore(64, 128)
|
||||
if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }
|
||||
|
||||
constructor_C_6()
|
||||
|
||||
let _1 := allocate_unbounded()
|
||||
codecopy(_1, dataoffset(\"C_6_deployed\"), datasize(\"C_6_deployed\"))
|
||||
|
||||
return(_1, datasize(\"C_6_deployed\"))
|
||||
|
||||
function allocate_unbounded() -> memPtr {
|
||||
memPtr := mload(64)
|
||||
}
|
||||
|
||||
function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {
|
||||
revert(0, 0)
|
||||
}
|
||||
|
||||
/// @src 0:60:101 \"contract C {...\"
|
||||
function constructor_C_6() {
|
||||
|
||||
/// @src 0:60:101 \"contract C {...\"
|
||||
|
||||
}
|
||||
/// @src 0:60:101 \"contract C {...\"
|
||||
|
||||
}
|
||||
/// @use-src 0:\"C\"
|
||||
object \"C_6_deployed\" {
|
||||
code {
|
||||
/// @src 0:60:101 \"contract C {...\"
|
||||
mstore(64, 128)
|
||||
|
||||
if iszero(lt(calldatasize(), 4))
|
||||
{
|
||||
let selector := shift_right_224_unsigned(calldataload(0))
|
||||
switch selector
|
||||
|
||||
case 0x26121ff0
|
||||
{
|
||||
// f()
|
||||
|
||||
if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }
|
||||
abi_decode_tuple_(4, calldatasize())
|
||||
fun_f_5()
|
||||
let memPos := allocate_unbounded()
|
||||
let memEnd := abi_encode_tuple__to__fromStack(memPos )
|
||||
return(memPos, sub(memEnd, memPos))
|
||||
}
|
||||
|
||||
default {}
|
||||
}
|
||||
if iszero(calldatasize()) { }
|
||||
revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()
|
||||
|
||||
function shift_right_224_unsigned(value) -> newValue {
|
||||
newValue :=
|
||||
|
||||
shr(224, value)
|
||||
|
||||
}
|
||||
|
||||
function allocate_unbounded() -> memPtr {
|
||||
memPtr := mload(64)
|
||||
}
|
||||
|
||||
function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {
|
||||
revert(0, 0)
|
||||
}
|
||||
|
||||
function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {
|
||||
revert(0, 0)
|
||||
}
|
||||
|
||||
function abi_decode_tuple_(headStart, dataEnd) {
|
||||
if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }
|
||||
|
||||
}
|
||||
|
||||
function abi_encode_tuple__to__fromStack(headStart ) -> tail {
|
||||
tail := add(headStart, 0)
|
||||
|
||||
}
|
||||
|
||||
function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {
|
||||
revert(0, 0)
|
||||
}
|
||||
|
||||
/// @ast-id 5
|
||||
/// @src 0:77:99 \"function f() public {}\"
|
||||
function fun_f_5() {
|
||||
|
||||
}
|
||||
/// @src 0:60:101 \"contract C {...\"
|
||||
|
||||
}
|
||||
|
||||
data \".metadata\" hex\"<BYTECODE REMOVED>\"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
",
|
||||
"irOptimized": "/*=====================================================*
|
||||
* WARNING *
|
||||
* Solidity to Yul compilation is still EXPERIMENTAL *
|
||||
* It can result in LOSS OF FUNDS or worse *
|
||||
* !USE AT YOUR OWN RISK! *
|
||||
*=====================================================*/
|
||||
|
||||
/// @use-src 0:\"C\"
|
||||
object \"C_6\" {
|
||||
code {
|
||||
{
|
||||
/// @src 0:60:101 \"contract C {...\"
|
||||
mstore(64, 128)
|
||||
if callvalue() { revert(0, 0) }
|
||||
let _1 := datasize(\"C_6_deployed\")
|
||||
codecopy(128, dataoffset(\"C_6_deployed\"), _1)
|
||||
return(128, _1)
|
||||
}
|
||||
}
|
||||
/// @use-src 0:\"C\"
|
||||
object \"C_6_deployed\" {
|
||||
code {
|
||||
{
|
||||
/// @src 0:60:101 \"contract C {...\"
|
||||
mstore(64, 128)
|
||||
if iszero(lt(calldatasize(), 4))
|
||||
{
|
||||
let _1 := 0
|
||||
if eq(0x26121ff0, shr(224, calldataload(_1)))
|
||||
{
|
||||
if callvalue() { revert(_1, _1) }
|
||||
if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) }
|
||||
return(128, _1)
|
||||
}
|
||||
}
|
||||
revert(0, 0)
|
||||
}
|
||||
}
|
||||
data \".metadata\" hex\"<BYTECODE REMOVED>\"
|
||||
}
|
||||
}
|
||||
"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sources":
|
||||
{
|
||||
"C":
|
||||
{
|
||||
"id": 0
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
--pretty-json --json-indent 4 --allow-paths .
|
@ -0,0 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
pragma solidity >=0.0;
|
||||
|
||||
contract C {
|
||||
function f() public {}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
{
|
||||
"language": "Solidity",
|
||||
"sources": {
|
||||
"C": {"urls": ["standard_debug_info_in_yul_and_evm_asm_print_location_only/in.sol"]}
|
||||
},
|
||||
"settings": {
|
||||
"debug": {"debugInfo": ["location"]},
|
||||
"optimizer": {"enabled": true},
|
||||
"outputSelection": {
|
||||
"*": {"*": ["ir", "irOptimized", "evm.assembly"]}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,229 @@
|
||||
{
|
||||
"contracts":
|
||||
{
|
||||
"C":
|
||||
{
|
||||
"C":
|
||||
{
|
||||
"evm":
|
||||
{
|
||||
"assembly": " /* \"C\":60:101 */
|
||||
mstore(0x40, 0x80)
|
||||
callvalue
|
||||
dup1
|
||||
iszero
|
||||
tag_1
|
||||
jumpi
|
||||
0x00
|
||||
dup1
|
||||
revert
|
||||
tag_1:
|
||||
pop
|
||||
dataSize(sub_0)
|
||||
dup1
|
||||
dataOffset(sub_0)
|
||||
0x00
|
||||
codecopy
|
||||
0x00
|
||||
return
|
||||
stop
|
||||
|
||||
sub_0: assembly {
|
||||
/* \"C\":60:101 */
|
||||
mstore(0x40, 0x80)
|
||||
callvalue
|
||||
dup1
|
||||
iszero
|
||||
tag_1
|
||||
jumpi
|
||||
0x00
|
||||
dup1
|
||||
revert
|
||||
tag_1:
|
||||
pop
|
||||
jumpi(tag_2, lt(calldatasize, 0x04))
|
||||
shr(0xe0, calldataload(0x00))
|
||||
dup1
|
||||
0x26121ff0
|
||||
eq
|
||||
tag_3
|
||||
jumpi
|
||||
tag_2:
|
||||
0x00
|
||||
dup1
|
||||
revert
|
||||
/* \"C\":77:99 */
|
||||
tag_3:
|
||||
stop
|
||||
|
||||
auxdata: <AUXDATA REMOVED>
|
||||
}
|
||||
"
|
||||
},
|
||||
"ir": "/*=====================================================*
|
||||
* WARNING *
|
||||
* Solidity to Yul compilation is still EXPERIMENTAL *
|
||||
* It can result in LOSS OF FUNDS or worse *
|
||||
* !USE AT YOUR OWN RISK! *
|
||||
*=====================================================*/
|
||||
|
||||
|
||||
/// @use-src 0:\"C\"
|
||||
object \"C_6\" {
|
||||
code {
|
||||
/// @src 0:60:101
|
||||
mstore(64, 128)
|
||||
if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }
|
||||
|
||||
constructor_C_6()
|
||||
|
||||
let _1 := allocate_unbounded()
|
||||
codecopy(_1, dataoffset(\"C_6_deployed\"), datasize(\"C_6_deployed\"))
|
||||
|
||||
return(_1, datasize(\"C_6_deployed\"))
|
||||
|
||||
function allocate_unbounded() -> memPtr {
|
||||
memPtr := mload(64)
|
||||
}
|
||||
|
||||
function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {
|
||||
revert(0, 0)
|
||||
}
|
||||
|
||||
/// @src 0:60:101
|
||||
function constructor_C_6() {
|
||||
|
||||
/// @src 0:60:101
|
||||
|
||||
}
|
||||
/// @src 0:60:101
|
||||
|
||||
}
|
||||
/// @use-src 0:\"C\"
|
||||
object \"C_6_deployed\" {
|
||||
code {
|
||||
/// @src 0:60:101
|
||||
mstore(64, 128)
|
||||
|
||||
if iszero(lt(calldatasize(), 4))
|
||||
{
|
||||
let selector := shift_right_224_unsigned(calldataload(0))
|
||||
switch selector
|
||||
|
||||
case 0x26121ff0
|
||||
{
|
||||
// f()
|
||||
|
||||
if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }
|
||||
abi_decode_tuple_(4, calldatasize())
|
||||
fun_f_5()
|
||||
let memPos := allocate_unbounded()
|
||||
let memEnd := abi_encode_tuple__to__fromStack(memPos )
|
||||
return(memPos, sub(memEnd, memPos))
|
||||
}
|
||||
|
||||
default {}
|
||||
}
|
||||
if iszero(calldatasize()) { }
|
||||
revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()
|
||||
|
||||
function shift_right_224_unsigned(value) -> newValue {
|
||||
newValue :=
|
||||
|
||||
shr(224, value)
|
||||
|
||||
}
|
||||
|
||||
function allocate_unbounded() -> memPtr {
|
||||
memPtr := mload(64)
|
||||
}
|
||||
|
||||
function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {
|
||||
revert(0, 0)
|
||||
}
|
||||
|
||||
function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {
|
||||
revert(0, 0)
|
||||
}
|
||||
|
||||
function abi_decode_tuple_(headStart, dataEnd) {
|
||||
if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }
|
||||
|
||||
}
|
||||
|
||||
function abi_encode_tuple__to__fromStack(headStart ) -> tail {
|
||||
tail := add(headStart, 0)
|
||||
|
||||
}
|
||||
|
||||
function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {
|
||||
revert(0, 0)
|
||||
}
|
||||
|
||||
/// @src 0:77:99
|
||||
function fun_f_5() {
|
||||
|
||||
}
|
||||
/// @src 0:60:101
|
||||
|
||||
}
|
||||
|
||||
data \".metadata\" hex\"<BYTECODE REMOVED>\"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
",
|
||||
"irOptimized": "/*=====================================================*
|
||||
* WARNING *
|
||||
* Solidity to Yul compilation is still EXPERIMENTAL *
|
||||
* It can result in LOSS OF FUNDS or worse *
|
||||
* !USE AT YOUR OWN RISK! *
|
||||
*=====================================================*/
|
||||
|
||||
/// @use-src 0:\"C\"
|
||||
object \"C_6\" {
|
||||
code {
|
||||
{
|
||||
/// @src 0:60:101
|
||||
mstore(64, 128)
|
||||
if callvalue() { revert(0, 0) }
|
||||
let _1 := datasize(\"C_6_deployed\")
|
||||
codecopy(128, dataoffset(\"C_6_deployed\"), _1)
|
||||
return(128, _1)
|
||||
}
|
||||
}
|
||||
/// @use-src 0:\"C\"
|
||||
object \"C_6_deployed\" {
|
||||
code {
|
||||
{
|
||||
/// @src 0:60:101
|
||||
mstore(64, 128)
|
||||
if iszero(lt(calldatasize(), 4))
|
||||
{
|
||||
let _1 := 0
|
||||
if eq(0x26121ff0, shr(224, calldataload(_1)))
|
||||
{
|
||||
if callvalue() { revert(_1, _1) }
|
||||
if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) }
|
||||
return(128, _1)
|
||||
}
|
||||
}
|
||||
revert(0, 0)
|
||||
}
|
||||
}
|
||||
data \".metadata\" hex\"<BYTECODE REMOVED>\"
|
||||
}
|
||||
}
|
||||
"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sources":
|
||||
{
|
||||
"C":
|
||||
{
|
||||
"id": 0
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
--pretty-json --json-indent 4 --allow-paths .
|
@ -0,0 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
pragma solidity >=0.0;
|
||||
|
||||
contract C {
|
||||
function f() public {}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
{
|
||||
"language": "Solidity",
|
||||
"sources": {
|
||||
"C": {"urls": ["standard_debug_info_in_yul_and_evm_asm_print_none/in.sol"]}
|
||||
},
|
||||
"settings": {
|
||||
"debug": {"debugInfo": []},
|
||||
"optimizer": {"enabled": true},
|
||||
"outputSelection": {
|
||||
"*": {"*": ["ir", "irOptimized", "evm.assembly"]}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,218 @@
|
||||
{
|
||||
"contracts":
|
||||
{
|
||||
"C":
|
||||
{
|
||||
"C":
|
||||
{
|
||||
"evm":
|
||||
{
|
||||
"assembly": " mstore(0x40, 0x80)
|
||||
callvalue
|
||||
dup1
|
||||
iszero
|
||||
tag_1
|
||||
jumpi
|
||||
0x00
|
||||
dup1
|
||||
revert
|
||||
tag_1:
|
||||
pop
|
||||
dataSize(sub_0)
|
||||
dup1
|
||||
dataOffset(sub_0)
|
||||
0x00
|
||||
codecopy
|
||||
0x00
|
||||
return
|
||||
stop
|
||||
|
||||
sub_0: assembly {
|
||||
mstore(0x40, 0x80)
|
||||
callvalue
|
||||
dup1
|
||||
iszero
|
||||
tag_1
|
||||
jumpi
|
||||
0x00
|
||||
dup1
|
||||
revert
|
||||
tag_1:
|
||||
pop
|
||||
jumpi(tag_2, lt(calldatasize, 0x04))
|
||||
shr(0xe0, calldataload(0x00))
|
||||
dup1
|
||||
0x26121ff0
|
||||
eq
|
||||
tag_3
|
||||
jumpi
|
||||
tag_2:
|
||||
0x00
|
||||
dup1
|
||||
revert
|
||||
tag_3:
|
||||
stop
|
||||
|
||||
auxdata: <AUXDATA REMOVED>
|
||||
}
|
||||
"
|
||||
},
|
||||
"ir": "/*=====================================================*
|
||||
* WARNING *
|
||||
* Solidity to Yul compilation is still EXPERIMENTAL *
|
||||
* It can result in LOSS OF FUNDS or worse *
|
||||
* !USE AT YOUR OWN RISK! *
|
||||
*=====================================================*/
|
||||
|
||||
|
||||
/// @use-src 0:\"C\"
|
||||
object \"C_6\" {
|
||||
code {
|
||||
|
||||
mstore(64, 128)
|
||||
if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }
|
||||
|
||||
constructor_C_6()
|
||||
|
||||
let _1 := allocate_unbounded()
|
||||
codecopy(_1, dataoffset(\"C_6_deployed\"), datasize(\"C_6_deployed\"))
|
||||
|
||||
return(_1, datasize(\"C_6_deployed\"))
|
||||
|
||||
function allocate_unbounded() -> memPtr {
|
||||
memPtr := mload(64)
|
||||
}
|
||||
|
||||
function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {
|
||||
revert(0, 0)
|
||||
}
|
||||
|
||||
function constructor_C_6() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
/// @use-src 0:\"C\"
|
||||
object \"C_6_deployed\" {
|
||||
code {
|
||||
|
||||
mstore(64, 128)
|
||||
|
||||
if iszero(lt(calldatasize(), 4))
|
||||
{
|
||||
let selector := shift_right_224_unsigned(calldataload(0))
|
||||
switch selector
|
||||
|
||||
case 0x26121ff0
|
||||
{
|
||||
// f()
|
||||
|
||||
if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }
|
||||
abi_decode_tuple_(4, calldatasize())
|
||||
fun_f_5()
|
||||
let memPos := allocate_unbounded()
|
||||
let memEnd := abi_encode_tuple__to__fromStack(memPos )
|
||||
return(memPos, sub(memEnd, memPos))
|
||||
}
|
||||
|
||||
default {}
|
||||
}
|
||||
if iszero(calldatasize()) { }
|
||||
revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()
|
||||
|
||||
function shift_right_224_unsigned(value) -> newValue {
|
||||
newValue :=
|
||||
|
||||
shr(224, value)
|
||||
|
||||
}
|
||||
|
||||
function allocate_unbounded() -> memPtr {
|
||||
memPtr := mload(64)
|
||||
}
|
||||
|
||||
function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {
|
||||
revert(0, 0)
|
||||
}
|
||||
|
||||
function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {
|
||||
revert(0, 0)
|
||||
}
|
||||
|
||||
function abi_decode_tuple_(headStart, dataEnd) {
|
||||
if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }
|
||||
|
||||
}
|
||||
|
||||
function abi_encode_tuple__to__fromStack(headStart ) -> tail {
|
||||
tail := add(headStart, 0)
|
||||
|
||||
}
|
||||
|
||||
function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {
|
||||
revert(0, 0)
|
||||
}
|
||||
|
||||
function fun_f_5() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
data \".metadata\" hex\"<BYTECODE REMOVED>\"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
",
|
||||
"irOptimized": "/*=====================================================*
|
||||
* WARNING *
|
||||
* Solidity to Yul compilation is still EXPERIMENTAL *
|
||||
* It can result in LOSS OF FUNDS or worse *
|
||||
* !USE AT YOUR OWN RISK! *
|
||||
*=====================================================*/
|
||||
|
||||
/// @use-src 0:\"C\"
|
||||
object \"C_6\" {
|
||||
code {
|
||||
{
|
||||
mstore(64, 128)
|
||||
if callvalue() { revert(0, 0) }
|
||||
let _1 := datasize(\"C_6_deployed\")
|
||||
codecopy(128, dataoffset(\"C_6_deployed\"), _1)
|
||||
return(128, _1)
|
||||
}
|
||||
}
|
||||
/// @use-src 0:\"C\"
|
||||
object \"C_6_deployed\" {
|
||||
code {
|
||||
{
|
||||
mstore(64, 128)
|
||||
if iszero(lt(calldatasize(), 4))
|
||||
{
|
||||
let _1 := 0
|
||||
if eq(0x26121ff0, shr(224, calldataload(_1)))
|
||||
{
|
||||
if callvalue() { revert(_1, _1) }
|
||||
if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) }
|
||||
return(128, _1)
|
||||
}
|
||||
}
|
||||
revert(0, 0)
|
||||
}
|
||||
}
|
||||
data \".metadata\" hex\"<BYTECODE REMOVED>\"
|
||||
}
|
||||
}
|
||||
"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sources":
|
||||
{
|
||||
"C":
|
||||
{
|
||||
"id": 0
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
--pretty-json --json-indent 4 --allow-paths .
|
@ -0,0 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
pragma solidity >=0.0;
|
||||
|
||||
contract C {
|
||||
function f() public {}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
{
|
||||
"language": "Solidity",
|
||||
"sources": {
|
||||
"C": {"urls": ["standard_debug_info_in_yul_and_evm_asm_print_snippet_only/in.sol"]}
|
||||
},
|
||||
"settings": {
|
||||
"debug": {"debugInfo": ["snippet"]},
|
||||
"optimizer": {"enabled": true},
|
||||
"outputSelection": {
|
||||
"*": {"*": ["ir", "irOptimized", "evm.assembly"]}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
{
|
||||
"errors":
|
||||
[
|
||||
{
|
||||
"component": "general",
|
||||
"formattedMessage": "To use 'snippet' with settings.debug.debugInfo you must select also 'location'.",
|
||||
"message": "To use 'snippet' with settings.debug.debugInfo you must select also 'location'.",
|
||||
"severity": "error",
|
||||
"type": "JSONError"
|
||||
}
|
||||
]
|
||||
}
|
1
test/cmdlineTests/standard_yul_debug_info_print_all/args
Normal file
1
test/cmdlineTests/standard_yul_debug_info_print_all/args
Normal file
@ -0,0 +1 @@
|
||||
--pretty-json --json-indent 4 --allow-paths .
|
15
test/cmdlineTests/standard_yul_debug_info_print_all/in.yul
Normal file
15
test/cmdlineTests/standard_yul_debug_info_print_all/in.yul
Normal file
@ -0,0 +1,15 @@
|
||||
/// @use-src 0:"input.sol"
|
||||
object "C_6_deployed" {
|
||||
code {
|
||||
/// @src 0:60:101 "contract C {..."
|
||||
mstore(64, 128)
|
||||
|
||||
// f()
|
||||
fun_f_5()
|
||||
|
||||
/// @src 0:77:99 "function f() public {}"
|
||||
function fun_f_5() {
|
||||
}
|
||||
/// @src 0:60:101 "contract C {..."
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
{
|
||||
"language": "Yul",
|
||||
"sources": {
|
||||
"C": {"urls": ["standard_yul_debug_info_print_all/in.yul"]}
|
||||
},
|
||||
"settings": {
|
||||
"debug": {"debugInfo": ["*"]},
|
||||
"outputSelection": {
|
||||
"*": {"*": ["evm.assembly"]}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
{
|
||||
"contracts":
|
||||
{
|
||||
"C":
|
||||
{
|
||||
"C_6_deployed":
|
||||
{
|
||||
"evm":
|
||||
{
|
||||
"assembly": " /* \"input.sol\":60:101 */
|
||||
mstore(0x40, 0x80)
|
||||
tag_2
|
||||
tag_1
|
||||
jump\t// in
|
||||
tag_2:
|
||||
/* \"input.sol\":77:99 */
|
||||
jump(tag_3)
|
||||
tag_1:
|
||||
jump\t// out
|
||||
tag_3:
|
||||
"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"errors":
|
||||
[
|
||||
{
|
||||
"component": "general",
|
||||
"formattedMessage": "Yul is still experimental. Please use the output with care.",
|
||||
"message": "Yul is still experimental. Please use the output with care.",
|
||||
"severity": "warning",
|
||||
"type": "Warning"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1 @@
|
||||
--pretty-json --json-indent 4 --allow-paths .
|
@ -0,0 +1,15 @@
|
||||
/// @use-src 0:"input.sol"
|
||||
object "C_6_deployed" {
|
||||
code {
|
||||
/// @src 0:60:101 "contract C {..."
|
||||
mstore(64, 128)
|
||||
|
||||
// f()
|
||||
fun_f_5()
|
||||
|
||||
/// @src 0:77:99 "function f() public {}"
|
||||
function fun_f_5() {
|
||||
}
|
||||
/// @src 0:60:101 "contract C {..."
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
{
|
||||
"language": "Yul",
|
||||
"sources": {
|
||||
"C": {"urls": ["standard_yul_debug_info_print_location_only/in.yul"]}
|
||||
},
|
||||
"settings": {
|
||||
"debug": {"debugInfo": ["location"]},
|
||||
"outputSelection": {
|
||||
"*": {"*": ["evm.assembly"]}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
{
|
||||
"contracts":
|
||||
{
|
||||
"C":
|
||||
{
|
||||
"C_6_deployed":
|
||||
{
|
||||
"evm":
|
||||
{
|
||||
"assembly": " /* \"input.sol\":60:101 */
|
||||
mstore(0x40, 0x80)
|
||||
tag_2
|
||||
tag_1
|
||||
jump\t// in
|
||||
tag_2:
|
||||
/* \"input.sol\":77:99 */
|
||||
jump(tag_3)
|
||||
tag_1:
|
||||
jump\t// out
|
||||
tag_3:
|
||||
"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"errors":
|
||||
[
|
||||
{
|
||||
"component": "general",
|
||||
"formattedMessage": "Yul is still experimental. Please use the output with care.",
|
||||
"message": "Yul is still experimental. Please use the output with care.",
|
||||
"severity": "warning",
|
||||
"type": "Warning"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1 @@
|
||||
--pretty-json --json-indent 4 --allow-paths .
|
15
test/cmdlineTests/standard_yul_debug_info_print_none/in.yul
Normal file
15
test/cmdlineTests/standard_yul_debug_info_print_none/in.yul
Normal file
@ -0,0 +1,15 @@
|
||||
/// @use-src 0:"input.sol"
|
||||
object "C_6_deployed" {
|
||||
code {
|
||||
/// @src 0:60:101 "contract C {..."
|
||||
mstore(64, 128)
|
||||
|
||||
// f()
|
||||
fun_f_5()
|
||||
|
||||
/// @src 0:77:99 "function f() public {}"
|
||||
function fun_f_5() {
|
||||
}
|
||||
/// @src 0:60:101 "contract C {..."
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
{
|
||||
"language": "Yul",
|
||||
"sources": {
|
||||
"C": {"urls": ["standard_yul_debug_info_print_none/in.yul"]}
|
||||
},
|
||||
"settings": {
|
||||
"debug": {"debugInfo": []},
|
||||
"outputSelection": {
|
||||
"*": {"*": ["evm.assembly"]}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
{
|
||||
"contracts":
|
||||
{
|
||||
"C":
|
||||
{
|
||||
"C_6_deployed":
|
||||
{
|
||||
"evm":
|
||||
{
|
||||
"assembly": " mstore(0x40, 0x80)
|
||||
tag_2
|
||||
tag_1
|
||||
jump\t// in
|
||||
tag_2:
|
||||
jump(tag_3)
|
||||
tag_1:
|
||||
jump\t// out
|
||||
tag_3:
|
||||
"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"errors":
|
||||
[
|
||||
{
|
||||
"component": "general",
|
||||
"formattedMessage": "Yul is still experimental. Please use the output with care.",
|
||||
"message": "Yul is still experimental. Please use the output with care.",
|
||||
"severity": "warning",
|
||||
"type": "Warning"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1 @@
|
||||
--pretty-json --json-indent 4 --allow-paths .
|
@ -0,0 +1,15 @@
|
||||
/// @use-src 0:"input.sol"
|
||||
object "C_6_deployed" {
|
||||
code {
|
||||
/// @src 0:60:101 "contract C {..."
|
||||
mstore(64, 128)
|
||||
|
||||
// f()
|
||||
fun_f_5()
|
||||
|
||||
/// @src 0:77:99 "function f() public {}"
|
||||
function fun_f_5() {
|
||||
}
|
||||
/// @src 0:60:101 "contract C {..."
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
{
|
||||
"language": "Yul",
|
||||
"sources": {
|
||||
"C": {"urls": ["standard_yul_debug_info_print_snippet_only/in.yul"]}
|
||||
},
|
||||
"settings": {
|
||||
"debug": {"debugInfo": ["snippet"]},
|
||||
"outputSelection": {
|
||||
"*": {"*": ["evm.assembly"]}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
{
|
||||
"errors":
|
||||
[
|
||||
{
|
||||
"component": "general",
|
||||
"formattedMessage": "To use 'snippet' with settings.debug.debugInfo you must select also 'location'.",
|
||||
"message": "To use 'snippet' with settings.debug.debugInfo you must select also 'location'.",
|
||||
"severity": "error",
|
||||
"type": "JSONError"
|
||||
}
|
||||
]
|
||||
}
|
1
test/cmdlineTests/strict_asm_debug_info_print_all/args
Normal file
1
test/cmdlineTests/strict_asm_debug_info_print_all/args
Normal file
@ -0,0 +1 @@
|
||||
--strict-assembly --debug-info all
|
1
test/cmdlineTests/strict_asm_debug_info_print_all/err
Normal file
1
test/cmdlineTests/strict_asm_debug_info_print_all/err
Normal file
@ -0,0 +1 @@
|
||||
Warning: Yul is still experimental. Please use the output with care.
|
15
test/cmdlineTests/strict_asm_debug_info_print_all/input.yul
Normal file
15
test/cmdlineTests/strict_asm_debug_info_print_all/input.yul
Normal file
@ -0,0 +1,15 @@
|
||||
/// @use-src 0:"input.sol"
|
||||
object "C_6_deployed" {
|
||||
code {
|
||||
/// @src 0:60:101 "contract C {..."
|
||||
mstore(64, 128)
|
||||
|
||||
// f()
|
||||
fun_f_5()
|
||||
|
||||
/// @src 0:77:99 "function f() public {}"
|
||||
function fun_f_5() {
|
||||
}
|
||||
/// @src 0:60:101 "contract C {..."
|
||||
}
|
||||
}
|
32
test/cmdlineTests/strict_asm_debug_info_print_all/output
Normal file
32
test/cmdlineTests/strict_asm_debug_info_print_all/output
Normal file
@ -0,0 +1,32 @@
|
||||
|
||||
======= strict_asm_debug_info_print_all/input.yul (EVM) =======
|
||||
|
||||
Pretty printed source:
|
||||
/// @use-src 0:"input.sol"
|
||||
object "C_6_deployed" {
|
||||
code {
|
||||
/// @src 0:60:101
|
||||
mstore(64, 128)
|
||||
fun_f_5()
|
||||
/// @src 0:77:99
|
||||
function fun_f_5()
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Binary representation:
|
||||
6080604052600a600e565b6010565b565b
|
||||
|
||||
Text representation:
|
||||
/* "input.sol":60:101 */
|
||||
mstore(0x40, 0x80)
|
||||
tag_2
|
||||
tag_1
|
||||
jump // in
|
||||
tag_2:
|
||||
/* "input.sol":77:99 */
|
||||
jump(tag_3)
|
||||
tag_1:
|
||||
jump // out
|
||||
tag_3:
|
@ -0,0 +1 @@
|
||||
--strict-assembly --debug-info location
|
@ -0,0 +1 @@
|
||||
Warning: Yul is still experimental. Please use the output with care.
|
@ -0,0 +1,15 @@
|
||||
/// @use-src 0:"input.sol"
|
||||
object "C_6_deployed" {
|
||||
code {
|
||||
/// @src 0:60:101 "contract C {..."
|
||||
mstore(64, 128)
|
||||
|
||||
// f()
|
||||
fun_f_5()
|
||||
|
||||
/// @src 0:77:99 "function f() public {}"
|
||||
function fun_f_5() {
|
||||
}
|
||||
/// @src 0:60:101 "contract C {..."
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
|
||||
======= strict_asm_debug_info_print_location_only/input.yul (EVM) =======
|
||||
|
||||
Pretty printed source:
|
||||
/// @use-src 0:"input.sol"
|
||||
object "C_6_deployed" {
|
||||
code {
|
||||
/// @src 0:60:101
|
||||
mstore(64, 128)
|
||||
fun_f_5()
|
||||
/// @src 0:77:99
|
||||
function fun_f_5()
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Binary representation:
|
||||
6080604052600a600e565b6010565b565b
|
||||
|
||||
Text representation:
|
||||
/* "input.sol":60:101 */
|
||||
mstore(0x40, 0x80)
|
||||
tag_2
|
||||
tag_1
|
||||
jump // in
|
||||
tag_2:
|
||||
/* "input.sol":77:99 */
|
||||
jump(tag_3)
|
||||
tag_1:
|
||||
jump // out
|
||||
tag_3:
|
1
test/cmdlineTests/strict_asm_debug_info_print_none/args
Normal file
1
test/cmdlineTests/strict_asm_debug_info_print_none/args
Normal file
@ -0,0 +1 @@
|
||||
--strict-assembly --debug-info none
|
1
test/cmdlineTests/strict_asm_debug_info_print_none/err
Normal file
1
test/cmdlineTests/strict_asm_debug_info_print_none/err
Normal file
@ -0,0 +1 @@
|
||||
Warning: Yul is still experimental. Please use the output with care.
|
15
test/cmdlineTests/strict_asm_debug_info_print_none/input.yul
Normal file
15
test/cmdlineTests/strict_asm_debug_info_print_none/input.yul
Normal file
@ -0,0 +1,15 @@
|
||||
/// @use-src 0:"input.sol"
|
||||
object "C_6_deployed" {
|
||||
code {
|
||||
/// @src 0:60:101 "contract C {..."
|
||||
mstore(64, 128)
|
||||
|
||||
// f()
|
||||
fun_f_5()
|
||||
|
||||
/// @src 0:77:99 "function f() public {}"
|
||||
function fun_f_5() {
|
||||
}
|
||||
/// @src 0:60:101 "contract C {..."
|
||||
}
|
||||
}
|
28
test/cmdlineTests/strict_asm_debug_info_print_none/output
Normal file
28
test/cmdlineTests/strict_asm_debug_info_print_none/output
Normal file
@ -0,0 +1,28 @@
|
||||
|
||||
======= strict_asm_debug_info_print_none/input.yul (EVM) =======
|
||||
|
||||
Pretty printed source:
|
||||
/// @use-src 0:"input.sol"
|
||||
object "C_6_deployed" {
|
||||
code {
|
||||
mstore(64, 128)
|
||||
fun_f_5()
|
||||
function fun_f_5()
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Binary representation:
|
||||
6080604052600a600e565b6010565b565b
|
||||
|
||||
Text representation:
|
||||
mstore(0x40, 0x80)
|
||||
tag_2
|
||||
tag_1
|
||||
jump // in
|
||||
tag_2:
|
||||
jump(tag_3)
|
||||
tag_1:
|
||||
jump // out
|
||||
tag_3:
|
@ -0,0 +1 @@
|
||||
--strict-assembly --debug-info snippet
|
@ -0,0 +1 @@
|
||||
To use 'snippet' with --debug-info you must select also 'location'.
|
@ -0,0 +1 @@
|
||||
1
|
@ -0,0 +1,15 @@
|
||||
/// @use-src 0:"input.sol"
|
||||
object "C_6_deployed" {
|
||||
code {
|
||||
/// @src 0:60:101 "contract C {..."
|
||||
mstore(64, 128)
|
||||
|
||||
// f()
|
||||
fun_f_5()
|
||||
|
||||
/// @src 0:77:99 "function f() public {}"
|
||||
function fun_f_5() {
|
||||
}
|
||||
/// @src 0:60:101 "contract C {..."
|
||||
}
|
||||
}
|
@ -28,8 +28,9 @@
|
||||
|
||||
#include <libyul/AssemblyStack.h>
|
||||
|
||||
#include <liblangutil/Scanner.h>
|
||||
#include <liblangutil/DebugInfoSelection.h>
|
||||
#include <liblangutil/Exceptions.h>
|
||||
#include <liblangutil/Scanner.h>
|
||||
#include <liblangutil/SourceReferenceFormatter.h>
|
||||
|
||||
#include <libevmasm/Assembly.h>
|
||||
@ -59,7 +60,12 @@ std::optional<Error> parseAndReturnFirstError(
|
||||
AssemblyStack::Machine _machine = AssemblyStack::Machine::EVM
|
||||
)
|
||||
{
|
||||
AssemblyStack stack(solidity::test::CommonOptions::get().evmVersion(), _language, solidity::frontend::OptimiserSettings::none());
|
||||
AssemblyStack stack(
|
||||
solidity::test::CommonOptions::get().evmVersion(),
|
||||
_language,
|
||||
solidity::frontend::OptimiserSettings::none(),
|
||||
DebugInfoSelection::None()
|
||||
);
|
||||
bool success = false;
|
||||
try
|
||||
{
|
||||
@ -125,7 +131,12 @@ Error expectError(
|
||||
|
||||
void parsePrintCompare(string const& _source, bool _canWarn = false)
|
||||
{
|
||||
AssemblyStack stack(solidity::test::CommonOptions::get().evmVersion(), AssemblyStack::Language::Assembly, OptimiserSettings::none());
|
||||
AssemblyStack stack(
|
||||
solidity::test::CommonOptions::get().evmVersion(),
|
||||
AssemblyStack::Language::Assembly,
|
||||
OptimiserSettings::none(),
|
||||
DebugInfoSelection::None()
|
||||
);
|
||||
BOOST_REQUIRE(stack.parseAndAnalyze("", _source));
|
||||
if (_canWarn)
|
||||
BOOST_REQUIRE(!Error::containsErrors(stack.errors()));
|
||||
@ -210,7 +221,12 @@ BOOST_AUTO_TEST_CASE(print_string_literal_unicode)
|
||||
{
|
||||
string source = "{ let x := \"\\u1bac\" }";
|
||||
string parsed = "object \"object\" {\n code { let x := \"\\xe1\\xae\\xac\" }\n}\n";
|
||||
AssemblyStack stack(solidity::test::CommonOptions::get().evmVersion(), AssemblyStack::Language::Assembly, OptimiserSettings::none());
|
||||
AssemblyStack stack(
|
||||
solidity::test::CommonOptions::get().evmVersion(),
|
||||
AssemblyStack::Language::Assembly,
|
||||
OptimiserSettings::none(),
|
||||
DebugInfoSelection::None()
|
||||
);
|
||||
BOOST_REQUIRE(stack.parseAndAnalyze("", source));
|
||||
BOOST_REQUIRE(stack.errors().empty());
|
||||
BOOST_CHECK_EQUAL(stack.print(), parsed);
|
||||
|
@ -21,17 +21,22 @@
|
||||
* Framework for executing Solidity contracts and testing them against C++ implementation.
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <boost/test/framework.hpp>
|
||||
#include <test/libsolidity/SolidityExecutionFramework.h>
|
||||
|
||||
#include <liblangutil/DebugInfoSelection.h>
|
||||
#include <liblangutil/Exceptions.h>
|
||||
#include <liblangutil/SourceReferenceFormatter.h>
|
||||
|
||||
#include <boost/test/framework.hpp>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
using namespace solidity;
|
||||
using namespace solidity::test;
|
||||
using namespace solidity::frontend;
|
||||
using namespace solidity::frontend::test;
|
||||
using namespace solidity::langutil;
|
||||
using namespace solidity::test;
|
||||
using namespace std;
|
||||
|
||||
bytes SolidityExecutionFramework::multiSourceCompileContract(
|
||||
@ -91,8 +96,12 @@ bytes SolidityExecutionFramework::multiSourceCompileContract(
|
||||
else if (forceEnableOptimizer)
|
||||
optimiserSettings = OptimiserSettings::full();
|
||||
|
||||
yul::AssemblyStack
|
||||
asmStack(m_evmVersion, yul::AssemblyStack::Language::StrictAssembly, optimiserSettings);
|
||||
yul::AssemblyStack asmStack(
|
||||
m_evmVersion,
|
||||
yul::AssemblyStack::Language::StrictAssembly,
|
||||
optimiserSettings,
|
||||
DebugInfoSelection::All()
|
||||
);
|
||||
bool analysisSuccessful = asmStack.parseAndAnalyze("", m_compiler.yulIROptimized(contractName));
|
||||
solAssert(analysisSuccessful, "Code that passed analysis in CompilerStack can't have errors");
|
||||
|
||||
|
@ -23,8 +23,6 @@
|
||||
|
||||
#include <test/Common.h>
|
||||
|
||||
#include <liblangutil/SourceReferenceFormatter.h>
|
||||
|
||||
#include <libyul/optimiser/Disambiguator.h>
|
||||
#include <libyul/AsmAnalysis.h>
|
||||
#include <libyul/AsmPrinter.h>
|
||||
@ -33,8 +31,10 @@
|
||||
#include <libyul/backends/evm/EVMDialect.h>
|
||||
#include <libyul/backends/wasm/WasmDialect.h>
|
||||
|
||||
#include <liblangutil/Scanner.h>
|
||||
#include <liblangutil/DebugInfoSelection.h>
|
||||
#include <liblangutil/ErrorReporter.h>
|
||||
#include <liblangutil/Scanner.h>
|
||||
#include <liblangutil/SourceReferenceFormatter.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@ -60,7 +60,8 @@ pair<shared_ptr<Block>, shared_ptr<yul::AsmAnalysisInfo>> yul::test::parse(strin
|
||||
_yul ? AssemblyStack::Language::Yul : AssemblyStack::Language::StrictAssembly,
|
||||
solidity::test::CommonOptions::get().optimize ?
|
||||
solidity::frontend::OptimiserSettings::standard() :
|
||||
solidity::frontend::OptimiserSettings::minimal()
|
||||
solidity::frontend::OptimiserSettings::minimal(),
|
||||
DebugInfoSelection::All()
|
||||
);
|
||||
if (!stack.parseAndAnalyze("", _source) || !stack.errors().empty())
|
||||
BOOST_FAIL("Invalid source.");
|
||||
|
@ -47,7 +47,12 @@ TestCase::TestResult EVMCodeTransformTest::run(ostream& _stream, string const& _
|
||||
solidity::frontend::OptimiserSettings settings = solidity::frontend::OptimiserSettings::none();
|
||||
settings.runYulOptimiser = false;
|
||||
settings.optimizeStackAllocation = m_stackOpt;
|
||||
AssemblyStack stack(EVMVersion{}, AssemblyStack::Language::StrictAssembly, settings);
|
||||
AssemblyStack stack(
|
||||
EVMVersion{},
|
||||
AssemblyStack::Language::StrictAssembly,
|
||||
settings,
|
||||
DebugInfoSelection::All()
|
||||
);
|
||||
if (!stack.parseAndAnalyze("", m_source))
|
||||
{
|
||||
AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Error parsing source." << endl;
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <libyul/AST.h>
|
||||
#include <libyul/Object.h>
|
||||
|
||||
#include <liblangutil/DebugInfoSelection.h>
|
||||
#include <liblangutil/ErrorReporter.h>
|
||||
#include <liblangutil/SourceReferenceFormatter.h>
|
||||
|
||||
@ -82,7 +83,8 @@ bool EwasmTranslationTest::parse(ostream& _stream, string const& _linePrefix, bo
|
||||
m_stack = AssemblyStack(
|
||||
solidity::test::CommonOptions::get().evmVersion(),
|
||||
AssemblyStack::Language::StrictAssembly,
|
||||
solidity::frontend::OptimiserSettings::none()
|
||||
solidity::frontend::OptimiserSettings::none(),
|
||||
DebugInfoSelection::All()
|
||||
);
|
||||
if (m_stack.parseAndAnalyze("", m_source))
|
||||
{
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include <libyul/optimiser/FullInliner.h>
|
||||
#include <libyul/optimiser/FunctionHoister.h>
|
||||
#include <libyul/optimiser/FunctionGrouper.h>
|
||||
#include <libyul/AsmPrinter.h>
|
||||
#include <libyul/AST.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
#include <libevmasm/Instruction.h>
|
||||
|
||||
#include <liblangutil/DebugInfoSelection.h>
|
||||
#include <liblangutil/SourceReferenceFormatter.h>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
@ -64,7 +65,8 @@ TestCase::TestResult ObjectCompilerTest::run(ostream& _stream, string const& _li
|
||||
AssemblyStack stack(
|
||||
EVMVersion(),
|
||||
m_wasm ? AssemblyStack::Language::Ewasm : AssemblyStack::Language::StrictAssembly,
|
||||
OptimiserSettings::preset(m_optimisationPreset)
|
||||
OptimiserSettings::preset(m_optimisationPreset),
|
||||
DebugInfoSelection::All()
|
||||
);
|
||||
if (!stack.parseAndAnalyze("source", m_source))
|
||||
{
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include <test/libsolidity/ErrorCheck.h>
|
||||
|
||||
#include <liblangutil/DebugInfoSelection.h>
|
||||
#include <liblangutil/Scanner.h>
|
||||
|
||||
#include <libyul/AssemblyStack.h>
|
||||
@ -60,7 +61,8 @@ pair<bool, ErrorList> parse(string const& _source)
|
||||
AssemblyStack asmStack(
|
||||
solidity::test::CommonOptions::get().evmVersion(),
|
||||
AssemblyStack::Language::StrictAssembly,
|
||||
solidity::frontend::OptimiserSettings::none()
|
||||
solidity::frontend::OptimiserSettings::none(),
|
||||
DebugInfoSelection::All()
|
||||
);
|
||||
bool success = asmStack.parseAndAnalyze("source", _source);
|
||||
return {success, asmStack.errors()};
|
||||
@ -181,7 +183,8 @@ BOOST_AUTO_TEST_CASE(to_string)
|
||||
AssemblyStack asmStack(
|
||||
solidity::test::CommonOptions::get().evmVersion(),
|
||||
AssemblyStack::Language::StrictAssembly,
|
||||
solidity::frontend::OptimiserSettings::none()
|
||||
solidity::frontend::OptimiserSettings::none(),
|
||||
DebugInfoSelection::All()
|
||||
);
|
||||
BOOST_REQUIRE(asmStack.parseAndAnalyze("source", code));
|
||||
BOOST_CHECK_EQUAL(asmStack.print(), expectation);
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <libyul/AssemblyStack.h>
|
||||
#include <libyul/AsmAnalysisInfo.h>
|
||||
|
||||
#include <liblangutil/DebugInfoSelection.h>
|
||||
#include <liblangutil/ErrorReporter.h>
|
||||
#include <liblangutil/SourceReferenceFormatter.h>
|
||||
|
||||
@ -67,7 +68,8 @@ bool YulInterpreterTest::parse(ostream& _stream, string const& _linePrefix, bool
|
||||
AssemblyStack stack(
|
||||
solidity::test::CommonOptions::get().evmVersion(),
|
||||
AssemblyStack::Language::StrictAssembly,
|
||||
solidity::frontend::OptimiserSettings::none()
|
||||
solidity::frontend::OptimiserSettings::none(),
|
||||
DebugInfoSelection::All()
|
||||
);
|
||||
if (stack.parseAndAnalyze("", m_source))
|
||||
{
|
||||
|
@ -61,7 +61,6 @@
|
||||
#include <libyul/backends/evm/EVMMetrics.h>
|
||||
#include <libyul/backends/wasm/WordSizeTransform.h>
|
||||
#include <libyul/backends/wasm/WasmDialect.h>
|
||||
#include <libyul/AsmPrinter.h>
|
||||
#include <libyul/AsmAnalysis.h>
|
||||
#include <libyul/CompilabilityChecker.h>
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user