mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #5842 from ethereum/refactorStructEncoding
[Yul] Refactor struct encoder.
This commit is contained in:
commit
a010e45166
@ -904,6 +904,8 @@ string ABIFunctions::abiEncodingFunctionStruct(
|
|||||||
<#members>
|
<#members>
|
||||||
{
|
{
|
||||||
// <memberName>
|
// <memberName>
|
||||||
|
<preprocess>
|
||||||
|
let memberValue := <retrieveValue>
|
||||||
<encode>
|
<encode>
|
||||||
}
|
}
|
||||||
</members>
|
</members>
|
||||||
@ -932,20 +934,10 @@ string ABIFunctions::abiEncodingFunctionStruct(
|
|||||||
bool dynamicMember = memberTypeTo->isDynamicallyEncoded();
|
bool dynamicMember = memberTypeTo->isDynamicallyEncoded();
|
||||||
if (dynamicMember)
|
if (dynamicMember)
|
||||||
solAssert(dynamic, "");
|
solAssert(dynamic, "");
|
||||||
Whiskers memberTempl(R"(
|
|
||||||
<preprocess>
|
members.push_back({});
|
||||||
let memberValue := <retrieveValue>
|
members.back()["preprocess"] = "";
|
||||||
)" + (
|
|
||||||
dynamicMember ?
|
|
||||||
string(R"(
|
|
||||||
mstore(add(pos, <encodingOffset>), sub(tail, pos))
|
|
||||||
tail := <abiEncode>(memberValue, tail)
|
|
||||||
)") :
|
|
||||||
string(R"(
|
|
||||||
<abiEncode>(memberValue, add(pos, <encodingOffset>))
|
|
||||||
)")
|
|
||||||
)
|
|
||||||
);
|
|
||||||
if (fromStorage)
|
if (fromStorage)
|
||||||
{
|
{
|
||||||
solAssert(memberTypeFrom->isValueType() == memberTypeTo->isValueType(), "");
|
solAssert(memberTypeFrom->isValueType() == memberTypeTo->isValueType(), "");
|
||||||
@ -956,36 +948,42 @@ string ABIFunctions::abiEncodingFunctionStruct(
|
|||||||
{
|
{
|
||||||
if (storageSlotOffset != previousSlotOffset)
|
if (storageSlotOffset != previousSlotOffset)
|
||||||
{
|
{
|
||||||
memberTempl("preprocess", "slotValue := sload(add(value, " + toCompactHexWithPrefix(storageSlotOffset) + "))");
|
members.back()["preprocess"] = "slotValue := sload(add(value, " + toCompactHexWithPrefix(storageSlotOffset) + "))";
|
||||||
previousSlotOffset = storageSlotOffset;
|
previousSlotOffset = storageSlotOffset;
|
||||||
}
|
}
|
||||||
else
|
members.back()["retrieveValue"] = shiftRightFunction(intraSlotOffset * 8) + "(slotValue)";
|
||||||
memberTempl("preprocess", "");
|
|
||||||
memberTempl("retrieveValue", shiftRightFunction(intraSlotOffset * 8) + "(slotValue)");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
solAssert(memberTypeFrom->dataStoredIn(DataLocation::Storage), "");
|
solAssert(memberTypeFrom->dataStoredIn(DataLocation::Storage), "");
|
||||||
solAssert(intraSlotOffset == 0, "");
|
solAssert(intraSlotOffset == 0, "");
|
||||||
memberTempl("preprocess", "");
|
members.back()["retrieveValue"] = "add(value, " + toCompactHexWithPrefix(storageSlotOffset) + ")";
|
||||||
memberTempl("retrieveValue", "add(value, " + toCompactHexWithPrefix(storageSlotOffset) + ")");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memberTempl("preprocess", "");
|
|
||||||
string sourceOffset = toCompactHexWithPrefix(_from.memoryOffsetOfMember(member.name));
|
string sourceOffset = toCompactHexWithPrefix(_from.memoryOffsetOfMember(member.name));
|
||||||
memberTempl("retrieveValue", "mload(add(value, " + sourceOffset + "))");
|
members.back()["retrieveValue"] = "mload(add(value, " + sourceOffset + "))";
|
||||||
}
|
}
|
||||||
memberTempl("encodingOffset", toCompactHexWithPrefix(encodingOffset));
|
|
||||||
|
Whiskers encodeTempl(
|
||||||
|
dynamicMember ?
|
||||||
|
string(R"(
|
||||||
|
mstore(add(pos, <encodingOffset>), sub(tail, pos))
|
||||||
|
tail := <abiEncode>(memberValue, tail)
|
||||||
|
)") :
|
||||||
|
string(R"(
|
||||||
|
<abiEncode>(memberValue, add(pos, <encodingOffset>))
|
||||||
|
)")
|
||||||
|
);
|
||||||
|
encodeTempl("encodingOffset", toCompactHexWithPrefix(encodingOffset));
|
||||||
encodingOffset += dynamicMember ? 0x20 : memberTypeTo->calldataEncodedSize();
|
encodingOffset += dynamicMember ? 0x20 : memberTypeTo->calldataEncodedSize();
|
||||||
|
|
||||||
EncodingOptions subOptions(_options);
|
EncodingOptions subOptions(_options);
|
||||||
subOptions.encodeFunctionFromStack = false;
|
subOptions.encodeFunctionFromStack = false;
|
||||||
memberTempl("abiEncode", abiEncodingFunction(*memberTypeFrom, *memberTypeTo, subOptions));
|
encodeTempl("abiEncode", abiEncodingFunction(*memberTypeFrom, *memberTypeTo, subOptions));
|
||||||
|
|
||||||
members.push_back({});
|
members.back()["encode"] = encodeTempl.render();
|
||||||
members.back()["encode"] = memberTempl.render();
|
|
||||||
members.back()["memberName"] = member.name;
|
members.back()["memberName"] = member.name;
|
||||||
}
|
}
|
||||||
templ("members", members);
|
templ("members", members);
|
||||||
|
Loading…
Reference in New Issue
Block a user