mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
[Sol->Yul] Implementing struct copying from calldata to storage
This commit is contained in:
parent
381784dd89
commit
762e3f3cee
@ -1427,7 +1427,7 @@ string YulUtilFunctions::readFromStorage(Type const& _type, size_t _offset, bool
|
|||||||
bool isStruct = structMembers[i].type->category() == Type::Category::Struct;
|
bool isStruct = structMembers[i].type->category() == Type::Category::Struct;
|
||||||
|
|
||||||
memberSetValues[i]["setMember"] = Whiskers(R"(
|
memberSetValues[i]["setMember"] = Whiskers(R"(
|
||||||
mstore(add(value, <memberMemoryOffset>), <readFromStorage>(add(slot, <memberSlotDiff>)<?notStruct>, <memberStorageOffset></notStruct>))
|
mstore(add(value, <memberMemoryOffset>), <readFromStorage>(add(slot, <memberSlotDiff>)<?hasOffset>, <memberStorageOffset></hasOffset>))
|
||||||
)")
|
)")
|
||||||
("memberMemoryOffset", structType.memoryOffsetOfMember(structMembers[i].name).str())
|
("memberMemoryOffset", structType.memoryOffsetOfMember(structMembers[i].name).str())
|
||||||
("memberSlotDiff", memberSlotDiff.str())
|
("memberSlotDiff", memberSlotDiff.str())
|
||||||
@ -1437,7 +1437,7 @@ string YulUtilFunctions::readFromStorage(Type const& _type, size_t _offset, bool
|
|||||||
readFromStorage(*structMembers[i].type, memberStorageOffset, true) :
|
readFromStorage(*structMembers[i].type, memberStorageOffset, true) :
|
||||||
readFromStorageDynamic(*structMembers[i].type, true)
|
readFromStorageDynamic(*structMembers[i].type, true)
|
||||||
)
|
)
|
||||||
("notStruct", !isStruct)
|
("hasOffset", !isStruct)
|
||||||
.render();
|
.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1548,11 +1548,16 @@ string YulUtilFunctions::updateStorageValueFunction(
|
|||||||
auto const& fromStructType = dynamic_cast<StructType const&>(*_fromType);
|
auto const& fromStructType = dynamic_cast<StructType const&>(*_fromType);
|
||||||
auto const& toStructType = dynamic_cast<StructType const&>(_toType);
|
auto const& toStructType = dynamic_cast<StructType const&>(_toType);
|
||||||
solAssert(fromStructType.structDefinition() == toStructType.structDefinition(), "");
|
solAssert(fromStructType.structDefinition() == toStructType.structDefinition(), "");
|
||||||
solUnimplementedAssert(fromStructType.location() == DataLocation::Memory, "");
|
solAssert(fromStructType.location() != DataLocation::Storage, "");
|
||||||
solUnimplementedAssert(_offset.has_value() && _offset.value() == 0, "");
|
solUnimplementedAssert(_offset.has_value() && _offset.value() == 0, "");
|
||||||
|
|
||||||
Whiskers templ(R"(
|
Whiskers templ(R"(
|
||||||
function <functionName>(slot, value) {
|
function <functionName>(slot, value) {
|
||||||
|
<?fromCalldata>
|
||||||
|
let valueMem := <convertToMemory>(value)
|
||||||
|
<!fromCalldata>
|
||||||
|
let valueMem := value
|
||||||
|
</fromCalldata>
|
||||||
<#member>
|
<#member>
|
||||||
{
|
{
|
||||||
<updateMemberCall>
|
<updateMemberCall>
|
||||||
@ -1561,6 +1566,12 @@ string YulUtilFunctions::updateStorageValueFunction(
|
|||||||
}
|
}
|
||||||
)");
|
)");
|
||||||
templ("functionName", functionName);
|
templ("functionName", functionName);
|
||||||
|
templ("fromCalldata", fromStructType.location() == DataLocation::CallData);
|
||||||
|
if (fromStructType.location() == DataLocation::CallData)
|
||||||
|
templ("convertToMemory", conversionFunction(
|
||||||
|
fromStructType,
|
||||||
|
*TypeProvider::structType(toStructType.structDefinition(), DataLocation::Memory)
|
||||||
|
));
|
||||||
|
|
||||||
MemberList::MemberMap toStructMembers = toStructType.nativeMembers(nullptr);
|
MemberList::MemberMap toStructMembers = toStructType.nativeMembers(nullptr);
|
||||||
MemberList::MemberMap fromStructMembers = fromStructType.nativeMembers(nullptr);
|
MemberList::MemberMap fromStructMembers = fromStructType.nativeMembers(nullptr);
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
contract C {
|
||||||
|
struct S {
|
||||||
|
uint256 a;
|
||||||
|
uint256 b;
|
||||||
|
bytes2 c;
|
||||||
|
}
|
||||||
|
|
||||||
|
S s;
|
||||||
|
|
||||||
|
function f(uint32 a, S calldata c, uint256 b) external returns (uint256, uint256, byte) {
|
||||||
|
s = c;
|
||||||
|
return (s.a, s.b, s.c[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ====
|
||||||
|
// compileViaYul: true
|
||||||
|
// ----
|
||||||
|
// f(uint32, (uint256, uint256, bytes2), uint256): 1, 42, 23, "ab", 1 -> 42, 23, "b"
|
Loading…
Reference in New Issue
Block a user