mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #11270 from ethereum/addingBoundsByteArraySolYul
This commit is contained in:
commit
8840fb6ffd
@ -1209,31 +1209,24 @@ std::string YulUtilFunctions::resizeArrayFunction(ArrayType const& _type)
|
|||||||
string YulUtilFunctions::resizeDynamicByteArrayFunction(ArrayType const& _type)
|
string YulUtilFunctions::resizeDynamicByteArrayFunction(ArrayType const& _type)
|
||||||
{
|
{
|
||||||
string functionName = "resize_array_" + _type.identifier();
|
string functionName = "resize_array_" + _type.identifier();
|
||||||
return m_functionCollector.createFunction(functionName, [&]() {
|
return m_functionCollector.createFunction(functionName, [&](vector<string>& _args, vector<string>&) {
|
||||||
|
_args = {"array", "newLen"};
|
||||||
return Whiskers(R"(
|
return Whiskers(R"(
|
||||||
function <functionName>(array, newLen) {
|
let data := sload(array)
|
||||||
if gt(newLen, <maxArrayLength>) {
|
let oldLen := <extractLength>(data)
|
||||||
<panic>()
|
|
||||||
}
|
|
||||||
|
|
||||||
let data := sload(array)
|
if gt(newLen, oldLen) {
|
||||||
let oldLen := <extractLength>(data)
|
<increaseSize>(array, data, oldLen, newLen)
|
||||||
|
}
|
||||||
|
|
||||||
if gt(newLen, oldLen) {
|
if lt(newLen, oldLen) {
|
||||||
<increaseSize>(array, data, oldLen, newLen)
|
<decreaseSize>(array, data, oldLen, newLen)
|
||||||
}
|
}
|
||||||
|
)")
|
||||||
if lt(newLen, oldLen) {
|
("extractLength", extractByteArrayLengthFunction())
|
||||||
<decreaseSize>(array, data, oldLen, newLen)
|
("decreaseSize", decreaseByteArraySizeFunction(_type))
|
||||||
}
|
("increaseSize", increaseByteArraySizeFunction(_type))
|
||||||
})")
|
.render();
|
||||||
("functionName", functionName)
|
|
||||||
("panic", panicFunction(PanicCode::ResourceError))
|
|
||||||
("extractLength", extractByteArrayLengthFunction())
|
|
||||||
("maxArrayLength", (u256(1) << 64).str())
|
|
||||||
("decreaseSize", decreaseByteArraySizeFunction(_type))
|
|
||||||
("increaseSize", increaseByteArraySizeFunction(_type))
|
|
||||||
.render();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1282,32 +1275,35 @@ string YulUtilFunctions::decreaseByteArraySizeFunction(ArrayType const& _type)
|
|||||||
string YulUtilFunctions::increaseByteArraySizeFunction(ArrayType const& _type)
|
string YulUtilFunctions::increaseByteArraySizeFunction(ArrayType const& _type)
|
||||||
{
|
{
|
||||||
string functionName = "byte_array_increase_size_" + _type.identifier();
|
string functionName = "byte_array_increase_size_" + _type.identifier();
|
||||||
return m_functionCollector.createFunction(functionName, [&]() {
|
return m_functionCollector.createFunction(functionName, [&](vector<string>& _args, vector<string>&) {
|
||||||
|
_args = {"array", "data", "oldLen", "newLen"};
|
||||||
return Whiskers(R"(
|
return Whiskers(R"(
|
||||||
function <functionName>(array, data, oldLen, newLen) {
|
if gt(newLen, <maxArrayLength>) { <panic>() }
|
||||||
switch lt(oldLen, 32)
|
|
||||||
|
switch lt(oldLen, 32)
|
||||||
|
case 0 {
|
||||||
|
// in this case array stays unpacked, so we just set new length
|
||||||
|
sstore(array, add(mul(2, newLen), 1))
|
||||||
|
}
|
||||||
|
default {
|
||||||
|
switch lt(newLen, 32)
|
||||||
case 0 {
|
case 0 {
|
||||||
// in this case array stays unpacked, so we just set new length
|
// we need to copy elements to data area as we changed array from packed to unpacked
|
||||||
|
data := and(not(0xff), data)
|
||||||
|
sstore(<dataPosition>(array), data)
|
||||||
sstore(array, add(mul(2, newLen), 1))
|
sstore(array, add(mul(2, newLen), 1))
|
||||||
}
|
}
|
||||||
default {
|
default {
|
||||||
switch lt(newLen, 32)
|
// here array stays packed, we just need to increase length
|
||||||
case 0 {
|
sstore(array, <encodeUsedSetLen>(data, newLen))
|
||||||
// we need to copy elements to data area as we changed array from packed to unpacked
|
|
||||||
data := and(not(0xff), data)
|
|
||||||
sstore(<dataPosition>(array), data)
|
|
||||||
sstore(array, add(mul(2, newLen), 1))
|
|
||||||
}
|
|
||||||
default {
|
|
||||||
// here array stays packed, we just need to increase length
|
|
||||||
sstore(array, <encodeUsedSetLen>(data, newLen))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})")
|
}
|
||||||
("functionName", functionName)
|
)")
|
||||||
("dataPosition", arrayDataAreaFunction(_type))
|
("panic", panicFunction(PanicCode::ResourceError))
|
||||||
("encodeUsedSetLen", shortByteArrayEncodeUsedAreaSetLengthFunction())
|
("maxArrayLength", (u256(1) << 64).str())
|
||||||
.render();
|
("dataPosition", arrayDataAreaFunction(_type))
|
||||||
|
("encodeUsedSetLen", shortByteArrayEncodeUsedAreaSetLengthFunction())
|
||||||
|
.render();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ contract C {
|
|||||||
// ----
|
// ----
|
||||||
// l() -> 0
|
// l() -> 0
|
||||||
// g(uint256): 70 ->
|
// g(uint256): 70 ->
|
||||||
// gas irOptimized: 429679
|
// gas irOptimized: 434229
|
||||||
// gas legacy: 419791
|
// gas legacy: 419791
|
||||||
// gas legacyOptimized: 415408
|
// gas legacyOptimized: 415408
|
||||||
// l() -> 70
|
// l() -> 70
|
||||||
|
Loading…
Reference in New Issue
Block a user