From 90fa56c7191d4353d8cdbc778c0f71a4459f4a56 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Mon, 2 Mar 2020 16:32:30 +0100 Subject: [PATCH 1/3] Allow use of yul util functions in legacy code generation. --- libsolidity/codegen/ABIFunctions.cpp | 11 +--------- libsolidity/codegen/ABIFunctions.h | 7 ------- libsolidity/codegen/CompilerContext.cpp | 14 +++++++++++++ libsolidity/codegen/CompilerContext.h | 20 ++++++++++++++++++- libsolidity/codegen/ContractCompiler.cpp | 8 ++++---- .../codegen/MultiUseYulFunctionCollector.cpp | 12 +++++++++-- .../codegen/MultiUseYulFunctionCollector.h | 19 ++++++++++++++++-- libsolidity/codegen/ir/IRGenerator.cpp | 6 +++--- 8 files changed, 68 insertions(+), 29 deletions(-) diff --git a/libsolidity/codegen/ABIFunctions.cpp b/libsolidity/codegen/ABIFunctions.cpp index 0ad044a54..b69f47346 100644 --- a/libsolidity/codegen/ABIFunctions.cpp +++ b/libsolidity/codegen/ABIFunctions.cpp @@ -240,13 +240,6 @@ string ABIFunctions::tupleDecoder(TypePointers const& _types, bool _fromMemory) }); } -pair> ABIFunctions::requestedFunctions() -{ - std::set empty; - swap(empty, m_externallyUsedFunctions); - return make_pair(m_functionCollector->requestedFunctions(), std::move(empty)); -} - string ABIFunctions::EncodingOptions::toFunctionNameSuffix() const { string suffix; @@ -1504,9 +1497,7 @@ string ABIFunctions::createFunction(string const& _name, function con string ABIFunctions::createExternallyUsedFunction(string const& _name, function const& _creator) { - string name = createFunction(_name, _creator); - m_externallyUsedFunctions.insert(name); - return name; + return m_functionCollector->createExternallyUsedFunction(_name, _creator); } size_t ABIFunctions::headSize(TypePointers const& _targetTypes) diff --git a/libsolidity/codegen/ABIFunctions.h b/libsolidity/codegen/ABIFunctions.h index ce3efe6ea..74bfdf7fa 100644 --- a/libsolidity/codegen/ABIFunctions.h +++ b/libsolidity/codegen/ABIFunctions.h @@ -104,12 +104,6 @@ public: /// stack slot, it takes exactly that number of values. std::string tupleDecoder(TypePointers const& _types, bool _fromMemory = false); - /// @returns concatenation of all generated functions and a set of the - /// externally used functions. - /// Clears the internal list, i.e. calling it again will result in an - /// empty return value. - std::pair> requestedFunctions(); - private: struct EncodingOptions { @@ -260,7 +254,6 @@ private: langutil::EVMVersion m_evmVersion; RevertStrings const m_revertStrings; std::shared_ptr m_functionCollector; - std::set m_externallyUsedFunctions; YulUtilFunctions m_utils; }; diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index 8c1099855..f65ccae52 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -94,6 +94,20 @@ void CompilerContext::callLowLevelFunction( *this << retTag.tag(); } +void CompilerContext::callYulUtilFunction( + string const& _name, + unsigned _inArgs, + unsigned _outArgs +) +{ + m_functionCollector->markAsExternallyUsed(_name); + auto retTag = pushNewTag(); + CompilerUtils(*this).moveIntoStack(_inArgs); + appendJumpTo(namedTag(_name)); + adjustStackOffset(int(_outArgs) - 1 - _inArgs); + *this << retTag.tag(); +} + evmasm::AssemblyItem CompilerContext::lowLevelFunctionTag( string const& _name, unsigned _inArgs, diff --git a/libsolidity/codegen/CompilerContext.h b/libsolidity/codegen/CompilerContext.h index c37afbfa5..d9393e23a 100644 --- a/libsolidity/codegen/CompilerContext.h +++ b/libsolidity/codegen/CompilerContext.h @@ -65,7 +65,8 @@ public: m_evmVersion(_evmVersion), m_revertStrings(_revertStrings), m_runtimeContext(_runtimeContext), - m_abiFunctions(m_evmVersion, m_revertStrings) + m_abiFunctions(m_evmVersion, m_revertStrings, m_functionCollector), + m_yulUtilFunctions(m_evmVersion, m_revertStrings, m_functionCollector) { if (m_runtimeContext) m_runtimeSub = size_t(m_asm->newSub(m_runtimeContext->m_asm).data()); @@ -131,6 +132,14 @@ public: unsigned _outArgs, std::function const& _generator ); + + /// Appends a call to a yul util function and registers the function as externally used. + void callYulUtilFunction( + std::string const& _name, + unsigned _inArgs, + unsigned _outArgs + ); + /// Returns the tag of the named low-level function and inserts the generator into the /// list of low-level-functions to be generated, unless it already exists. /// Note that the generator should not assume that objects are still alive when it is called, @@ -144,6 +153,11 @@ public: /// Generates the code for missing low-level functions, i.e. calls the generators passed above. void appendMissingLowLevelFunctions(); ABIFunctions& abiFunctions() { return m_abiFunctions; } + YulUtilFunctions& utilFunctions() { return m_yulUtilFunctions; } + std::pair> requestedYulFunctions() + { + return m_functionCollector->requestedFunctions(); + } ModifierDefinition const& resolveVirtualFunctionModifier(ModifierDefinition const& _modifier) const; /// Returns the distance of the given local variable from the bottom of the stack (of the current function). @@ -355,8 +369,12 @@ private: size_t m_runtimeSub = -1; /// An index of low-level function labels by name. std::map m_lowLevelFunctions; + // Collector for yul functions. + std::shared_ptr m_functionCollector = std::make_shared(); /// Container for ABI functions to be generated. ABIFunctions m_abiFunctions; + /// Container for Yul Util functions to be generated. + YulUtilFunctions m_yulUtilFunctions; /// The queue of low-level functions to generate. std::queue>> m_lowLevelFunctionGenerationQueue; }; diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index a99aefb5f..47187b1c8 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -1267,12 +1267,12 @@ void ContractCompiler::appendMissingFunctions() solAssert(m_context.nextFunctionToCompile() != function, "Compiled the wrong function?"); } m_context.appendMissingLowLevelFunctions(); - auto abiFunctions = m_context.abiFunctions().requestedFunctions(); - if (!abiFunctions.first.empty()) + auto yulFunctions = m_context.requestedYulFunctions(); + if (!yulFunctions.first.empty()) m_context.appendInlineAssembly( - "{" + move(abiFunctions.first) + "}", + "{" + move(yulFunctions.first) + "}", {}, - abiFunctions.second, + yulFunctions.second, true, m_optimiserSettings ); diff --git a/libsolidity/codegen/MultiUseYulFunctionCollector.cpp b/libsolidity/codegen/MultiUseYulFunctionCollector.cpp index 2be3d29ae..8af292eda 100644 --- a/libsolidity/codegen/MultiUseYulFunctionCollector.cpp +++ b/libsolidity/codegen/MultiUseYulFunctionCollector.cpp @@ -30,13 +30,15 @@ using namespace std; using namespace solidity; using namespace solidity::frontend; -string MultiUseYulFunctionCollector::requestedFunctions() +pair> MultiUseYulFunctionCollector::requestedFunctions() { string result; for (auto const& f: m_requestedFunctions) result += f.second; m_requestedFunctions.clear(); - return result; + std::set empty; + swap(empty, m_externallyUsedFunctions); + return make_pair(result, std::move(empty)); } string MultiUseYulFunctionCollector::createFunction(string const& _name, function const& _creator) @@ -50,3 +52,9 @@ string MultiUseYulFunctionCollector::createFunction(string const& _name, functio } return _name; } + +string MultiUseYulFunctionCollector::createExternallyUsedFunction(string const& _name, function const& _creator) +{ + m_externallyUsedFunctions.insert(_name); + return createFunction(_name, _creator); +} diff --git a/libsolidity/codegen/MultiUseYulFunctionCollector.h b/libsolidity/codegen/MultiUseYulFunctionCollector.h index d839a31be..a1c733274 100644 --- a/libsolidity/codegen/MultiUseYulFunctionCollector.h +++ b/libsolidity/codegen/MultiUseYulFunctionCollector.h @@ -23,6 +23,7 @@ #include #include +#include #include namespace solidity::frontend @@ -40,14 +41,28 @@ public: /// cases. std::string createFunction(std::string const& _name, std::function const& _creator); - /// @returns concatenation of all generated functions. + /// Helper function that uses @a _creator to create a function and add it to + /// @a m_requestedFunctions if it has not been created yet and returns @a _name in both + /// cases. + std::string createExternallyUsedFunction(std::string const& _name, std::function const& _creator); + + /// Manually mark a function as externally used. + void markAsExternallyUsed(std::string const& _name) + { + m_externallyUsedFunctions.insert(_name); + } + + /// @returns concatenation of all generated functions and a set of the + /// externally used functions. /// Clears the internal list, i.e. calling it again will result in an /// empty return value. - std::string requestedFunctions(); + std::pair> requestedFunctions(); private: /// Map from function name to code for a multi-use function. std::map m_requestedFunctions; + // Set of externally used functions. + std::set m_externallyUsedFunctions; }; } diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index 9c2d8807c..0f2ffaf35 100644 --- a/libsolidity/codegen/ir/IRGenerator.cpp +++ b/libsolidity/codegen/ir/IRGenerator.cpp @@ -107,7 +107,7 @@ string IRGenerator::generate(ContractDefinition const& _contract) for (auto const* contract: _contract.annotation().linearizedBaseContracts) for (auto const* fun: contract->definedFunctions()) generateFunction(*fun); - t("functions", m_context.functionCollector()->requestedFunctions()); + t("functions", m_context.functionCollector()->requestedFunctions().first); resetContext(_contract); m_context.setInheritanceHierarchy(_contract.annotation().linearizedBaseContracts); @@ -116,7 +116,7 @@ string IRGenerator::generate(ContractDefinition const& _contract) for (auto const* contract: _contract.annotation().linearizedBaseContracts) for (auto const* fun: contract->definedFunctions()) generateFunction(*fun); - t("runtimeFunctions", m_context.functionCollector()->requestedFunctions()); + t("runtimeFunctions", m_context.functionCollector()->requestedFunctions().first); return t.render(); } @@ -383,7 +383,7 @@ string IRGenerator::memoryInit() void IRGenerator::resetContext(ContractDefinition const& _contract) { solAssert( - m_context.functionCollector()->requestedFunctions().empty(), + m_context.functionCollector()->requestedFunctions().first.empty(), "Reset context while it still had functions." ); m_context = IRGenerationContext(m_evmVersion, m_context.revertStrings(), m_optimiserSettings); From 24d6e6295e75ee9da587ced7471df9e89713b21b Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Mon, 2 Mar 2020 17:20:49 +0100 Subject: [PATCH 2/3] Reuse the mechanism for abi functions and move tracking of used functions to CompilerContext --- libsolidity/codegen/ABIFunctions.cpp | 11 +++-------- libsolidity/codegen/ABIFunctions.h | 6 ------ libsolidity/codegen/CompilerContext.cpp | 9 ++++++++- libsolidity/codegen/CompilerContext.h | 11 +++++++---- libsolidity/codegen/CompilerUtils.cpp | 16 +++------------- .../codegen/MultiUseYulFunctionCollector.cpp | 12 ++---------- .../codegen/MultiUseYulFunctionCollector.h | 19 ++----------------- libsolidity/codegen/ir/IRGenerator.cpp | 6 +++--- 8 files changed, 28 insertions(+), 62 deletions(-) diff --git a/libsolidity/codegen/ABIFunctions.cpp b/libsolidity/codegen/ABIFunctions.cpp index b69f47346..b6d690898 100644 --- a/libsolidity/codegen/ABIFunctions.cpp +++ b/libsolidity/codegen/ABIFunctions.cpp @@ -55,7 +55,7 @@ string ABIFunctions::tupleEncoder( functionName += t->identifier() + "_"; functionName += options.toFunctionNameSuffix(); - return createExternallyUsedFunction(functionName, [&]() { + return createFunction(functionName, [&]() { // Note that the values are in reverse due to the difference in calling semantics. Whiskers templ(R"( function (headStart ) -> tail { @@ -121,7 +121,7 @@ string ABIFunctions::tupleEncoderPacked( functionName += t->identifier() + "_"; functionName += options.toFunctionNameSuffix(); - return createExternallyUsedFunction(functionName, [&]() { + return createFunction(functionName, [&]() { solAssert(!_givenTypes.empty(), ""); // Note that the values are in reverse due to the difference in calling semantics. @@ -173,7 +173,7 @@ string ABIFunctions::tupleDecoder(TypePointers const& _types, bool _fromMemory) if (_fromMemory) functionName += "_fromMemory"; - return createExternallyUsedFunction(functionName, [&]() { + return createFunction(functionName, [&]() { TypePointers decodingTypes; for (auto const& t: _types) decodingTypes.emplace_back(t->decodingType()); @@ -1495,11 +1495,6 @@ string ABIFunctions::createFunction(string const& _name, function con return m_functionCollector->createFunction(_name, _creator); } -string ABIFunctions::createExternallyUsedFunction(string const& _name, function const& _creator) -{ - return m_functionCollector->createExternallyUsedFunction(_name, _creator); -} - size_t ABIFunctions::headSize(TypePointers const& _targetTypes) { size_t headSize = 0; diff --git a/libsolidity/codegen/ABIFunctions.h b/libsolidity/codegen/ABIFunctions.h index 74bfdf7fa..1099e3593 100644 --- a/libsolidity/codegen/ABIFunctions.h +++ b/libsolidity/codegen/ABIFunctions.h @@ -31,7 +31,6 @@ #include #include -#include #include namespace solidity::frontend @@ -233,11 +232,6 @@ private: /// cases. std::string createFunction(std::string const& _name, std::function const& _creator); - /// Helper function that uses @a _creator to create a function and add it to - /// @a m_requestedFunctions if it has not been created yet and returns @a _name in both - /// cases. Also adds it to the list of externally used functions. - std::string createExternallyUsedFunction(std::string const& _name, std::function const& _creator); - /// @returns the size of the static part of the encoding of the given types. static size_t headSize(TypePointers const& _targetTypes); diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index f65ccae52..ee12b9b3e 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -100,7 +100,7 @@ void CompilerContext::callYulUtilFunction( unsigned _outArgs ) { - m_functionCollector->markAsExternallyUsed(_name); + m_externallyUsedFunctions.insert(_name); auto retTag = pushNewTag(); CompilerUtils(*this).moveIntoStack(_inArgs); appendJumpTo(namedTag(_name)); @@ -147,6 +147,13 @@ void CompilerContext::appendMissingLowLevelFunctions() } } +pair> CompilerContext::requestedYulFunctions() +{ + set empty; + swap(empty, m_externallyUsedFunctions); + return make_pair(m_functionCollector->requestedFunctions(), std::move(empty)); +} + void CompilerContext::addVariable( VariableDeclaration const& _declaration, unsigned _offsetToCurrent diff --git a/libsolidity/codegen/CompilerContext.h b/libsolidity/codegen/CompilerContext.h index d9393e23a..6d554da82 100644 --- a/libsolidity/codegen/CompilerContext.h +++ b/libsolidity/codegen/CompilerContext.h @@ -154,10 +154,11 @@ public: void appendMissingLowLevelFunctions(); ABIFunctions& abiFunctions() { return m_abiFunctions; } YulUtilFunctions& utilFunctions() { return m_yulUtilFunctions; } - std::pair> requestedYulFunctions() - { - return m_functionCollector->requestedFunctions(); - } + /// @returns concatenation of all generated functions and a set of the + /// externally used functions. + /// Clears the internal list, i.e. calling it again will result in an + /// empty return value. + std::pair> requestedYulFunctions(); ModifierDefinition const& resolveVirtualFunctionModifier(ModifierDefinition const& _modifier) const; /// Returns the distance of the given local variable from the bottom of the stack (of the current function). @@ -371,6 +372,8 @@ private: std::map m_lowLevelFunctions; // Collector for yul functions. std::shared_ptr m_functionCollector = std::make_shared(); + /// Set of externally used yul functions. + std::set m_externallyUsedFunctions; /// Container for ABI functions to be generated. ABIFunctions m_abiFunctions; /// Container for Yul Util functions to be generated. diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index 4c75081ff..a0d38eae5 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -595,31 +595,21 @@ void CompilerUtils::abiEncodeV2( // stack: <$value0> <$value1> ... <$value(n-1)> <$headStart> - auto ret = m_context.pushNewTag(); - moveIntoStack(sizeOnStack(_givenTypes) + 1); - string encoderName = _padToWordBoundaries ? m_context.abiFunctions().tupleEncoder(_givenTypes, _targetTypes, _encodeAsLibraryTypes) : m_context.abiFunctions().tupleEncoderPacked(_givenTypes, _targetTypes); - m_context.appendJumpTo(m_context.namedTag(encoderName)); - m_context.adjustStackOffset(-int(sizeOnStack(_givenTypes)) - 1); - m_context << ret.tag(); + m_context.callYulUtilFunction(encoderName, sizeOnStack(_givenTypes) + 1, 1); } void CompilerUtils::abiDecodeV2(TypePointers const& _parameterTypes, bool _fromMemory) { // stack: [stack top] - auto ret = m_context.pushNewTag(); - moveIntoStack(2); - // stack: [stack top] m_context << Instruction::DUP2 << Instruction::ADD; m_context << Instruction::SWAP1; - // stack: + // stack: string decoderName = m_context.abiFunctions().tupleDecoder(_parameterTypes, _fromMemory); - m_context.appendJumpTo(m_context.namedTag(decoderName)); - m_context.adjustStackOffset(int(sizeOnStack(_parameterTypes)) - 3); - m_context << ret.tag(); + m_context.callYulUtilFunction(decoderName, 2, sizeOnStack(_parameterTypes)); } void CompilerUtils::zeroInitialiseMemoryArray(ArrayType const& _type) diff --git a/libsolidity/codegen/MultiUseYulFunctionCollector.cpp b/libsolidity/codegen/MultiUseYulFunctionCollector.cpp index 8af292eda..2be3d29ae 100644 --- a/libsolidity/codegen/MultiUseYulFunctionCollector.cpp +++ b/libsolidity/codegen/MultiUseYulFunctionCollector.cpp @@ -30,15 +30,13 @@ using namespace std; using namespace solidity; using namespace solidity::frontend; -pair> MultiUseYulFunctionCollector::requestedFunctions() +string MultiUseYulFunctionCollector::requestedFunctions() { string result; for (auto const& f: m_requestedFunctions) result += f.second; m_requestedFunctions.clear(); - std::set empty; - swap(empty, m_externallyUsedFunctions); - return make_pair(result, std::move(empty)); + return result; } string MultiUseYulFunctionCollector::createFunction(string const& _name, function const& _creator) @@ -52,9 +50,3 @@ string MultiUseYulFunctionCollector::createFunction(string const& _name, functio } return _name; } - -string MultiUseYulFunctionCollector::createExternallyUsedFunction(string const& _name, function const& _creator) -{ - m_externallyUsedFunctions.insert(_name); - return createFunction(_name, _creator); -} diff --git a/libsolidity/codegen/MultiUseYulFunctionCollector.h b/libsolidity/codegen/MultiUseYulFunctionCollector.h index a1c733274..d839a31be 100644 --- a/libsolidity/codegen/MultiUseYulFunctionCollector.h +++ b/libsolidity/codegen/MultiUseYulFunctionCollector.h @@ -23,7 +23,6 @@ #include #include -#include #include namespace solidity::frontend @@ -41,28 +40,14 @@ public: /// cases. std::string createFunction(std::string const& _name, std::function const& _creator); - /// Helper function that uses @a _creator to create a function and add it to - /// @a m_requestedFunctions if it has not been created yet and returns @a _name in both - /// cases. - std::string createExternallyUsedFunction(std::string const& _name, std::function const& _creator); - - /// Manually mark a function as externally used. - void markAsExternallyUsed(std::string const& _name) - { - m_externallyUsedFunctions.insert(_name); - } - - /// @returns concatenation of all generated functions and a set of the - /// externally used functions. + /// @returns concatenation of all generated functions. /// Clears the internal list, i.e. calling it again will result in an /// empty return value. - std::pair> requestedFunctions(); + std::string requestedFunctions(); private: /// Map from function name to code for a multi-use function. std::map m_requestedFunctions; - // Set of externally used functions. - std::set m_externallyUsedFunctions; }; } diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index 0f2ffaf35..9c2d8807c 100644 --- a/libsolidity/codegen/ir/IRGenerator.cpp +++ b/libsolidity/codegen/ir/IRGenerator.cpp @@ -107,7 +107,7 @@ string IRGenerator::generate(ContractDefinition const& _contract) for (auto const* contract: _contract.annotation().linearizedBaseContracts) for (auto const* fun: contract->definedFunctions()) generateFunction(*fun); - t("functions", m_context.functionCollector()->requestedFunctions().first); + t("functions", m_context.functionCollector()->requestedFunctions()); resetContext(_contract); m_context.setInheritanceHierarchy(_contract.annotation().linearizedBaseContracts); @@ -116,7 +116,7 @@ string IRGenerator::generate(ContractDefinition const& _contract) for (auto const* contract: _contract.annotation().linearizedBaseContracts) for (auto const* fun: contract->definedFunctions()) generateFunction(*fun); - t("runtimeFunctions", m_context.functionCollector()->requestedFunctions().first); + t("runtimeFunctions", m_context.functionCollector()->requestedFunctions()); return t.render(); } @@ -383,7 +383,7 @@ string IRGenerator::memoryInit() void IRGenerator::resetContext(ContractDefinition const& _contract) { solAssert( - m_context.functionCollector()->requestedFunctions().first.empty(), + m_context.functionCollector()->requestedFunctions().empty(), "Reset context while it still had functions." ); m_context = IRGenerationContext(m_evmVersion, m_context.revertStrings(), m_optimiserSettings); From 561e5d9b27439e56cbd136abecfde5727594155b Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Mon, 2 Mar 2020 17:23:58 +0100 Subject: [PATCH 3/3] Rename variables and review suggestion. --- libsolidity/codegen/CompilerContext.cpp | 10 +++++----- libsolidity/codegen/CompilerContext.h | 14 +++++++------- libsolidity/codegen/CompilerUtils.cpp | 4 ++-- libsolidity/codegen/ContractCompiler.cpp | 8 ++++---- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index ee12b9b3e..1d1eb92b9 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -94,14 +94,14 @@ void CompilerContext::callLowLevelFunction( *this << retTag.tag(); } -void CompilerContext::callYulUtilFunction( +void CompilerContext::callYulFunction( string const& _name, unsigned _inArgs, unsigned _outArgs ) { - m_externallyUsedFunctions.insert(_name); - auto retTag = pushNewTag(); + m_externallyUsedYulFunctions.insert(_name); + auto const retTag = pushNewTag(); CompilerUtils(*this).moveIntoStack(_inArgs); appendJumpTo(namedTag(_name)); adjustStackOffset(int(_outArgs) - 1 - _inArgs); @@ -150,8 +150,8 @@ void CompilerContext::appendMissingLowLevelFunctions() pair> CompilerContext::requestedYulFunctions() { set empty; - swap(empty, m_externallyUsedFunctions); - return make_pair(m_functionCollector->requestedFunctions(), std::move(empty)); + swap(empty, m_externallyUsedYulFunctions); + return make_pair(m_yulFunctionCollector->requestedFunctions(), std::move(empty)); } void CompilerContext::addVariable( diff --git a/libsolidity/codegen/CompilerContext.h b/libsolidity/codegen/CompilerContext.h index 6d554da82..76c72770d 100644 --- a/libsolidity/codegen/CompilerContext.h +++ b/libsolidity/codegen/CompilerContext.h @@ -65,8 +65,8 @@ public: m_evmVersion(_evmVersion), m_revertStrings(_revertStrings), m_runtimeContext(_runtimeContext), - m_abiFunctions(m_evmVersion, m_revertStrings, m_functionCollector), - m_yulUtilFunctions(m_evmVersion, m_revertStrings, m_functionCollector) + m_abiFunctions(m_evmVersion, m_revertStrings, m_yulFunctionCollector), + m_yulUtilFunctions(m_evmVersion, m_revertStrings, m_yulFunctionCollector) { if (m_runtimeContext) m_runtimeSub = size_t(m_asm->newSub(m_runtimeContext->m_asm).data()); @@ -133,8 +133,8 @@ public: std::function const& _generator ); - /// Appends a call to a yul util function and registers the function as externally used. - void callYulUtilFunction( + /// Appends a call to a yul function and registers the function as externally used. + void callYulFunction( std::string const& _name, unsigned _inArgs, unsigned _outArgs @@ -370,10 +370,10 @@ private: size_t m_runtimeSub = -1; /// An index of low-level function labels by name. std::map m_lowLevelFunctions; - // Collector for yul functions. - std::shared_ptr m_functionCollector = std::make_shared(); + /// Collector for yul functions. + std::shared_ptr m_yulFunctionCollector = std::make_shared(); /// Set of externally used yul functions. - std::set m_externallyUsedFunctions; + std::set m_externallyUsedYulFunctions; /// Container for ABI functions to be generated. ABIFunctions m_abiFunctions; /// Container for Yul Util functions to be generated. diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index a0d38eae5..b39633377 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -599,7 +599,7 @@ void CompilerUtils::abiEncodeV2( _padToWordBoundaries ? m_context.abiFunctions().tupleEncoder(_givenTypes, _targetTypes, _encodeAsLibraryTypes) : m_context.abiFunctions().tupleEncoderPacked(_givenTypes, _targetTypes); - m_context.callYulUtilFunction(encoderName, sizeOnStack(_givenTypes) + 1, 1); + m_context.callYulFunction(encoderName, sizeOnStack(_givenTypes) + 1, 1); } void CompilerUtils::abiDecodeV2(TypePointers const& _parameterTypes, bool _fromMemory) @@ -609,7 +609,7 @@ void CompilerUtils::abiDecodeV2(TypePointers const& _parameterTypes, bool _fromM m_context << Instruction::SWAP1; // stack: string decoderName = m_context.abiFunctions().tupleDecoder(_parameterTypes, _fromMemory); - m_context.callYulUtilFunction(decoderName, 2, sizeOnStack(_parameterTypes)); + m_context.callYulFunction(decoderName, 2, sizeOnStack(_parameterTypes)); } void CompilerUtils::zeroInitialiseMemoryArray(ArrayType const& _type) diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 47187b1c8..8b9061af3 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -1267,12 +1267,12 @@ void ContractCompiler::appendMissingFunctions() solAssert(m_context.nextFunctionToCompile() != function, "Compiled the wrong function?"); } m_context.appendMissingLowLevelFunctions(); - auto yulFunctions = m_context.requestedYulFunctions(); - if (!yulFunctions.first.empty()) + auto [yulFunctions, externallyUsedYulFunctions] = m_context.requestedYulFunctions(); + if (!yulFunctions.empty()) m_context.appendInlineAssembly( - "{" + move(yulFunctions.first) + "}", + "{" + move(yulFunctions) + "}", {}, - yulFunctions.second, + externallyUsedYulFunctions, true, m_optimiserSettings );