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 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();
}); });
} }

View File

@ -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