Use index into m_asm->items() to modify free memory push.

This commit is contained in:
Daniel Kirchner 2021-09-08 12:51:13 +02:00
parent abf0e47e0a
commit 0f09b850fc
7 changed files with 24 additions and 17 deletions

View File

@ -62,9 +62,6 @@ public:
AssemblyItem(u256 _push, langutil::SourceLocation _location = langutil::SourceLocation()): AssemblyItem(u256 _push, langutil::SourceLocation _location = langutil::SourceLocation()):
AssemblyItem(Push, std::move(_push), std::move(_location)) { } AssemblyItem(Push, std::move(_push), std::move(_location)) { }
/// Used only for the free memory pointer as "memoryguard". Should probably be replaced by a separate AssemblyItemType.
AssemblyItem(std::shared_ptr<u256> _pushData, langutil::SourceLocation _location = langutil::SourceLocation()):
m_type(Push), m_data(std::move(_pushData)), m_location(std::move(_location)) { }
AssemblyItem(Instruction _i, langutil::SourceLocation _location = langutil::SourceLocation()): AssemblyItem(Instruction _i, langutil::SourceLocation _location = langutil::SourceLocation()):
m_type(Operation), m_type(Operation),
m_instruction(_i), m_instruction(_i),

View File

@ -545,7 +545,13 @@ void CompilerContext::optimizeYul(
bool const isCreation = runtimeContext() != nullptr; bool const isCreation = runtimeContext() != nullptr;
yul::GasMeter meter(_dialect, isCreation, _optimiserSettings.expectedExecutionsPerDeployment); yul::GasMeter meter(_dialect, isCreation, _optimiserSettings.expectedExecutionsPerDeployment);
unique_ptr<u256> freeMemoryInitPushValue;
if (_system)
{
solAssert(m_freeMemoryInitPush, ""); solAssert(m_freeMemoryInitPush, "");
solAssert(m_asm->items().size() > *m_freeMemoryInitPush, "");
freeMemoryInitPushValue = make_unique<u256>(m_asm->items().at(*m_freeMemoryInitPush).data());
}
yul::OptimiserSuite::run( yul::OptimiserSuite::run(
_dialect, _dialect,
&meter, &meter,
@ -554,8 +560,10 @@ void CompilerContext::optimizeYul(
_optimiserSettings.yulOptimiserSteps, _optimiserSettings.yulOptimiserSteps,
isCreation? nullopt : make_optional(_optimiserSettings.expectedExecutionsPerDeployment), isCreation? nullopt : make_optional(_optimiserSettings.expectedExecutionsPerDeployment),
_externalIdentifiers, _externalIdentifiers,
_system ? m_freeMemoryInitPush : shared_ptr<u256>{} freeMemoryInitPushValue.get()
); );
if (_system)
m_asm->items().at(*m_freeMemoryInitPush).setData(*freeMemoryInitPushValue);
#ifdef SOL_OUTPUT_ASM #ifdef SOL_OUTPUT_ASM
cout << "After optimizer:" << endl; cout << "After optimizer:" << endl;
@ -572,6 +580,12 @@ string CompilerContext::revertReasonIfDebug(string const& _message)
); );
} }
void CompilerContext::appendFreeMemoryInitPush(u256 _value)
{
m_freeMemoryInitPush = m_asm->items().size();
m_asm->append(AssemblyItem(_value));
}
void CompilerContext::updateSourceLocation() void CompilerContext::updateSourceLocation()
{ {
m_asm->setSourceLocation(m_visitedNodes.empty() ? SourceLocation() : m_visitedNodes.top()->location()); m_asm->setSourceLocation(m_visitedNodes.empty() ? SourceLocation() : m_visitedNodes.top()->location());

View File

@ -315,11 +315,7 @@ public:
RevertStrings revertStrings() const { return m_revertStrings; } RevertStrings revertStrings() const { return m_revertStrings; }
evmasm::AssemblyItem makeFreeMemoryInitPush(u256 _value) void appendFreeMemoryInitPush(u256 _value);
{
m_freeMemoryInitPush = std::make_shared<u256>(_value);
return evmasm::AssemblyItem(m_freeMemoryInitPush);
}
private: private:
/// Updates source location set in the assembly. /// Updates source location set in the assembly.
@ -406,8 +402,8 @@ private:
std::queue<std::tuple<std::string, unsigned, unsigned, std::function<void(CompilerContext&)>>> m_lowLevelFunctionGenerationQueue; std::queue<std::tuple<std::string, unsigned, unsigned, std::function<void(CompilerContext&)>>> m_lowLevelFunctionGenerationQueue;
/// Flag to check that appendYulUtilityFunctions() was called exactly once /// Flag to check that appendYulUtilityFunctions() was called exactly once
bool m_appendYulUtilityFunctionsRan = false; bool m_appendYulUtilityFunctionsRan = false;
/// The assembly item that pushes the initial value of the free memory pointer. /// The index of the assembly item that pushes the initial value of the free memory pointer.
std::shared_ptr<u256> m_freeMemoryInitPush; std::optional<size_t> m_freeMemoryInitPush;
}; };
} }

