mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Introduce ceil division helper function.
This commit is contained in:
parent
9d156b52c4
commit
72fc4d4a32
@ -541,6 +541,18 @@ string YulUtilFunctions::roundUpFunction()
|
||||
});
|
||||
}
|
||||
|
||||
string YulUtilFunctions::divide32CeilFunction()
|
||||
{
|
||||
return m_functionCollector.createFunction(
|
||||
"divide_by_32_ceil",
|
||||
[&](vector<string>& _args, vector<string>& _ret) {
|
||||
_args = {"value"};
|
||||
_ret = {"result"};
|
||||
return "result := div(add(value, 31), 32)";
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
string YulUtilFunctions::overflowCheckedIntAddFunction(IntegerType const& _type)
|
||||
{
|
||||
string functionName = "checked_add_" + _type.identifier();
|
||||
@ -1257,14 +1269,14 @@ string YulUtilFunctions::cleanUpDynamicByteArrayEndSlotsFunction(ArrayType const
|
||||
return Whiskers(R"(
|
||||
if gt(len, 31) {
|
||||
let dataArea := <dataLocation>(array)
|
||||
let deleteStart := add(dataArea, div(<roundUp>(startIndex), 32))
|
||||
let deleteStart := add(dataArea, <div32Ceil>(startIndex))
|
||||
// If we are clearing array to be short byte array, we want to clear only data starting from array data area.
|
||||
if lt(startIndex, 32) { deleteStart := dataArea }
|
||||
<clearStorageRange>(deleteStart, add(dataArea, div(add(len, 31), 32)))
|
||||
<clearStorageRange>(deleteStart, add(dataArea, <div32Ceil>(len)))
|
||||
}
|
||||
)")
|
||||
("dataLocation", arrayDataAreaFunction(_type))
|
||||
("roundUp", roundUpFunction())
|
||||
("div32Ceil", divide32CeilFunction())
|
||||
("clearStorageRange", clearStorageRangeFunction(*_type.baseType()))
|
||||
.render();
|
||||
});
|
||||
@ -1279,13 +1291,13 @@ string YulUtilFunctions::decreaseByteArraySizeFunction(ArrayType const& _type)
|
||||
switch lt(newLen, 32)
|
||||
case 0 {
|
||||
let arrayDataStart := <dataPosition>(array)
|
||||
let deleteStart := add(arrayDataStart, div(add(newLen, 31), 32))
|
||||
let deleteStart := add(arrayDataStart, <div32Ceil>(newLen))
|
||||
|
||||
// we have to partially clear last slot that is still used
|
||||
let offset := and(newLen, 0x1f)
|
||||
if offset { <partialClearStorageSlot>(sub(deleteStart, 1), offset) }
|
||||
|
||||
<clearStorageRange>(deleteStart, add(arrayDataStart, div(add(oldLen, 31), 32)))
|
||||
<clearStorageRange>(deleteStart, add(arrayDataStart, <div32Ceil>(oldLen)))
|
||||
|
||||
sstore(array, or(mul(2, newLen), 1))
|
||||
}
|
||||
@ -1294,7 +1306,7 @@ string YulUtilFunctions::decreaseByteArraySizeFunction(ArrayType const& _type)
|
||||
case 1 {
|
||||
let arrayDataStart := <dataPosition>(array)
|
||||
// clear whole old array, as we are transforming to short bytes array
|
||||
<clearStorageRange>(add(arrayDataStart, 1), add(arrayDataStart, div(add(oldLen, 31), 32)))
|
||||
<clearStorageRange>(add(arrayDataStart, 1), add(arrayDataStart, <div32Ceil>(oldLen)))
|
||||
<transitLongToShort>(array, newLen)
|
||||
}
|
||||
default {
|
||||
@ -1307,6 +1319,7 @@ string YulUtilFunctions::decreaseByteArraySizeFunction(ArrayType const& _type)
|
||||
("partialClearStorageSlot", partialClearStorageSlotFunction())
|
||||
("clearStorageRange", clearStorageRangeFunction(*_type.baseType()))
|
||||
("transitLongToShort", byteArrayTransitLongToShortFunction(_type))
|
||||
("div32Ceil", divide32CeilFunction())
|
||||
("encodeUsedSetLen", shortByteArrayEncodeUsedAreaSetLengthFunction())
|
||||
.render();
|
||||
});
|
||||
|
@ -126,9 +126,16 @@ public:
|
||||
|
||||
/// @returns the name of a function that rounds its input to the next multiple
|
||||
/// of 32 or the input if it is a multiple of 32.
|
||||
/// Ignores overflow.
|
||||
/// signature: (value) -> result
|
||||
std::string roundUpFunction();
|
||||
|
||||
/// @returns the name of a function that divides by 32 and rounds up during the division.
|
||||
/// In other words, on input x it returns the smallest y such that y * 32 >= x.
|
||||
/// Ignores overflow.
|
||||
/// signature: (x) -> y
|
||||
std::string divide32CeilFunction();
|
||||
|
||||
/// signature: (x, y) -> sum
|
||||
std::string overflowCheckedIntAddFunction(IntegerType const& _type);
|
||||
/// signature: (x, y) -> sum
|
||||
|
Loading…
Reference in New Issue
Block a user