[Sol->Yul] Implementing deleting storage structs

This commit is contained in:
Djordje Mijovic 2020-09-18 12:37:38 +02:00
parent 3ede1f1bca
commit 700390a68b
2 changed files with 54 additions and 0 deletions

View File

@ -1147,6 +1147,45 @@ string YulUtilFunctions::clearStorageArrayFunction(ArrayType const& _type)
});
}
string YulUtilFunctions::clearStorageStructFunction(StructType const& _type)
{
solAssert(_type.location() == DataLocation::Storage, "");
string functionName = "clear_struct_storage_" + _type.identifier();
return m_functionCollector.createFunction(functionName, [&] {
MemberList::MemberMap structMembers = _type.nativeMembers(nullptr);
vector<map<string, string>> memberSetValues;
for (auto const& member: structMembers)
{
auto const& [memberSlotDiff, memberStorageOffset] = _type.storageOffsetsOfMember(member.name);
memberSetValues.emplace_back().emplace("clearMember", Whiskers(R"(
<setZero>(add(slot, <memberSlotDiff>), <memberStorageOffset>)
)")
("setZero", storageSetToZeroFunction(*member.type))
("memberSlotDiff", memberSlotDiff.str())
("memberStorageOffset", to_string(memberStorageOffset))
.render()
);
}
return Whiskers(R"(
function <functionName>(slot) {
<#member>
<clearMember>
</member>
}
)")
("functionName", functionName)
("allocStruct", allocateMemoryStructFunction(_type))
("storageSize", _type.storageSize().str())
("member", memberSetValues)
.render();
});
}
string YulUtilFunctions::arrayConvertLengthToSize(ArrayType const& _type)
{
string functionName = "array_convert_length_to_size_" + _type.identifier();
@ -2741,12 +2780,23 @@ string YulUtilFunctions::storageSetToZeroFunction(Type const& _type)
else if (_type.category() == Type::Category::Array)
return Whiskers(R"(
function <functionName>(slot, offset) {
if iszero(eq(offset, 0)) { panic() }
<clearArray>(slot)
}
)")
("functionName", functionName)
("clearArray", clearStorageArrayFunction(dynamic_cast<ArrayType const&>(_type)))
.render();
else if (_type.category() == Type::Category::Struct)
return Whiskers(R"(
function <functionName>(slot, offset) {
if iszero(eq(offset, 0)) { panic() }
<clearStruct>(slot)
}
)")
("functionName", functionName)
("clearStruct", clearStorageStructFunction(dynamic_cast<StructType const&>(_type)))
.render();
else
solUnimplemented("setToZero for type " + _type.identifier() + " not yet implemented!");
});

View File

@ -427,6 +427,10 @@ private:
/// signature: (slot, offset)
std::string partialClearStorageSlotFunction();
/// @returns the name of a function that will clear the given storage struct
/// signature: (slot) ->
std::string clearStorageStructFunction(StructType const& _type);
langutil::EVMVersion m_evmVersion;
RevertStrings m_revertStrings;
MultiUseYulFunctionCollector& m_functionCollector;