View File

@ -55,7 +55,7 @@ void CompilerUtils::initialiseFreeMemoryPointer()
{ {
size_t reservedMemory = m_context.reservedMemory(); size_t reservedMemory = m_context.reservedMemory();
solAssert(bigint(generalPurposeMemoryStart) + bigint(reservedMemory) < bigint(1) << 63, ""); solAssert(bigint(generalPurposeMemoryStart) + bigint(reservedMemory) < bigint(1) << 63, "");
m_context << m_context.makeFreeMemoryInitPush((u256(generalPurposeMemoryStart) + reservedMemory)); m_context.appendFreeMemoryInitPush((u256(generalPurposeMemoryStart) + reservedMemory));
storeFreeMemoryPointer(); storeFreeMemoryPointer();
} }

View File

@ -41,7 +41,7 @@ struct OptimiserStepContext
std::set<YulString> const& reservedIdentifiers; std::set<YulString> const& reservedIdentifiers;
/// The value nullopt represents creation code /// The value nullopt represents creation code
std::optional<size_t> expectedExecutionsPerDeployment; std::optional<size_t> expectedExecutionsPerDeployment;
std::shared_ptr<u256> externalFreeMemoryPointerInitializer{}; u256* externalFreeMemoryPointerInitializer = nullptr;
}; };

View File

@ -90,7 +90,7 @@ void OptimiserSuite::run(
string const& _optimisationSequence, string const& _optimisationSequence,
optional<size_t> _expectedExecutionsPerDeployment, optional<size_t> _expectedExecutionsPerDeployment,
set<YulString> const& _externallyUsedIdentifiers, set<YulString> const& _externallyUsedIdentifiers,
std::shared_ptr<u256> _externalFreeMemoryPointerInitializer u256* _externalFreeMemoryPointerInitializer
) )
{ {
EVMDialect const* evmDialect = dynamic_cast<EVMDialect const*>(&_dialect); EVMDialect const* evmDialect = dynamic_cast<EVMDialect const*>(&_dialect);

View File

@ -67,7 +67,7 @@ public:
std::string const& _optimisationSequence, std::string const& _optimisationSequence,
std::optional<size_t> _expectedExecutionsPerDeployment, std::optional<size_t> _expectedExecutionsPerDeployment,
std::set<YulString> const& _externallyUsedIdentifiers = {}, std::set<YulString> const& _externallyUsedIdentifiers = {},
std::shared_ptr<u256> _externalFreeMemoryPointerInitializer = {} u256* _externalFreeMemoryPointerInitializer = nullptr
); );
/// Ensures that specified sequence of step abbreviations is well-formed and can be executed. /// Ensures that specified sequence of step abbreviations is well-formed and can be executed.
@ -93,7 +93,7 @@ private:
Debug _debug, Debug _debug,
Block& _ast, Block& _ast,
std::optional<size_t> expectedExecutionsPerDeployment, std::optional<size_t> expectedExecutionsPerDeployment,
std::shared_ptr<u256> _externalFreeMemoryPointerInitializer = {} u256* _externalFreeMemoryPointerInitializer = nullptr
): ):
m_dispenser{_dialect, _ast, _externallyUsedIdentifiers}, m_dispenser{_dialect, _ast, _externallyUsedIdentifiers},