mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #9882 from ethereum/invalidOnErrorYul
[SolYul] Use invalid opcode for internal errors
This commit is contained in:
commit
d52b3839e2
@ -118,10 +118,10 @@ string YulUtilFunctions::requireOrAssertFunction(bool _assert, Type const* _mess
|
|||||||
if (!_messageType)
|
if (!_messageType)
|
||||||
return Whiskers(R"(
|
return Whiskers(R"(
|
||||||
function <functionName>(condition) {
|
function <functionName>(condition) {
|
||||||
if iszero(condition) { <invalidOrRevert> }
|
if iszero(condition) { <error> }
|
||||||
}
|
}
|
||||||
)")
|
)")
|
||||||
("invalidOrRevert", _assert ? "invalid()" : "revert(0, 0)")
|
("error", _assert ? panicFunction() + "()" : "revert(0, 0)")
|
||||||
("functionName", functionName)
|
("functionName", functionName)
|
||||||
.render();
|
.render();
|
||||||
|
|
||||||
@ -457,7 +457,7 @@ string YulUtilFunctions::overflowCheckedIntAddFunction(IntegerType const& _type)
|
|||||||
string functionName = "checked_add_" + _type.identifier();
|
string functionName = "checked_add_" + _type.identifier();
|
||||||
// TODO: Consider to add a special case for unsigned 256-bit integers
|
// TODO: Consider to add a special case for unsigned 256-bit integers
|
||||||
// and use the following instead:
|
// and use the following instead:
|
||||||
// sum := add(x, y) if lt(sum, x) { revert(0, 0) }
|
// sum := add(x, y) if lt(sum, x) { <panic>() }
|
||||||
return m_functionCollector.createFunction(functionName, [&]() {
|
return m_functionCollector.createFunction(functionName, [&]() {
|
||||||
return
|
return
|
||||||
Whiskers(R"(
|
Whiskers(R"(
|
||||||
@ -466,12 +466,12 @@ string YulUtilFunctions::overflowCheckedIntAddFunction(IntegerType const& _type)
|
|||||||
y := <cleanupFunction>(y)
|
y := <cleanupFunction>(y)
|
||||||
<?signed>
|
<?signed>
|
||||||
// overflow, if x >= 0 and y > (maxValue - x)
|
// overflow, if x >= 0 and y > (maxValue - x)
|
||||||
if and(iszero(slt(x, 0)), sgt(y, sub(<maxValue>, x))) { revert(0, 0) }
|
if and(iszero(slt(x, 0)), sgt(y, sub(<maxValue>, x))) { <panic>() }
|
||||||
// underflow, if x < 0 and y < (minValue - x)
|
// underflow, if x < 0 and y < (minValue - x)
|
||||||
if and(slt(x, 0), slt(y, sub(<minValue>, x))) { revert(0, 0) }
|
if and(slt(x, 0), slt(y, sub(<minValue>, x))) { <panic>() }
|
||||||
<!signed>
|
<!signed>
|
||||||
// overflow, if x > (maxValue - y)
|
// overflow, if x > (maxValue - y)
|
||||||
if gt(x, sub(<maxValue>, y)) { revert(0, 0) }
|
if gt(x, sub(<maxValue>, y)) { <panic>() }
|
||||||
</signed>
|
</signed>
|
||||||
sum := add(x, y)
|
sum := add(x, y)
|
||||||
}
|
}
|
||||||
@ -481,6 +481,7 @@ string YulUtilFunctions::overflowCheckedIntAddFunction(IntegerType const& _type)
|
|||||||
("maxValue", toCompactHexWithPrefix(u256(_type.maxValue())))
|
("maxValue", toCompactHexWithPrefix(u256(_type.maxValue())))
|
||||||
("minValue", toCompactHexWithPrefix(u256(_type.minValue())))
|
("minValue", toCompactHexWithPrefix(u256(_type.minValue())))
|
||||||
("cleanupFunction", cleanupFunction(_type))
|
("cleanupFunction", cleanupFunction(_type))
|
||||||
|
("panic", panicFunction())
|
||||||
.render();
|
.render();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -497,16 +498,16 @@ string YulUtilFunctions::overflowCheckedIntMulFunction(IntegerType const& _type)
|
|||||||
y := <cleanupFunction>(y)
|
y := <cleanupFunction>(y)
|
||||||
<?signed>
|
<?signed>
|
||||||
// overflow, if x > 0, y > 0 and x > (maxValue / y)
|
// overflow, if x > 0, y > 0 and x > (maxValue / y)
|
||||||
if and(and(sgt(x, 0), sgt(y, 0)), gt(x, div(<maxValue>, y))) { revert(0, 0) }
|
if and(and(sgt(x, 0), sgt(y, 0)), gt(x, div(<maxValue>, y))) { <panic>() }
|
||||||
// underflow, if x > 0, y < 0 and y < (minValue / x)
|
// underflow, if x > 0, y < 0 and y < (minValue / x)
|
||||||
if and(and(sgt(x, 0), slt(y, 0)), slt(y, sdiv(<minValue>, x))) { revert(0, 0) }
|
if and(and(sgt(x, 0), slt(y, 0)), slt(y, sdiv(<minValue>, x))) { <panic>() }
|
||||||
// underflow, if x < 0, y > 0 and x < (minValue / y)
|
// underflow, if x < 0, y > 0 and x < (minValue / y)
|
||||||
if and(and(slt(x, 0), sgt(y, 0)), slt(x, sdiv(<minValue>, y))) { revert(0, 0) }
|
if and(and(slt(x, 0), sgt(y, 0)), slt(x, sdiv(<minValue>, y))) { <panic>() }
|
||||||
// overflow, if x < 0, y < 0 and x < (maxValue / y)
|
// overflow, if x < 0, y < 0 and x < (maxValue / y)
|
||||||
if and(and(slt(x, 0), slt(y, 0)), slt(x, sdiv(<maxValue>, y))) { revert(0, 0) }
|
if and(and(slt(x, 0), slt(y, 0)), slt(x, sdiv(<maxValue>, y))) { <panic>() }
|
||||||
<!signed>
|
<!signed>
|
||||||
// overflow, if x != 0 and y > (maxValue / x)
|
// overflow, if x != 0 and y > (maxValue / x)
|
||||||
if and(iszero(iszero(x)), gt(y, div(<maxValue>, x))) { revert(0, 0) }
|
if and(iszero(iszero(x)), gt(y, div(<maxValue>, x))) { <panic>() }
|
||||||
</signed>
|
</signed>
|
||||||
product := mul(x, y)
|
product := mul(x, y)
|
||||||
}
|
}
|
||||||
@ -516,6 +517,7 @@ string YulUtilFunctions::overflowCheckedIntMulFunction(IntegerType const& _type)
|
|||||||
("maxValue", toCompactHexWithPrefix(u256(_type.maxValue())))
|
("maxValue", toCompactHexWithPrefix(u256(_type.maxValue())))
|
||||||
("minValue", toCompactHexWithPrefix(u256(_type.minValue())))
|
("minValue", toCompactHexWithPrefix(u256(_type.minValue())))
|
||||||
("cleanupFunction", cleanupFunction(_type))
|
("cleanupFunction", cleanupFunction(_type))
|
||||||
|
("panic", panicFunction())
|
||||||
.render();
|
.render();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -529,13 +531,13 @@ string YulUtilFunctions::overflowCheckedIntDivFunction(IntegerType const& _type)
|
|||||||
function <functionName>(x, y) -> r {
|
function <functionName>(x, y) -> r {
|
||||||
x := <cleanupFunction>(x)
|
x := <cleanupFunction>(x)
|
||||||
y := <cleanupFunction>(y)
|
y := <cleanupFunction>(y)
|
||||||
if iszero(y) { revert(0, 0) }
|
if iszero(y) { <panic>() }
|
||||||
<?signed>
|
<?signed>
|
||||||
// overflow for minVal / -1
|
// overflow for minVal / -1
|
||||||
if and(
|
if and(
|
||||||
eq(x, <minVal>),
|
eq(x, <minVal>),
|
||||||
eq(y, sub(0, 1))
|
eq(y, sub(0, 1))
|
||||||
) { revert(0, 0) }
|
) { <panic>() }
|
||||||
</signed>
|
</signed>
|
||||||
r := <?signed>s</signed>div(x, y)
|
r := <?signed>s</signed>div(x, y)
|
||||||
}
|
}
|
||||||
@ -544,6 +546,7 @@ string YulUtilFunctions::overflowCheckedIntDivFunction(IntegerType const& _type)
|
|||||||
("signed", _type.isSigned())
|
("signed", _type.isSigned())
|
||||||
("minVal", toCompactHexWithPrefix(u256(_type.minValue())))
|
("minVal", toCompactHexWithPrefix(u256(_type.minValue())))
|
||||||
("cleanupFunction", cleanupFunction(_type))
|
("cleanupFunction", cleanupFunction(_type))
|
||||||
|
("panic", panicFunction())
|
||||||
.render();
|
.render();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -557,13 +560,14 @@ string YulUtilFunctions::checkedIntModFunction(IntegerType const& _type)
|
|||||||
function <functionName>(x, y) -> r {
|
function <functionName>(x, y) -> r {
|
||||||
x := <cleanupFunction>(x)
|
x := <cleanupFunction>(x)
|
||||||
y := <cleanupFunction>(y)
|
y := <cleanupFunction>(y)
|
||||||
if iszero(y) { revert(0, 0) }
|
if iszero(y) { <panic>() }
|
||||||
r := <?signed>s</signed>mod(x, y)
|
r := <?signed>s</signed>mod(x, y)
|
||||||
}
|
}
|
||||||
)")
|
)")
|
||||||
("functionName", functionName)
|
("functionName", functionName)
|
||||||
("signed", _type.isSigned())
|
("signed", _type.isSigned())
|
||||||
("cleanupFunction", cleanupFunction(_type))
|
("cleanupFunction", cleanupFunction(_type))
|
||||||
|
("panic", panicFunction())
|
||||||
.render();
|
.render();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -579,11 +583,11 @@ string YulUtilFunctions::overflowCheckedIntSubFunction(IntegerType const& _type)
|
|||||||
y := <cleanupFunction>(y)
|
y := <cleanupFunction>(y)
|
||||||
<?signed>
|
<?signed>
|
||||||
// underflow, if y >= 0 and x < (minValue + y)
|
// underflow, if y >= 0 and x < (minValue + y)
|
||||||
if and(iszero(slt(y, 0)), slt(x, add(<minValue>, y))) { revert(0, 0) }
|
if and(iszero(slt(y, 0)), slt(x, add(<minValue>, y))) { <panic>() }
|
||||||
// overflow, if y < 0 and x > (maxValue + y)
|
// overflow, if y < 0 and x > (maxValue + y)
|
||||||
if and(slt(y, 0), sgt(x, add(<maxValue>, y))) { revert(0, 0) }
|
if and(slt(y, 0), sgt(x, add(<maxValue>, y))) { <panic>() }
|
||||||
<!signed>
|
<!signed>
|
||||||
if lt(x, y) { revert(0, 0) }
|
if lt(x, y) { <panic>() }
|
||||||
</signed>
|
</signed>
|
||||||
diff := sub(x, y)
|
diff := sub(x, y)
|
||||||
}
|
}
|
||||||
@ -593,6 +597,7 @@ string YulUtilFunctions::overflowCheckedIntSubFunction(IntegerType const& _type)
|
|||||||
("maxValue", toCompactHexWithPrefix(u256(_type.maxValue())))
|
("maxValue", toCompactHexWithPrefix(u256(_type.maxValue())))
|
||||||
("minValue", toCompactHexWithPrefix(u256(_type.minValue())))
|
("minValue", toCompactHexWithPrefix(u256(_type.minValue())))
|
||||||
("cleanupFunction", cleanupFunction(_type))
|
("cleanupFunction", cleanupFunction(_type))
|
||||||
|
("panic", panicFunction())
|
||||||
.render();
|
.render();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -660,9 +665,9 @@ string YulUtilFunctions::overflowCheckedUnsignedExpFunction()
|
|||||||
case 1 { power := 1 leave }
|
case 1 { power := 1 leave }
|
||||||
case 2
|
case 2
|
||||||
{
|
{
|
||||||
if gt(exponent, 255) { revert(0, 0) }
|
if gt(exponent, 255) { <panic>() }
|
||||||
power := exp(2, exponent)
|
power := exp(2, exponent)
|
||||||
if gt(power, max) { revert(0, 0) }
|
if gt(power, max) { <panic>() }
|
||||||
leave
|
leave
|
||||||
}
|
}
|
||||||
if or(
|
if or(
|
||||||
@ -671,17 +676,18 @@ string YulUtilFunctions::overflowCheckedUnsignedExpFunction()
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
power := exp(base, exponent)
|
power := exp(base, exponent)
|
||||||
if gt(power, max) { revert(0, 0) }
|
if gt(power, max) { <panic>() }
|
||||||
leave
|
leave
|
||||||
}
|
}
|
||||||
|
|
||||||
power, base := <expLoop>(1, base, exponent, max)
|
power, base := <expLoop>(1, base, exponent, max)
|
||||||
|
|
||||||
if gt(power, div(max, base)) { revert(0, 0) }
|
if gt(power, div(max, base)) { <panic>() }
|
||||||
power := mul(power, base)
|
power := mul(power, base)
|
||||||
}
|
}
|
||||||
)")
|
)")
|
||||||
("functionName", functionName)
|
("functionName", functionName)
|
||||||
|
("panic", panicFunction())
|
||||||
("expLoop", overflowCheckedExpLoopFunction())
|
("expLoop", overflowCheckedExpLoopFunction())
|
||||||
("shr_1", shiftRightFunction(1))
|
("shr_1", shiftRightFunction(1))
|
||||||
.render();
|
.render();
|
||||||
@ -712,8 +718,8 @@ string YulUtilFunctions::overflowCheckedSignedExpFunction()
|
|||||||
|
|
||||||
// overflow check for base * base
|
// overflow check for base * base
|
||||||
switch sgt(base, 0)
|
switch sgt(base, 0)
|
||||||
case 1 { if gt(base, div(max, base)) { revert(0, 0) } }
|
case 1 { if gt(base, div(max, base)) { <panic>() } }
|
||||||
case 0 { if slt(base, sdiv(max, base)) { revert(0, 0) } }
|
case 0 { if slt(base, sdiv(max, base)) { <panic>() } }
|
||||||
if and(exponent, 1)
|
if and(exponent, 1)
|
||||||
{
|
{
|
||||||
power := base
|
power := base
|
||||||
@ -725,12 +731,13 @@ string YulUtilFunctions::overflowCheckedSignedExpFunction()
|
|||||||
|
|
||||||
power, base := <expLoop>(power, base, exponent, max)
|
power, base := <expLoop>(power, base, exponent, max)
|
||||||
|
|
||||||
if and(sgt(power, 0), gt(power, div(max, base))) { revert(0, 0) }
|
if and(sgt(power, 0), gt(power, div(max, base))) { <panic>() }
|
||||||
if and(slt(power, 0), slt(power, sdiv(min, base))) { revert(0, 0) }
|
if and(slt(power, 0), slt(power, sdiv(min, base))) { <panic>() }
|
||||||
power := mul(power, base)
|
power := mul(power, base)
|
||||||
}
|
}
|
||||||
)")
|
)")
|
||||||
("functionName", functionName)
|
("functionName", functionName)
|
||||||
|
("panic", panicFunction())
|
||||||
("expLoop", overflowCheckedExpLoopFunction())
|
("expLoop", overflowCheckedExpLoopFunction())
|
||||||
("shr_1", shiftRightFunction(1))
|
("shr_1", shiftRightFunction(1))
|
||||||
.render();
|
.render();
|
||||||
@ -755,7 +762,7 @@ string YulUtilFunctions::overflowCheckedExpLoopFunction()
|
|||||||
for { } gt(exponent, 1) {}
|
for { } gt(exponent, 1) {}
|
||||||
{
|
{
|
||||||
// overflow check for base * base
|
// overflow check for base * base
|
||||||
if gt(base, div(max, base)) { revert(0, 0) }
|
if gt(base, div(max, base)) { <panic>() }
|
||||||
if and(exponent, 1)
|
if and(exponent, 1)
|
||||||
{
|
{
|
||||||
// No checks for power := mul(power, base) needed, because the check
|
// No checks for power := mul(power, base) needed, because the check
|
||||||
@ -771,6 +778,7 @@ string YulUtilFunctions::overflowCheckedExpLoopFunction()
|
|||||||
}
|
}
|
||||||
)")
|
)")
|
||||||
("functionName", functionName)
|
("functionName", functionName)
|
||||||
|
("panic", panicFunction())
|
||||||
("shr_1", shiftRightFunction(1))
|
("shr_1", shiftRightFunction(1))
|
||||||
.render();
|
.render();
|
||||||
});
|
});
|
||||||
@ -850,7 +858,7 @@ std::string YulUtilFunctions::resizeDynamicArrayFunction(ArrayType const& _type)
|
|||||||
return Whiskers(R"(
|
return Whiskers(R"(
|
||||||
function <functionName>(array, newLen) {
|
function <functionName>(array, newLen) {
|
||||||
if gt(newLen, <maxArrayLength>) {
|
if gt(newLen, <maxArrayLength>) {
|
||||||
invalid()
|
<panic>()
|
||||||
}
|
}
|
||||||
|
|
||||||
let oldLen := <fetchLength>(array)
|
let oldLen := <fetchLength>(array)
|
||||||
@ -869,6 +877,7 @@ std::string YulUtilFunctions::resizeDynamicArrayFunction(ArrayType const& _type)
|
|||||||
}
|
}
|
||||||
})")
|
})")
|
||||||
("functionName", functionName)
|
("functionName", functionName)
|
||||||
|
("panic", panicFunction())
|
||||||
("fetchLength", arrayLengthFunction(_type))
|
("fetchLength", arrayLengthFunction(_type))
|
||||||
("convertToSize", arrayConvertLengthToSize(_type))
|
("convertToSize", arrayConvertLengthToSize(_type))
|
||||||
("dataPosition", arrayDataAreaFunction(_type))
|
("dataPosition", arrayDataAreaFunction(_type))
|
||||||
@ -891,13 +900,14 @@ string YulUtilFunctions::storageArrayPopFunction(ArrayType const& _type)
|
|||||||
return Whiskers(R"(
|
return Whiskers(R"(
|
||||||
function <functionName>(array) {
|
function <functionName>(array) {
|
||||||
let oldLen := <fetchLength>(array)
|
let oldLen := <fetchLength>(array)
|
||||||
if iszero(oldLen) { invalid() }
|
if iszero(oldLen) { <panic>() }
|
||||||
let newLen := sub(oldLen, 1)
|
let newLen := sub(oldLen, 1)
|
||||||
let slot, offset := <indexAccess>(array, newLen)
|
let slot, offset := <indexAccess>(array, newLen)
|
||||||
<setToZero>(slot, offset)
|
<setToZero>(slot, offset)
|
||||||
sstore(array, newLen)
|
sstore(array, newLen)
|
||||||
})")
|
})")
|
||||||
("functionName", functionName)
|
("functionName", functionName)
|
||||||
|
("panic", panicFunction())
|
||||||
("fetchLength", arrayLengthFunction(_type))
|
("fetchLength", arrayLengthFunction(_type))
|
||||||
("indexAccess", storageArrayIndexAccessFunction(_type))
|
("indexAccess", storageArrayIndexAccessFunction(_type))
|
||||||
("setToZero", storageSetToZeroFunction(*_type.baseType()))
|
("setToZero", storageSetToZeroFunction(*_type.baseType()))
|
||||||
@ -917,7 +927,7 @@ string YulUtilFunctions::storageByteArrayPopFunction(ArrayType const& _type)
|
|||||||
function <functionName>(array) {
|
function <functionName>(array) {
|
||||||
let data := sload(array)
|
let data := sload(array)
|
||||||
let oldLen := <extractByteArrayLength>(data)
|
let oldLen := <extractByteArrayLength>(data)
|
||||||
if iszero(oldLen) { invalid() }
|
if iszero(oldLen) { <panic>() }
|
||||||
|
|
||||||
switch eq(oldLen, 32)
|
switch eq(oldLen, 32)
|
||||||
case 1 {
|
case 1 {
|
||||||
@ -946,6 +956,7 @@ string YulUtilFunctions::storageByteArrayPopFunction(ArrayType const& _type)
|
|||||||
sstore(array, data)
|
sstore(array, data)
|
||||||
})")
|
})")
|
||||||
("functionName", functionName)
|
("functionName", functionName)
|
||||||
|
("panic", panicFunction())
|
||||||
("extractByteArrayLength", extractByteArrayLengthFunction())
|
("extractByteArrayLength", extractByteArrayLengthFunction())
|
||||||
("dataAreaFunction", arrayDataAreaFunction(_type))
|
("dataAreaFunction", arrayDataAreaFunction(_type))
|
||||||
("indexAccess", storageArrayIndexAccessFunction(_type))
|
("indexAccess", storageArrayIndexAccessFunction(_type))
|
||||||
@ -968,7 +979,7 @@ string YulUtilFunctions::storageArrayPushFunction(ArrayType const& _type)
|
|||||||
<?isByteArray>
|
<?isByteArray>
|
||||||
let data := sload(array)
|
let data := sload(array)
|
||||||
let oldLen := <extractByteArrayLength>(data)
|
let oldLen := <extractByteArrayLength>(data)
|
||||||
if iszero(lt(oldLen, <maxArrayLength>)) { invalid() }
|
if iszero(lt(oldLen, <maxArrayLength>)) { <panic>() }
|
||||||
|
|
||||||
switch gt(oldLen, 31)
|
switch gt(oldLen, 31)
|
||||||
case 0 {
|
case 0 {
|
||||||
@ -999,13 +1010,14 @@ string YulUtilFunctions::storageArrayPushFunction(ArrayType const& _type)
|
|||||||
}
|
}
|
||||||
<!isByteArray>
|
<!isByteArray>
|
||||||
let oldLen := sload(array)
|
let oldLen := sload(array)
|
||||||
if iszero(lt(oldLen, <maxArrayLength>)) { invalid() }
|
if iszero(lt(oldLen, <maxArrayLength>)) { <panic>() }
|
||||||
sstore(array, add(oldLen, 1))
|
sstore(array, add(oldLen, 1))
|
||||||
let slot, offset := <indexAccess>(array, oldLen)
|
let slot, offset := <indexAccess>(array, oldLen)
|
||||||
<storeValue>(slot, offset, value)
|
<storeValue>(slot, offset, value)
|
||||||
</isByteArray>
|
</isByteArray>
|
||||||
})")
|
})")
|
||||||
("functionName", functionName)
|
("functionName", functionName)
|
||||||
|
("panic", panicFunction())
|
||||||
("extractByteArrayLength", _type.isByteArray() ? extractByteArrayLengthFunction() : "")
|
("extractByteArrayLength", _type.isByteArray() ? extractByteArrayLengthFunction() : "")
|
||||||
("dataAreaFunction", arrayDataAreaFunction(_type))
|
("dataAreaFunction", arrayDataAreaFunction(_type))
|
||||||
("isByteArray", _type.isByteArray())
|
("isByteArray", _type.isByteArray())
|
||||||
@ -1032,12 +1044,13 @@ string YulUtilFunctions::storageArrayPushZeroFunction(ArrayType const& _type)
|
|||||||
return Whiskers(R"(
|
return Whiskers(R"(
|
||||||
function <functionName>(array) -> slot, offset {
|
function <functionName>(array) -> slot, offset {
|
||||||
let oldLen := <fetchLength>(array)
|
let oldLen := <fetchLength>(array)
|
||||||
if iszero(lt(oldLen, <maxArrayLength>)) { invalid() }
|
if iszero(lt(oldLen, <maxArrayLength>)) { <panic>() }
|
||||||
sstore(array, add(oldLen, 1))
|
sstore(array, add(oldLen, 1))
|
||||||
slot, offset := <indexAccess>(array, oldLen)
|
slot, offset := <indexAccess>(array, oldLen)
|
||||||
<storeValue>(slot, offset, <zeroValueFunction>())
|
<storeValue>(slot, offset, <zeroValueFunction>())
|
||||||
})")
|
})")
|
||||||
("functionName", functionName)
|
("functionName", functionName)
|
||||||
|
("panic", panicFunction())
|
||||||
("fetchLength", arrayLengthFunction(_type))
|
("fetchLength", arrayLengthFunction(_type))
|
||||||
("indexAccess", storageArrayIndexAccessFunction(_type))
|
("indexAccess", storageArrayIndexAccessFunction(_type))
|
||||||
("storeValue", updateStorageValueFunction(*_type.baseType(), *_type.baseType()))
|
("storeValue", updateStorageValueFunction(*_type.baseType(), *_type.baseType()))
|
||||||
@ -1172,7 +1185,7 @@ string YulUtilFunctions::arrayAllocationSizeFunction(ArrayType const& _type)
|
|||||||
Whiskers w(R"(
|
Whiskers w(R"(
|
||||||
function <functionName>(length) -> size {
|
function <functionName>(length) -> size {
|
||||||
// Make sure we can allocate memory without overflow
|
// Make sure we can allocate memory without overflow
|
||||||
if gt(length, 0xffffffffffffffff) { revert(0, 0) }
|
if gt(length, 0xffffffffffffffff) { <panic>() }
|
||||||
<?byteArray>
|
<?byteArray>
|
||||||
// round up
|
// round up
|
||||||
size := and(add(length, 0x1f), not(0x1f))
|
size := and(add(length, 0x1f), not(0x1f))
|
||||||
@ -1186,6 +1199,7 @@ string YulUtilFunctions::arrayAllocationSizeFunction(ArrayType const& _type)
|
|||||||
}
|
}
|
||||||
)");
|
)");
|
||||||
w("functionName", functionName);
|
w("functionName", functionName);
|
||||||
|
w("panic", panicFunction());
|
||||||
w("byteArray", _type.isByteArray());
|
w("byteArray", _type.isByteArray());
|
||||||
w("dynamic", _type.isDynamicallySized());
|
w("dynamic", _type.isDynamicallySized());
|
||||||
return w.render();
|
return w.render();
|
||||||
@ -1230,7 +1244,7 @@ string YulUtilFunctions::storageArrayIndexAccessFunction(ArrayType const& _type)
|
|||||||
return Whiskers(R"(
|
return Whiskers(R"(
|
||||||
function <functionName>(array, index) -> slot, offset {
|
function <functionName>(array, index) -> slot, offset {
|
||||||
let arrayLength := <arrayLen>(array)
|
let arrayLength := <arrayLen>(array)
|
||||||
if iszero(lt(index, arrayLength)) { invalid() }
|
if iszero(lt(index, arrayLength)) { <panic>() }
|
||||||
|
|
||||||
<?multipleItemsPerSlot>
|
<?multipleItemsPerSlot>
|
||||||
<?isBytesArray>
|
<?isBytesArray>
|
||||||
@ -1256,6 +1270,7 @@ string YulUtilFunctions::storageArrayIndexAccessFunction(ArrayType const& _type)
|
|||||||
}
|
}
|
||||||
)")
|
)")
|
||||||
("functionName", functionName)
|
("functionName", functionName)
|
||||||
|
("panic", panicFunction())
|
||||||
("arrayLen", arrayLengthFunction(_type))
|
("arrayLen", arrayLengthFunction(_type))
|
||||||
("dataAreaFunc", arrayDataAreaFunction(_type))
|
("dataAreaFunc", arrayDataAreaFunction(_type))
|
||||||
("multipleItemsPerSlot", _type.baseType()->storageBytes() <= 16)
|
("multipleItemsPerSlot", _type.baseType()->storageBytes() <= 16)
|
||||||
@ -1274,7 +1289,7 @@ string YulUtilFunctions::memoryArrayIndexAccessFunction(ArrayType const& _type)
|
|||||||
return Whiskers(R"(
|
return Whiskers(R"(
|
||||||
function <functionName>(baseRef, index) -> addr {
|
function <functionName>(baseRef, index) -> addr {
|
||||||
if iszero(lt(index, <arrayLen>(baseRef))) {
|
if iszero(lt(index, <arrayLen>(baseRef))) {
|
||||||
invalid()
|
<panic>()
|
||||||
}
|
}
|
||||||
|
|
||||||
let offset := mul(index, <stride>)
|
let offset := mul(index, <stride>)
|
||||||
@ -1285,6 +1300,7 @@ string YulUtilFunctions::memoryArrayIndexAccessFunction(ArrayType const& _type)
|
|||||||
}
|
}
|
||||||
)")
|
)")
|
||||||
("functionName", functionName)
|
("functionName", functionName)
|
||||||
|
("panic", panicFunction())
|
||||||
("arrayLen", arrayLengthFunction(_type))
|
("arrayLen", arrayLengthFunction(_type))
|
||||||
("stride", to_string(_type.memoryStride()))
|
("stride", to_string(_type.memoryStride()))
|
||||||
("dynamicallySized", _type.isDynamicallySized())
|
("dynamicallySized", _type.isDynamicallySized())
|
||||||
@ -1299,7 +1315,7 @@ string YulUtilFunctions::calldataArrayIndexAccessFunction(ArrayType const& _type
|
|||||||
return m_functionCollector.createFunction(functionName, [&]() {
|
return m_functionCollector.createFunction(functionName, [&]() {
|
||||||
return Whiskers(R"(
|
return Whiskers(R"(
|
||||||
function <functionName>(base_ref<?dynamicallySized>, length</dynamicallySized>, index) -> addr<?dynamicallySizedBase>, len</dynamicallySizedBase> {
|
function <functionName>(base_ref<?dynamicallySized>, length</dynamicallySized>, index) -> addr<?dynamicallySizedBase>, len</dynamicallySizedBase> {
|
||||||
if iszero(lt(index, <?dynamicallySized>length<!dynamicallySized><arrayLen></dynamicallySized>)) { invalid() }
|
if iszero(lt(index, <?dynamicallySized>length<!dynamicallySized><arrayLen></dynamicallySized>)) { <panic>() }
|
||||||
addr := add(base_ref, mul(index, <stride>))
|
addr := add(base_ref, mul(index, <stride>))
|
||||||
<?dynamicallyEncodedBase>
|
<?dynamicallyEncodedBase>
|
||||||
addr<?dynamicallySizedBase>, len</dynamicallySizedBase> := <accessCalldataTail>(base_ref, addr)
|
addr<?dynamicallySizedBase>, len</dynamicallySizedBase> := <accessCalldataTail>(base_ref, addr)
|
||||||
@ -1307,6 +1323,7 @@ string YulUtilFunctions::calldataArrayIndexAccessFunction(ArrayType const& _type
|
|||||||
}
|
}
|
||||||
)")
|
)")
|
||||||
("functionName", functionName)
|
("functionName", functionName)
|
||||||
|
("panic", panicFunction())
|
||||||
("stride", to_string(_type.calldataStride()))
|
("stride", to_string(_type.calldataStride()))
|
||||||
("dynamicallySized", _type.isDynamicallySized())
|
("dynamicallySized", _type.isDynamicallySized())
|
||||||
("dynamicallyEncodedBase", _type.baseType()->isDynamicallyEncoded())
|
("dynamicallyEncodedBase", _type.baseType()->isDynamicallyEncoded())
|
||||||
@ -1852,12 +1869,13 @@ string YulUtilFunctions::allocationFunction()
|
|||||||
memPtr := mload(<freeMemoryPointer>)
|
memPtr := mload(<freeMemoryPointer>)
|
||||||
let newFreePtr := add(memPtr, size)
|
let newFreePtr := add(memPtr, size)
|
||||||
// protect against overflow
|
// protect against overflow
|
||||||
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { revert(0, 0) }
|
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { <panic>() }
|
||||||
mstore(<freeMemoryPointer>, newFreePtr)
|
mstore(<freeMemoryPointer>, newFreePtr)
|
||||||
}
|
}
|
||||||
)")
|
)")
|
||||||
("freeMemoryPointer", to_string(CompilerUtils::freeMemoryPointer))
|
|
||||||
("functionName", functionName)
|
("functionName", functionName)
|
||||||
|
("freeMemoryPointer", to_string(CompilerUtils::freeMemoryPointer))
|
||||||
|
("panic", panicFunction())
|
||||||
.render();
|
.render();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -2427,7 +2445,7 @@ string YulUtilFunctions::validatorFunction(Type const& _type, bool _revertOnFail
|
|||||||
if (_revertOnFailure)
|
if (_revertOnFailure)
|
||||||
templ("failure", "revert(0, 0)");
|
templ("failure", "revert(0, 0)");
|
||||||
else
|
else
|
||||||
templ("failure", "invalid()");
|
templ("failure", panicFunction() + "()");
|
||||||
|
|
||||||
switch (_type.category())
|
switch (_type.category())
|
||||||
{
|
{
|
||||||
@ -2538,11 +2556,12 @@ std::string YulUtilFunctions::decrementCheckedFunction(Type const& _type)
|
|||||||
return Whiskers(R"(
|
return Whiskers(R"(
|
||||||
function <functionName>(value) -> ret {
|
function <functionName>(value) -> ret {
|
||||||
value := <cleanupFunction>(value)
|
value := <cleanupFunction>(value)
|
||||||
if <lt>(value, <minval>) { revert(0,0) }
|
if <lt>(value, <minval>) { <panic>() }
|
||||||
ret := sub(value, 1)
|
ret := sub(value, 1)
|
||||||
}
|
}
|
||||||
)")
|
)")
|
||||||
("functionName", functionName)
|
("functionName", functionName)
|
||||||
|
("panic", panicFunction())
|
||||||
("minval", toCompactHexWithPrefix(minintval))
|
("minval", toCompactHexWithPrefix(minintval))
|
||||||
("lt", type.isSigned() ? "slt" : "lt")
|
("lt", type.isSigned() ? "slt" : "lt")
|
||||||
("cleanupFunction", cleanupFunction(_type))
|
("cleanupFunction", cleanupFunction(_type))
|
||||||
@ -2568,13 +2587,14 @@ std::string YulUtilFunctions::incrementCheckedFunction(Type const& _type)
|
|||||||
return Whiskers(R"(
|
return Whiskers(R"(
|
||||||
function <functionName>(value) -> ret {
|
function <functionName>(value) -> ret {
|
||||||
value := <cleanupFunction>(value)
|
value := <cleanupFunction>(value)
|
||||||
if <gt>(value, <maxval>) { revert(0,0) }
|
if <gt>(value, <maxval>) { <panic>() }
|
||||||
ret := add(value, 1)
|
ret := add(value, 1)
|
||||||
}
|
}
|
||||||
)")
|
)")
|
||||||
("functionName", functionName)
|
("functionName", functionName)
|
||||||
("maxval", toCompactHexWithPrefix(maxintval))
|
("maxval", toCompactHexWithPrefix(maxintval))
|
||||||
("gt", type.isSigned() ? "sgt" : "gt")
|
("gt", type.isSigned() ? "sgt" : "gt")
|
||||||
|
("panic", panicFunction())
|
||||||
("cleanupFunction", cleanupFunction(_type))
|
("cleanupFunction", cleanupFunction(_type))
|
||||||
.render();
|
.render();
|
||||||
});
|
});
|
||||||
@ -2593,13 +2613,14 @@ string YulUtilFunctions::negateNumberCheckedFunction(Type const& _type)
|
|||||||
return Whiskers(R"(
|
return Whiskers(R"(
|
||||||
function <functionName>(value) -> ret {
|
function <functionName>(value) -> ret {
|
||||||
value := <cleanupFunction>(value)
|
value := <cleanupFunction>(value)
|
||||||
if slt(value, <minval>) { revert(0,0) }
|
if slt(value, <minval>) { <panic>() }
|
||||||
ret := sub(0, value)
|
ret := sub(0, value)
|
||||||
}
|
}
|
||||||
)")
|
)")
|
||||||
("functionName", functionName)
|
("functionName", functionName)
|
||||||
("minval", toCompactHexWithPrefix(minintval))
|
("minval", toCompactHexWithPrefix(minintval))
|
||||||
("cleanupFunction", cleanupFunction(_type))
|
("cleanupFunction", cleanupFunction(_type))
|
||||||
|
("panic", panicFunction())
|
||||||
.render();
|
.render();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -2935,6 +2956,20 @@ string YulUtilFunctions::revertReasonIfDebug(string const& _message)
|
|||||||
return revertReasonIfDebug(m_revertStrings, _message);
|
return revertReasonIfDebug(m_revertStrings, _message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string YulUtilFunctions::panicFunction()
|
||||||
|
{
|
||||||
|
string functionName = "panic_error";
|
||||||
|
return m_functionCollector.createFunction(functionName, [&]() {
|
||||||
|
return Whiskers(R"(
|
||||||
|
function <functionName>() {
|
||||||
|
invalid()
|
||||||
|
}
|
||||||
|
)")
|
||||||
|
("functionName", functionName)
|
||||||
|
.render();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
string YulUtilFunctions::tryDecodeErrorMessageFunction()
|
string YulUtilFunctions::tryDecodeErrorMessageFunction()
|
||||||
{
|
{
|
||||||
string const functionName = "try_decode_error_message";
|
string const functionName = "try_decode_error_message";
|
||||||
|
@ -373,6 +373,10 @@ public:
|
|||||||
|
|
||||||
std::string revertReasonIfDebug(std::string const& _message = "");
|
std::string revertReasonIfDebug(std::string const& _message = "");
|
||||||
|
|
||||||
|
/// Executes the invalid opcode.
|
||||||
|
/// Might use revert with special error code in the future.
|
||||||
|
std::string panicFunction();
|
||||||
|
|
||||||
/// Returns the name of a function that decodes an error message.
|
/// Returns the name of a function that decodes an error message.
|
||||||
/// signature: () -> arrayPtr
|
/// signature: () -> arrayPtr
|
||||||
///
|
///
|
||||||
|
@ -204,10 +204,11 @@ InternalDispatchMap IRGenerator::generateInternalDispatchFunctions()
|
|||||||
<?+out> <out> :=</+out> <name>(<in>)
|
<?+out> <out> :=</+out> <name>(<in>)
|
||||||
}
|
}
|
||||||
</cases>
|
</cases>
|
||||||
default { invalid() }
|
default { <panic>() }
|
||||||
}
|
}
|
||||||
)");
|
)");
|
||||||
templ("functionName", funName);
|
templ("functionName", funName);
|
||||||
|
templ("panic", m_utils.panicFunction());
|
||||||
templ("in", suffixedVariableNameList("in_", 0, arity.in));
|
templ("in", suffixedVariableNameList("in_", 0, arity.in));
|
||||||
templ("out", suffixedVariableNameList("out_", 0, arity.out));
|
templ("out", suffixedVariableNameList("out_", 0, arity.out));
|
||||||
|
|
||||||
|
@ -1247,8 +1247,10 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
|
|||||||
|
|
||||||
IRVariable modulus(m_context.newYulVariable(), *(parameterTypes[2]));
|
IRVariable modulus(m_context.newYulVariable(), *(parameterTypes[2]));
|
||||||
define(modulus, *arguments[2]);
|
define(modulus, *arguments[2]);
|
||||||
Whiskers templ("if iszero(<modulus>) { invalid() }\n");
|
Whiskers templ("if iszero(<modulus>) { <panic>() }\n");
|
||||||
m_code << templ("modulus", modulus.name()).render();
|
templ("modulus", modulus.name());
|
||||||
|
templ("panic", m_utils.panicFunction());
|
||||||
|
m_code << templ.render();
|
||||||
|
|
||||||
string args;
|
string args;
|
||||||
for (size_t i = 0; i < 2; ++i)
|
for (size_t i = 0; i < 2; ++i)
|
||||||
@ -1325,7 +1327,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
|
|||||||
Whiskers t(R"(
|
Whiskers t(R"(
|
||||||
let <memPos> := <allocateTemporaryMemory>()
|
let <memPos> := <allocateTemporaryMemory>()
|
||||||
let <memEnd> := add(<memPos>, datasize("<object>"))
|
let <memEnd> := add(<memPos>, datasize("<object>"))
|
||||||
if or(gt(<memEnd>, 0xffffffffffffffff), lt(<memEnd>, <memPos>)) { revert(0, 0) }
|
if or(gt(<memEnd>, 0xffffffffffffffff), lt(<memEnd>, <memPos>)) { <panic>() }
|
||||||
datacopy(<memPos>, dataoffset("<object>"), datasize("<object>"))
|
datacopy(<memPos>, dataoffset("<object>"), datasize("<object>"))
|
||||||
<memEnd> := <abiEncode>(<memEnd><constructorParams>)
|
<memEnd> := <abiEncode>(<memEnd><constructorParams>)
|
||||||
<?saltSet>
|
<?saltSet>
|
||||||
@ -1340,6 +1342,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
|
|||||||
t("allocateTemporaryMemory", m_utils.allocationTemporaryMemoryFunction());
|
t("allocateTemporaryMemory", m_utils.allocationTemporaryMemoryFunction());
|
||||||
t("releaseTemporaryMemory", m_utils.releaseTemporaryMemoryFunction());
|
t("releaseTemporaryMemory", m_utils.releaseTemporaryMemoryFunction());
|
||||||
t("object", IRNames::creationObject(*contract));
|
t("object", IRNames::creationObject(*contract));
|
||||||
|
t("panic", m_utils.panicFunction());
|
||||||
t("abiEncode",
|
t("abiEncode",
|
||||||
m_context.abiFunctions().tupleEncoder(argumentTypes, functionType->parameterTypes(), false)
|
m_context.abiFunctions().tupleEncoder(argumentTypes, functionType->parameterTypes(), false)
|
||||||
);
|
);
|
||||||
@ -1987,11 +1990,12 @@ void IRGeneratorForStatements::endVisit(IndexAccess const& _indexAccess)
|
|||||||
IRVariable index{m_context.newYulVariable(), *TypeProvider::uint256()};
|
IRVariable index{m_context.newYulVariable(), *TypeProvider::uint256()};
|
||||||
define(index, *_indexAccess.indexExpression());
|
define(index, *_indexAccess.indexExpression());
|
||||||
m_code << Whiskers(R"(
|
m_code << Whiskers(R"(
|
||||||
if iszero(lt(<index>, <length>)) { invalid() }
|
if iszero(lt(<index>, <length>)) { <panic>() }
|
||||||
let <result> := <shl248>(byte(<index>, <array>))
|
let <result> := <shl248>(byte(<index>, <array>))
|
||||||
)")
|
)")
|
||||||
("index", index.name())
|
("index", index.name())
|
||||||
("length", to_string(fixedBytesType.numBytes()))
|
("length", to_string(fixedBytesType.numBytes()))
|
||||||
|
("panic", m_utils.panicFunction())
|
||||||
("array", IRVariable(_indexAccess.baseExpression()).name())
|
("array", IRVariable(_indexAccess.baseExpression()).name())
|
||||||
("shl248", m_utils.shiftLeftFunction(256 - 8))
|
("shl248", m_utils.shiftLeftFunction(256 - 8))
|
||||||
("result", IRVariable(_indexAccess).name())
|
("result", IRVariable(_indexAccess).name())
|
||||||
|
@ -58,7 +58,7 @@ object "D_13" {
|
|||||||
if slt(add(calldatasize(), not(3)), _2) { revert(_2, _2) }
|
if slt(add(calldatasize(), not(3)), _2) { revert(_2, _2) }
|
||||||
let _3 := datasize("C_2")
|
let _3 := datasize("C_2")
|
||||||
let _4 := add(_1, _3)
|
let _4 := add(_1, _3)
|
||||||
if or(gt(_4, 0xffffffffffffffff), lt(_4, _1)) { revert(_2, _2) }
|
if or(gt(_4, 0xffffffffffffffff), lt(_4, _1)) { invalid() }
|
||||||
datacopy(_1, dataoffset("C_2"), _3)
|
datacopy(_1, dataoffset("C_2"), _3)
|
||||||
pop(create(_2, _1, sub(_4, _1)))
|
pop(create(_2, _1, sub(_4, _1)))
|
||||||
return(allocateMemory(_2), _2)
|
return(allocateMemory(_2), _2)
|
||||||
@ -70,7 +70,7 @@ object "D_13" {
|
|||||||
{
|
{
|
||||||
memPtr := mload(64)
|
memPtr := mload(64)
|
||||||
let newFreePtr := add(memPtr, size)
|
let newFreePtr := add(memPtr, size)
|
||||||
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { revert(0, 0) }
|
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { invalid() }
|
||||||
mstore(64, newFreePtr)
|
mstore(64, newFreePtr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ object "D_11" {
|
|||||||
{
|
{
|
||||||
if callvalue() { revert(_2, _2) }
|
if callvalue() { revert(_2, _2) }
|
||||||
if slt(add(calldatasize(), not(3)), _2) { revert(_2, _2) }
|
if slt(add(calldatasize(), not(3)), _2) { revert(_2, _2) }
|
||||||
if gt(_1, 0xffffffffffffffff) { revert(_2, _2) }
|
if gt(_1, 0xffffffffffffffff) { invalid() }
|
||||||
mstore(64, _1)
|
mstore(64, _1)
|
||||||
return(_1, _2)
|
return(_1, _2)
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ object "C_56" {
|
|||||||
if gt(offset, _3) { revert(_1, _1) }
|
if gt(offset, _3) { revert(_1, _1) }
|
||||||
if iszero(slt(add(offset, 35), calldatasize())) { revert(_1, _1) }
|
if iszero(slt(add(offset, 35), calldatasize())) { revert(_1, _1) }
|
||||||
let length := calldataload(add(4, offset))
|
let length := calldataload(add(4, offset))
|
||||||
if gt(length, _3) { revert(_1, _1) }
|
if gt(length, _3) { invalid() }
|
||||||
let _4 := mul(length, _2)
|
let _4 := mul(length, _2)
|
||||||
let dst := allocateMemory(add(_4, _2))
|
let dst := allocateMemory(add(_4, _2))
|
||||||
let dst_1 := dst
|
let dst_1 := dst
|
||||||
@ -58,8 +58,12 @@ object "C_56" {
|
|||||||
function abi_decode_t_struct$_S(headStart, end) -> value
|
function abi_decode_t_struct$_S(headStart, end) -> value
|
||||||
{
|
{
|
||||||
if slt(sub(end, headStart), 0x20) { revert(value, value) }
|
if slt(sub(end, headStart), 0x20) { revert(value, value) }
|
||||||
value := allocateMemory(0x20)
|
let memPtr := mload(64)
|
||||||
mstore(value, calldataload(headStart))
|
let newFreePtr := add(memPtr, 0x20)
|
||||||
|
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { invalid() }
|
||||||
|
mstore(64, newFreePtr)
|
||||||
|
value := memPtr
|
||||||
|
mstore(memPtr, calldataload(headStart))
|
||||||
}
|
}
|
||||||
function abi_encode_uint256_t_string(headStart, value0, value1) -> tail
|
function abi_encode_uint256_t_string(headStart, value0, value1) -> tail
|
||||||
{
|
{
|
||||||
@ -83,17 +87,21 @@ object "C_56" {
|
|||||||
{
|
{
|
||||||
memPtr := mload(64)
|
memPtr := mload(64)
|
||||||
let newFreePtr := add(memPtr, size)
|
let newFreePtr := add(memPtr, size)
|
||||||
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { revert(0, 0) }
|
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { invalid() }
|
||||||
mstore(64, newFreePtr)
|
mstore(64, newFreePtr)
|
||||||
}
|
}
|
||||||
function convert_t_stringliteral_6490_to_t_string() -> converted
|
function convert_t_stringliteral_6490_to_t_string() -> converted
|
||||||
{
|
{
|
||||||
converted := allocateMemory(160)
|
let memPtr := mload(64)
|
||||||
mstore(converted, 100)
|
let newFreePtr := add(memPtr, 160)
|
||||||
mstore(add(converted, 32), "longstringlongstringlongstringlo")
|
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { invalid() }
|
||||||
mstore(add(converted, 64), "ngstringlongstringlongstringlong")
|
mstore(64, newFreePtr)
|
||||||
mstore(add(converted, 96), "stringlongstringlongstringlongst")
|
converted := memPtr
|
||||||
mstore(add(converted, 128), "ring")
|
mstore(memPtr, 100)
|
||||||
|
mstore(add(memPtr, 32), "longstringlongstringlongstringlo")
|
||||||
|
mstore(add(memPtr, 64), "ngstringlongstringlongstringlong")
|
||||||
|
mstore(add(memPtr, 96), "stringlongstringlongstringlongst")
|
||||||
|
mstore(add(memPtr, 128), "ring")
|
||||||
}
|
}
|
||||||
function extract_from_storage_value_dynamict_uint256(slot_value, offset) -> value
|
function extract_from_storage_value_dynamict_uint256(slot_value, offset) -> value
|
||||||
{
|
{
|
||||||
|
@ -33,13 +33,13 @@ object "Arraysum_33" {
|
|||||||
for { }
|
for { }
|
||||||
lt(vloc_i, _2)
|
lt(vloc_i, _2)
|
||||||
{
|
{
|
||||||
if gt(vloc_i, not(1)) { revert(_1, _1) }
|
if gt(vloc_i, not(1)) { invalid() }
|
||||||
vloc_i := add(vloc_i, 1)
|
vloc_i := add(vloc_i, 1)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
mstore(_1, _1)
|
mstore(_1, _1)
|
||||||
let _3 := sload(add(keccak256(_1, 0x20), vloc_i))
|
let _3 := sload(add(keccak256(_1, 0x20), vloc_i))
|
||||||
if gt(vloc_sum, not(_3)) { revert(_1, _1) }
|
if gt(vloc_sum, not(_3)) { invalid() }
|
||||||
vloc_sum := add(vloc_sum, _3)
|
vloc_sum := add(vloc_sum, _3)
|
||||||
}
|
}
|
||||||
let memPos := allocateMemory(_1)
|
let memPos := allocateMemory(_1)
|
||||||
@ -57,7 +57,7 @@ object "Arraysum_33" {
|
|||||||
{
|
{
|
||||||
memPtr := mload(64)
|
memPtr := mload(64)
|
||||||
let newFreePtr := add(memPtr, size)
|
let newFreePtr := add(memPtr, size)
|
||||||
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { revert(0, 0) }
|
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { invalid() }
|
||||||
mstore(64, newFreePtr)
|
mstore(64, newFreePtr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because one or more lines are too long
@ -44,11 +44,13 @@ object \"C_6\" {
|
|||||||
{
|
{
|
||||||
memPtr := mload(64)
|
memPtr := mload(64)
|
||||||
let newFreePtr := add(memPtr, size)
|
let newFreePtr := add(memPtr, size)
|
||||||
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { revert(0, 0) }
|
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error() }
|
||||||
mstore(64, newFreePtr)
|
mstore(64, newFreePtr)
|
||||||
}
|
}
|
||||||
function fun_f_5()
|
function fun_f_5()
|
||||||
{ }
|
{ }
|
||||||
|
function panic_error()
|
||||||
|
{ invalid() }
|
||||||
function shift_right_224_unsigned(value) -> newValue
|
function shift_right_224_unsigned(value) -> newValue
|
||||||
{ newValue := shr(224, value) }
|
{ newValue := shr(224, value) }
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ object \"C_6\" {
|
|||||||
memPtr := mload(64)
|
memPtr := mload(64)
|
||||||
let newFreePtr := add(memPtr, size)
|
let newFreePtr := add(memPtr, size)
|
||||||
// protect against overflow
|
// protect against overflow
|
||||||
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { revert(0, 0) }
|
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error() }
|
||||||
mstore(64, newFreePtr)
|
mstore(64, newFreePtr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,6 +69,10 @@ object \"C_6\" {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function panic_error() {
|
||||||
|
invalid()
|
||||||
|
}
|
||||||
|
|
||||||
function shift_right_224_unsigned(value) -> newValue {
|
function shift_right_224_unsigned(value) -> newValue {
|
||||||
newValue :=
|
newValue :=
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
@ -71,7 +71,7 @@ object \"C_10\" {
|
|||||||
memPtr := mload(64)
|
memPtr := mload(64)
|
||||||
let newFreePtr := add(memPtr, size)
|
let newFreePtr := add(memPtr, size)
|
||||||
// protect against overflow
|
// protect against overflow
|
||||||
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { revert(0, 0) }
|
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error() }
|
||||||
mstore(64, newFreePtr)
|
mstore(64, newFreePtr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,6 +116,10 @@ object \"C_10\" {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function panic_error() {
|
||||||
|
invalid()
|
||||||
|
}
|
||||||
|
|
||||||
function round_up_to_mul_of_32(value) -> result {
|
function round_up_to_mul_of_32(value) -> result {
|
||||||
result := and(add(value, 31), not(31))
|
result := and(add(value, 31), not(31))
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ object \"C_10\" {
|
|||||||
memPtr := mload(64)
|
memPtr := mload(64)
|
||||||
let newFreePtr := add(memPtr, size)
|
let newFreePtr := add(memPtr, size)
|
||||||
// protect against overflow
|
// protect against overflow
|
||||||
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { revert(0, 0) }
|
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error() }
|
||||||
mstore(64, newFreePtr)
|
mstore(64, newFreePtr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,6 +88,10 @@ object \"C_10\" {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function panic_error() {
|
||||||
|
invalid()
|
||||||
|
}
|
||||||
|
|
||||||
function shift_right_224_unsigned(value) -> newValue {
|
function shift_right_224_unsigned(value) -> newValue {
|
||||||
newValue :=
|
newValue :=
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ object \"C_10\" {
|
|||||||
memPtr := mload(64)
|
memPtr := mload(64)
|
||||||
let newFreePtr := add(memPtr, size)
|
let newFreePtr := add(memPtr, size)
|
||||||
// protect against overflow
|
// protect against overflow
|
||||||
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { revert(0, 0) }
|
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error() }
|
||||||
mstore(64, newFreePtr)
|
mstore(64, newFreePtr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,6 +93,10 @@ object \"C_10\" {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function panic_error() {
|
||||||
|
invalid()
|
||||||
|
}
|
||||||
|
|
||||||
function shift_left_224(value) -> newValue {
|
function shift_left_224(value) -> newValue {
|
||||||
newValue :=
|
newValue :=
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ object \"C_10\" {
|
|||||||
memPtr := mload(64)
|
memPtr := mload(64)
|
||||||
let newFreePtr := add(memPtr, size)
|
let newFreePtr := add(memPtr, size)
|
||||||
// protect against overflow
|
// protect against overflow
|
||||||
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { revert(0, 0) }
|
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error() }
|
||||||
mstore(64, newFreePtr)
|
mstore(64, newFreePtr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,6 +120,10 @@ object \"C_10\" {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function panic_error() {
|
||||||
|
invalid()
|
||||||
|
}
|
||||||
|
|
||||||
function round_up_to_mul_of_32(value) -> result {
|
function round_up_to_mul_of_32(value) -> result {
|
||||||
result := and(add(value, 31), not(31))
|
result := and(add(value, 31), not(31))
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ object \"C_10\" {
|
|||||||
memPtr := mload(64)
|
memPtr := mload(64)
|
||||||
let newFreePtr := add(memPtr, size)
|
let newFreePtr := add(memPtr, size)
|
||||||
// protect against overflow
|
// protect against overflow
|
||||||
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { revert(0, 0) }
|
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error() }
|
||||||
mstore(64, newFreePtr)
|
mstore(64, newFreePtr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,6 +93,10 @@ object \"C_10\" {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function panic_error() {
|
||||||
|
invalid()
|
||||||
|
}
|
||||||
|
|
||||||
function shift_left_224(value) -> newValue {
|
function shift_left_224(value) -> newValue {
|
||||||
newValue :=
|
newValue :=
|
||||||
|
|
||||||
|
@ -14,9 +14,9 @@ contract C {
|
|||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// creation:
|
// creation:
|
||||||
// codeDepositCost: 1094400
|
// codeDepositCost: 1106800
|
||||||
// executionCost: 1134
|
// executionCost: 1147
|
||||||
// totalCost: 1095534
|
// totalCost: 1107947
|
||||||
// external:
|
// external:
|
||||||
// a(): 1130
|
// a(): 1130
|
||||||
// b(uint256): infinite
|
// b(uint256): infinite
|
||||||
|
@ -17,9 +17,9 @@ contract C {
|
|||||||
// optimize-yul: true
|
// optimize-yul: true
|
||||||
// ----
|
// ----
|
||||||
// creation:
|
// creation:
|
||||||
// codeDepositCost: 597000
|
// codeDepositCost: 604400
|
||||||
// executionCost: 632
|
// executionCost: 638
|
||||||
// totalCost: 597632
|
// totalCost: 605038
|
||||||
// external:
|
// external:
|
||||||
// a(): 1029
|
// a(): 1029
|
||||||
// b(uint256): 2084
|
// b(uint256): 2084
|
||||||
|
Loading…
Reference in New Issue
Block a user