Merge pull request #11066 from ethereum/functionCollectorrefactor

Adding additional interface to yul function collector.
This commit is contained in:
chriseth 2021-03-15 21:42:34 +01:00 committed by GitHub
commit ae1b321a2a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 12 deletions

View File

@ -23,11 +23,13 @@
#include <libsolidity/codegen/MultiUseYulFunctionCollector.h> #include <libsolidity/codegen/MultiUseYulFunctionCollector.h>
#include <liblangutil/Exceptions.h> #include <liblangutil/Exceptions.h>
#include <libsolutil/Whiskers.h>
#include <libsolutil/StringUtils.h>
using namespace std; using namespace std;
using namespace solidity; using namespace solidity;
using namespace solidity::frontend; using namespace solidity::frontend;
using namespace solidity::util;
string MultiUseYulFunctionCollector::requestedFunctions() string MultiUseYulFunctionCollector::requestedFunctions()
{ {
@ -54,3 +56,31 @@ string MultiUseYulFunctionCollector::createFunction(string const& _name, functio
} }
return _name; return _name;
} }
string MultiUseYulFunctionCollector::createFunction(
string const& _name,
function<string(vector<string>&, vector<string>&)> const& _creator
)
{
solAssert(!_name.empty(), "");
if (!m_requestedFunctions.count(_name))
{
m_requestedFunctions[_name] = "<<STUB<<";
vector<string> arguments;
vector<string> returnParameters;
string body = _creator(arguments, returnParameters);
solAssert(!body.empty(), "");
m_requestedFunctions[_name] = Whiskers(R"(
function <functionName>(<args>)<?+retParams> -> <retParams></+retParams> {
<body>
}
)")
("functionName", _name)
("args", joinHumanReadable(arguments))
("retParams", joinHumanReadable(returnParameters))
("body", body)
.render();;
}
return _name;
}

View File

@ -41,6 +41,11 @@ public:
/// cases. /// cases.
std::string createFunction(std::string const& _name, std::function<std::string()> const& _creator); std::string createFunction(std::string const& _name, std::function<std::string()> const& _creator);
std::string createFunction(
std::string const& _name,
std::function<std::string(std::vector<std::string>&, std::vector<std::string>&)> const& _creator
);
/// @returns concatenation of all generated functions. /// @returns concatenation of all generated functions.
/// Guarantees that the order of functions in the generated code is deterministic and /// Guarantees that the order of functions in the generated code is deterministic and
/// platform-independent. /// platform-independent.

View File

@ -3285,9 +3285,9 @@ string YulUtilFunctions::copyStructToStorageFunction(StructType const& _from, St
"_to_" + "_to_" +
_to.identifier(); _to.identifier();
return m_functionCollector.createFunction(functionName, [&]() { return m_functionCollector.createFunction(functionName, [&](auto& _arguments, auto&) {
_arguments = {"slot", "value"};
Whiskers templ(R"( Whiskers templ(R"(
function <functionName>(slot, value) {
<?fromStorage> if iszero(eq(slot, value)) { </fromStorage> <?fromStorage> if iszero(eq(slot, value)) { </fromStorage>
<#member> <#member>
{ {
@ -3295,9 +3295,7 @@ string YulUtilFunctions::copyStructToStorageFunction(StructType const& _from, St
} }
</member> </member>
<?fromStorage> } </fromStorage> <?fromStorage> } </fromStorage>
}
)"); )");
templ("functionName", functionName);
templ("fromStorage", _from.dataStoredIn(DataLocation::Storage)); templ("fromStorage", _from.dataStoredIn(DataLocation::Storage));
MemberList::MemberMap structMembers = _from.nativeMembers(nullptr); MemberList::MemberMap structMembers = _from.nativeMembers(nullptr);
@ -3368,7 +3366,7 @@ string YulUtilFunctions::copyStructToStorageFunction(StructType const& _from, St
} }
else if (fromStorage) else if (fromStorage)
{ {
auto[srcSlotOffset, srcOffset] = _from.storageOffsetsOfMember(structMembers[i].name); auto const& [srcSlotOffset, srcOffset] = _from.storageOffsetsOfMember(structMembers[i].name);
t("memberOffset", formatNumber(srcSlotOffset)); t("memberOffset", formatNumber(srcSlotOffset));
if (memberType.isValueType()) if (memberType.isValueType())
t("read", readFromStorageValueType(memberType, srcOffset, false)); t("read", readFromStorageValueType(memberType, srcOffset, false));