mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Do not allocate memory on reverts with small errors.
This commit is contained in:
parent
21caa43f2c
commit
87ce29542c
@ -15,6 +15,7 @@ Compiler Features:
|
|||||||
* SMTChecker: Properties that are proved safe are now reported explicitly at the end of the analysis. By default, only the number of safe properties is shown. The CLI option ``--model-checker-show-proved-safe`` and the JSON option ``settings.modelChecker.showProvedSafe`` can be enabled to show the full list of safe properties.
|
* SMTChecker: Properties that are proved safe are now reported explicitly at the end of the analysis. By default, only the number of safe properties is shown. The CLI option ``--model-checker-show-proved-safe`` and the JSON option ``settings.modelChecker.showProvedSafe`` can be enabled to show the full list of safe properties.
|
||||||
* SMTChecker: Group all messages about unsupported language features in a single warning. The CLI option ``--model-checker-show-unsupported`` and the JSON option ``settings.modelChecker.showUnsupported`` can be enabled to show the full list.
|
* SMTChecker: Group all messages about unsupported language features in a single warning. The CLI option ``--model-checker-show-unsupported`` and the JSON option ``settings.modelChecker.showUnsupported`` can be enabled to show the full list.
|
||||||
* Yul EVM Code Transform: If available, use ``push0`` instead of ``codesize`` to produce an arbitrary value on stack in order to create equal stack heights between branches.
|
* Yul EVM Code Transform: If available, use ``push0`` instead of ``codesize`` to produce an arbitrary value on stack in order to create equal stack heights between branches.
|
||||||
|
* Yul IR Code Generation: Cheaper code for reverting with errors of a static small encoding size.
|
||||||
|
|
||||||
|
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
#include <libsolutil/FunctionSelector.h>
|
#include <libsolutil/FunctionSelector.h>
|
||||||
#include <libsolutil/Visitor.h>
|
#include <libsolutil/Visitor.h>
|
||||||
|
|
||||||
|
#include <range/v3/algorithm/all_of.hpp>
|
||||||
#include <range/v3/view/transform.hpp>
|
#include <range/v3/view/transform.hpp>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -58,6 +59,18 @@ using namespace std::string_literals;
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
|
optional<size_t> staticEncodingSize(vector<Type const*> const& _parameterTypes)
|
||||||
|
{
|
||||||
|
size_t encodedSize = 0;
|
||||||
|
for (auto const* type: _parameterTypes)
|
||||||
|
{
|
||||||
|
if (type->isDynamicallyEncoded())
|
||||||
|
return nullopt;
|
||||||
|
encodedSize += type->calldataHeadSize();
|
||||||
|
}
|
||||||
|
return encodedSize;
|
||||||
|
}
|
||||||
|
|
||||||
struct CopyTranslate: public yul::ASTCopier
|
struct CopyTranslate: public yul::ASTCopier
|
||||||
{
|
{
|
||||||
using ExternalRefsMap = std::map<yul::Identifier const*, InlineAssemblyAnnotation::ExternalIdentifierInfo>;
|
using ExternalRefsMap = std::map<yul::Identifier const*, InlineAssemblyAnnotation::ExternalIdentifierInfo>;
|
||||||
@ -3363,8 +3376,16 @@ void IRGeneratorForStatements::revertWithError(
|
|||||||
vector<ASTPointer<Expression const>> const& _errorArguments
|
vector<ASTPointer<Expression const>> const& _errorArguments
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
bool needsAllocation = true;
|
||||||
|
if (optional<size_t> size = staticEncodingSize(_parameterTypes))
|
||||||
|
if (ranges::all_of(_parameterTypes, [](auto const* type) { return type && type->isValueType(); }))
|
||||||
|
needsAllocation = *size + 4 > CompilerUtils::generalPurposeMemoryStart;
|
||||||
Whiskers templ(R"({
|
Whiskers templ(R"({
|
||||||
|
<?needsAllocation>
|
||||||
let <pos> := <allocateUnbounded>()
|
let <pos> := <allocateUnbounded>()
|
||||||
|
<!needsAllocation>
|
||||||
|
let <pos> := 0
|
||||||
|
</needsAllocation>
|
||||||
mstore(<pos>, <hash>)
|
mstore(<pos>, <hash>)
|
||||||
let <end> := <encode>(add(<pos>, 4) <argumentVars>)
|
let <end> := <encode>(add(<pos>, 4) <argumentVars>)
|
||||||
revert(<pos>, sub(<end>, <pos>))
|
revert(<pos>, sub(<end>, <pos>))
|
||||||
@ -3372,7 +3393,9 @@ void IRGeneratorForStatements::revertWithError(
|
|||||||
templ("pos", m_context.newYulVariable());
|
templ("pos", m_context.newYulVariable());
|
||||||
templ("end", m_context.newYulVariable());
|
templ("end", m_context.newYulVariable());
|
||||||
templ("hash", util::selectorFromSignatureU256(_signature).str());
|
templ("hash", util::selectorFromSignatureU256(_signature).str());
|
||||||
templ("allocateUnbounded", m_utils.allocateUnboundedFunction());
|
templ("needsAllocation", needsAllocation);
|
||||||
|
if (needsAllocation)
|
||||||
|
templ("allocateUnbounded", m_utils.allocateUnboundedFunction());
|
||||||
|
|
||||||
vector<string> errorArgumentVars;
|
vector<string> errorArgumentVars;
|
||||||
vector<Type const*> errorArgumentTypes;
|
vector<Type const*> errorArgumentTypes;
|
||||||
|
@ -14,6 +14,6 @@ contract B {
|
|||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// f() -> FAILURE, hex"92bbf6e8"
|
// f() -> FAILURE, hex"92bbf6e8"
|
||||||
// gas irOptimized: 274265
|
// gas irOptimized: 270934
|
||||||
// gas legacy: 310592
|
// gas legacy: 310592
|
||||||
// gas legacyOptimized: 273662
|
// gas legacyOptimized: 273662
|
||||||
|
Loading…
Reference in New Issue
Block a user