mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Extract storing length to its own function.
This commit is contained in:
parent
d3820aa833
commit
49f8fa4cfe
@ -621,12 +621,12 @@ string ABIFunctions::abiEncodingFunctionCalldataArray(
|
|||||||
Whiskers templ(R"(
|
Whiskers templ(R"(
|
||||||
// <readableTypeNameFrom> -> <readableTypeNameTo>
|
// <readableTypeNameFrom> -> <readableTypeNameTo>
|
||||||
function <functionName>(start, length, pos) -> end {
|
function <functionName>(start, length, pos) -> end {
|
||||||
<storeLength> // might update pos
|
pos := <storeLength>(pos, length)
|
||||||
<copyFun>(start, pos, length)
|
<copyFun>(start, pos, length)
|
||||||
end := add(pos, <roundUpFun>(length))
|
end := add(pos, <roundUpFun>(length))
|
||||||
}
|
}
|
||||||
)");
|
)");
|
||||||
templ("storeLength", _to.isDynamicallySized() ? "mstore(pos, length) pos := add(pos, 0x20)" : "");
|
templ("storeLength", arrayStoreLengthForEncodingFunction(toArrayType));
|
||||||
templ("functionName", functionName);
|
templ("functionName", functionName);
|
||||||
templ("readableTypeNameFrom", _from.toString(true));
|
templ("readableTypeNameFrom", _from.toString(true));
|
||||||
templ("readableTypeNameTo", _to.toString(true));
|
templ("readableTypeNameTo", _to.toString(true));
|
||||||
@ -665,7 +665,7 @@ string ABIFunctions::abiEncodingFunctionSimpleArray(
|
|||||||
// <readableTypeNameFrom> -> <readableTypeNameTo>
|
// <readableTypeNameFrom> -> <readableTypeNameTo>
|
||||||
function <functionName>(value, pos) <return> {
|
function <functionName>(value, pos) <return> {
|
||||||
let length := <lengthFun>(value)
|
let length := <lengthFun>(value)
|
||||||
<storeLength> // might update pos
|
pos := <storeLength>(pos, length)
|
||||||
let headStart := pos
|
let headStart := pos
|
||||||
let tail := add(pos, mul(length, 0x20))
|
let tail := add(pos, mul(length, 0x20))
|
||||||
let srcPtr := <dataAreaFun>(value)
|
let srcPtr := <dataAreaFun>(value)
|
||||||
@ -684,7 +684,7 @@ string ABIFunctions::abiEncodingFunctionSimpleArray(
|
|||||||
// <readableTypeNameFrom> -> <readableTypeNameTo>
|
// <readableTypeNameFrom> -> <readableTypeNameTo>
|
||||||
function <functionName>(value, pos) <return> {
|
function <functionName>(value, pos) <return> {
|
||||||
let length := <lengthFun>(value)
|
let length := <lengthFun>(value)
|
||||||
<storeLength> // might update pos
|
pos := <storeLength>(pos, length)
|
||||||
let srcPtr := <dataAreaFun>(value)
|
let srcPtr := <dataAreaFun>(value)
|
||||||
for { let i := 0 } lt(i, length) { i := add(i, 1) }
|
for { let i := 0 } lt(i, length) { i := add(i, 1) }
|
||||||
{
|
{
|
||||||
@ -702,10 +702,7 @@ string ABIFunctions::abiEncodingFunctionSimpleArray(
|
|||||||
templ("return", dynamic ? " -> end " : "");
|
templ("return", dynamic ? " -> end " : "");
|
||||||
templ("assignEnd", dynamic ? "end := pos" : "");
|
templ("assignEnd", dynamic ? "end := pos" : "");
|
||||||
templ("lengthFun", arrayLengthFunction(_from));
|
templ("lengthFun", arrayLengthFunction(_from));
|
||||||
if (_to.isDynamicallySized())
|
templ("storeLength", arrayStoreLengthForEncodingFunction(_to));
|
||||||
templ("storeLength", "mstore(pos, length) pos := add(pos, 0x20)");
|
|
||||||
else
|
|
||||||
templ("storeLength", "");
|
|
||||||
templ("dataAreaFun", arrayDataAreaFunction(_from));
|
templ("dataAreaFun", arrayDataAreaFunction(_from));
|
||||||
templ("elementEncodedSize", toCompactHexWithPrefix(_to.baseType()->calldataEncodedSize()));
|
templ("elementEncodedSize", toCompactHexWithPrefix(_to.baseType()->calldataEncodedSize()));
|
||||||
|
|
||||||
@ -828,7 +825,7 @@ string ABIFunctions::abiEncodingFunctionCompactStorageArray(
|
|||||||
// <readableTypeNameFrom> -> <readableTypeNameTo>
|
// <readableTypeNameFrom> -> <readableTypeNameTo>
|
||||||
function <functionName>(value, pos) <return> {
|
function <functionName>(value, pos) <return> {
|
||||||
let length := <lengthFun>(value)
|
let length := <lengthFun>(value)
|
||||||
<storeLength> // might update pos
|
pos := <storeLength>(pos, length)
|
||||||
let originalPos := pos
|
let originalPos := pos
|
||||||
let srcPtr := <dataArea>(value)
|
let srcPtr := <dataArea>(value)
|
||||||
for { let i := 0 } lt(i, length) { i := add(i, <itemsPerSlot>) }
|
for { let i := 0 } lt(i, length) { i := add(i, <itemsPerSlot>) }
|
||||||
@ -851,10 +848,7 @@ string ABIFunctions::abiEncodingFunctionCompactStorageArray(
|
|||||||
templ("return", dynamic ? " -> end " : "");
|
templ("return", dynamic ? " -> end " : "");
|
||||||
templ("assignEnd", dynamic ? "end := pos" : "");
|
templ("assignEnd", dynamic ? "end := pos" : "");
|
||||||
templ("lengthFun", arrayLengthFunction(_from));
|
templ("lengthFun", arrayLengthFunction(_from));
|
||||||
if (_to.isDynamicallySized())
|
templ("storeLength", arrayStoreLengthForEncodingFunction(_to));
|
||||||
templ("storeLength", "mstore(pos, length) pos := add(pos, 0x20)");
|
|
||||||
else
|
|
||||||
templ("storeLength", "");
|
|
||||||
templ("dataArea", arrayDataAreaFunction(_from));
|
templ("dataArea", arrayDataAreaFunction(_from));
|
||||||
templ("itemsPerSlot", to_string(itemsPerSlot));
|
templ("itemsPerSlot", to_string(itemsPerSlot));
|
||||||
string elementEncodedSize = toCompactHexWithPrefix(_to.baseType()->calldataEncodedSize());
|
string elementEncodedSize = toCompactHexWithPrefix(_to.baseType()->calldataEncodedSize());
|
||||||
@ -1686,6 +1680,30 @@ string ABIFunctions::nextArrayElementFunction(ArrayType const& _type)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string ABIFunctions::arrayStoreLengthForEncodingFunction(ArrayType const& _type)
|
||||||
|
{
|
||||||
|
string functionName = "array_storeLengthForEncoding_" + _type.identifier();
|
||||||
|
return createFunction(functionName, [&]() {
|
||||||
|
if (_type.isDynamicallySized())
|
||||||
|
return Whiskers(R"(
|
||||||
|
function <functionName>(pos, length) -> updated_pos {
|
||||||
|
mstore(pos, length)
|
||||||
|
updated_pos := add(pos, 0x20)
|
||||||
|
}
|
||||||
|
)")
|
||||||
|
("functionName", functionName)
|
||||||
|
.render();
|
||||||
|
else
|
||||||
|
return Whiskers(R"(
|
||||||
|
function <functionName>(pos, length) -> updated_pos {
|
||||||
|
updated_pos := pos
|
||||||
|
}
|
||||||
|
)")
|
||||||
|
("functionName", functionName)
|
||||||
|
.render();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
string ABIFunctions::allocationFunction()
|
string ABIFunctions::allocationFunction()
|
||||||
{
|
{
|
||||||
string functionName = "allocateMemory";
|
string functionName = "allocateMemory";
|
||||||
|
@ -231,6 +231,11 @@ private:
|
|||||||
/// Only works for memory arrays and storage arrays that store one item per slot.
|
/// Only works for memory arrays and storage arrays that store one item per slot.
|
||||||
std::string nextArrayElementFunction(ArrayType const& _type);
|
std::string nextArrayElementFunction(ArrayType const& _type);
|
||||||
|
|
||||||
|
/// @returns the name of a function used during encoding that stores the length
|
||||||
|
/// if the array is dynamically sized. It returns the new encoding position.
|
||||||
|
/// If the array is not dynamically sized, does nothing and just returns the position again.
|
||||||
|
std::string arrayStoreLengthForEncodingFunction(ArrayType const& _type);
|
||||||
|
|
||||||
/// @returns the name of a function that allocates memory.
|
/// @returns the name of a function that allocates memory.
|
||||||
/// Modifies the "free memory pointer"
|
/// Modifies the "free memory pointer"
|
||||||
/// Arguments: size
|
/// Arguments: size
|
||||||
|
Loading…
Reference in New Issue
Block a user