Merge pull request #11270 from ethereum/addingBoundsByteArraySolYul

This commit is contained in:
Đorđe Mijović 2021-04-22 15:41:32 +02:00 committed by GitHub
commit 8840fb6ffd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 43 deletions

View File

@ -1209,31 +1209,24 @@ std::string YulUtilFunctions::resizeArrayFunction(ArrayType const& _type)
string YulUtilFunctions::resizeDynamicByteArrayFunction(ArrayType const& _type)
{
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"(
function <functionName>(array, newLen) {
if gt(newLen, <maxArrayLength>) {
<panic>()
}
let data := sload(array)
let oldLen := <extractLength>(data)
let data := sload(array)
let oldLen := <extractLength>(data)
if gt(newLen, oldLen) {
<increaseSize>(array, data, oldLen, newLen)
}
if gt(newLen, oldLen) {
<increaseSize>(array, data, oldLen, newLen)
}
if lt(newLen, oldLen) {
<decreaseSize>(array, data, oldLen, newLen)
}
})")
("functionName", functionName)
("panic", panicFunction(PanicCode::ResourceError))
("extractLength", extractByteArrayLengthFunction())
("maxArrayLength", (u256(1) << 64).str())
("decreaseSize", decreaseByteArraySizeFunction(_type))
("increaseSize", increaseByteArraySizeFunction(_type))
.render();
if lt(newLen, oldLen) {
<decreaseSize>(array, data, oldLen, newLen)
}
)")
("extractLength", extractByteArrayLengthFunction())
("decreaseSize", decreaseByteArraySizeFunction(_type))
("increaseSize", increaseByteArraySizeFunction(_type))
.render();
});
}
@ -1282,32 +1275,35 @@ string YulUtilFunctions::decreaseByteArraySizeFunction(ArrayType const& _type)
string YulUtilFunctions::increaseByteArraySizeFunction(ArrayType const& _type)
{
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"(
function <functionName>(array, data, oldLen, newLen) {
switch lt(oldLen, 32)
if gt(newLen, <maxArrayLength>) { <panic>() }
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 {
// 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))
}
default {
switch lt(newLen, 32)
case 0 {
// 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))
}
// here array stays packed, we just need to increase length
sstore(array, <encodeUsedSetLen>(data, newLen))
}
})")
("functionName", functionName)
("dataPosition", arrayDataAreaFunction(_type))
("encodeUsedSetLen", shortByteArrayEncodeUsedAreaSetLengthFunction())
.render();
}
)")
("panic", panicFunction(PanicCode::ResourceError))
("maxArrayLength", (u256(1) << 64).str())
("dataPosition", arrayDataAreaFunction(_type))
("encodeUsedSetLen", shortByteArrayEncodeUsedAreaSetLengthFunction())
.render();
});
}

View File

@ -23,7 +23,7 @@ contract C {
// ----
// l() -> 0
// g(uint256): 70 ->
// gas irOptimized: 429679
// gas irOptimized: 434229
// gas legacy: 419791
// gas legacyOptimized: 415408
// l() -> 70