Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ Compiler Features:

Bugfixes:
* SMTChecker: Fix SMT logic error when assigning to an array of addresses.
* Yul AST: Fix shifted native source locations when debug info selection included code snippets.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if we want to have a changelog entry for this one. Technically, we never made Yul AST output non-experimental. On the other hand, the feature has been there for a while and it's still nice to have a record of what changed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is good to have some documentation, even if the feature is experimental. Could be worth clarifying in the changelog that it is indeed an experimental feature, though?

Copy link
Member

@r0qs r0qs Sep 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think it is ok to have a changelog entry here, since we also included it when the feature was added in https://github.com/ethereum/solidity/pull/14177/files#diff-c275fec9c453c2a42515bc5ab47e30fa4130ff1426aef2f6e000a9a34e122cb8R8

Copy link
Collaborator Author

@cameel cameel Sep 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since we also included it when the feature was added in

Yeah, but that was actually an oversight back then :) I was meant to be experimental. And also we do have entries for introduction of experimental features, just not necessarily for updates to them. But given that it was not marked as experimental, perhaps this one is fine not being marked as such either...



### 0.8.27 (2024-09-04)

Expand Down
2 changes: 1 addition & 1 deletion libsolidity/codegen/ir/IRGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#include <libsolidity/codegen/ABIFunctions.h>
#include <libsolidity/codegen/CompilerUtils.h>

#include <libyul/YulStack.h>
#include <libyul/Object.h>
#include <libyul/Utilities.h>

#include <libsolutil/Algorithms.h>
Expand Down
1 change: 0 additions & 1 deletion libsolidity/experimental/codegen/IRGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@

#include <libsolidity/experimental/ast/TypeSystemHelper.h>

#include <libyul/YulStack.h>
#include <libyul/AsmPrinter.h>
#include <libyul/AST.h>
#include <libyul/optimiser/ASTCopier.h>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@

#include <libsolidity/experimental/ast/TypeSystemHelper.h>

#include <libyul/YulStack.h>
#include <libyul/AsmPrinter.h>
#include <libyul/AST.h>
#include <libyul/backends/evm/EVMDialect.h>
#include <libyul/optimiser/ASTCopier.h>

#include <libsolidity/experimental/codegen/Common.h>
Expand Down
4 changes: 3 additions & 1 deletion libsolidity/interface/CompilerStack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1522,6 +1522,7 @@ void CompilerStack::generateIR(ContractDefinition const& _contract, bool _unopti
YulStack::Language::StrictAssembly,
m_optimiserSettings,
m_debugInfoSelection,
this, // _soliditySourceProvider
m_objectOptimizer
);
bool yulAnalysisSuccessful = stack.parseAndAnalyze("", compiledContract.yulIR);
Expand All @@ -1537,7 +1538,7 @@ void CompilerStack::generateIR(ContractDefinition const& _contract, bool _unopti
if (!_unoptimizedOnly)
{
stack.optimize();
compiledContract.yulIROptimized = stack.print(this);
compiledContract.yulIROptimized = stack.print();
compiledContract.yulIROptimizedAst = stack.astJson();
}
}
Expand All @@ -1561,6 +1562,7 @@ void CompilerStack::generateEVMFromIR(ContractDefinition const& _contract)
yul::YulStack::Language::StrictAssembly,
m_optimiserSettings,
m_debugInfoSelection,
this, // _soliditySourceProvider
m_objectOptimizer
);
bool analysisSuccessful = stack.parseAndAnalyze("", compiledContract.yulIROptimized);
Expand Down
26 changes: 16 additions & 10 deletions libyul/YulStack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,12 +211,20 @@ void YulStack::reparse()
yulAssert(m_parserResult);
yulAssert(m_charStream);

// NOTE: Without passing in _soliditySourceProvider, printed debug info will not include code
// snippets, but it does not matter - we'll still get the same AST after we parse it. Snippets
// are not stored in the AST and the other info that is (location, AST ID, etc) will still be present.
std::string source = print(nullptr /* _soliditySourceProvider */);

YulStack cleanStack(m_evmVersion, m_eofVersion, m_language, m_optimiserSettings, m_debugInfoSelection, m_objectOptimizer);
// NOTE: it is important for the source printed here to exactly match what the compiler will
// eventually output to the user. In particular, debug info must be exactly the same.
// Otherwise source locations will be off.
std::string source = print();

YulStack cleanStack(
m_evmVersion,
m_eofVersion,
m_language,
m_optimiserSettings,
m_debugInfoSelection,
m_soliditySourceProvider,
m_objectOptimizer
);
bool reanalysisSuccessful = cleanStack.parseAndAnalyze(m_charStream->name(), source);
yulAssert(
reanalysisSuccessful,
Expand Down Expand Up @@ -348,16 +356,14 @@ YulStack::assembleEVMWithDeployed(std::optional<std::string_view> _deployName)
return {std::make_shared<evmasm::Assembly>(assembly), {}};
}

std::string YulStack::print(
CharStreamProvider const* _soliditySourceProvider
) const
std::string YulStack::print() const
{
yulAssert(m_stackState >= Parsed);
yulAssert(m_parserResult, "");
yulAssert(m_parserResult->hasCode(), "");
return m_parserResult->toString(
m_debugInfoSelection,
_soliditySourceProvider
m_soliditySourceProvider
) + "\n";
}

Expand Down
11 changes: 8 additions & 3 deletions libyul/YulStack.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,15 @@ class YulStack: public langutil::CharStreamProvider
Language _language,
solidity::frontend::OptimiserSettings _optimiserSettings,
langutil::DebugInfoSelection const& _debugInfoSelection,
langutil::CharStreamProvider const* _soliditySourceProvider = nullptr,
std::shared_ptr<ObjectOptimizer> _objectOptimizer = nullptr
):
m_language(_language),
m_evmVersion(_evmVersion),
m_eofVersion(_eofVersion),
m_optimiserSettings(std::move(_optimiserSettings)),
m_debugInfoSelection(_debugInfoSelection),
m_soliditySourceProvider(_soliditySourceProvider),
m_errorReporter(m_errors),
m_objectOptimizer(_objectOptimizer ? std::move(_objectOptimizer) : std::make_shared<ObjectOptimizer>())
{}
Expand Down Expand Up @@ -137,9 +139,7 @@ class YulStack: public langutil::CharStreamProvider
bool hasErrors() const { return m_errorReporter.hasErrors(); }

/// Pretty-print the input after having parsed it.
std::string print(
langutil::CharStreamProvider const* _soliditySourceProvider = nullptr
) const;
std::string print() const;
Json astJson() const;

// return the JSON representation of the YuL CFG (experimental)
Expand Down Expand Up @@ -172,6 +172,11 @@ class YulStack: public langutil::CharStreamProvider
solidity::frontend::OptimiserSettings m_optimiserSettings;
langutil::DebugInfoSelection m_debugInfoSelection{};

/// Provider of the Solidity sources that the Yul code was generated from.
/// Necessary when code snippets are requested as a part of debug info. When null, code snippets are omitted.
/// NOTE: Not owned by YulStack, the user must ensure that it is not destroyed before the stack is.
langutil::CharStreamProvider const* m_soliditySourceProvider{};
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that the best solution is to just store a pointer to the source provider (i.e. CompilerStack in YulStack. This will require us to worry about its lifetime, but on the other hand we'll no longer have any issues with things being printed differently due to debug info.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that the lifetime is a big worry in this case, so fully agree!


std::unique_ptr<langutil::CharStream> m_charStream;

State m_stackState = Empty;
Expand Down
Loading