Merge pull request #11739 from ethereum/refactor_yul_conversion

solyul: Refactor conversion function.
This commit is contained in:
chriseth 2021-08-05 12:54:04 +02:00 committed by GitHub
commit 35e1ab2c6f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 43 deletions

View File

@ -3258,6 +3258,7 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to)
switch (fromCategory) switch (fromCategory)
{ {
case Type::Category::Address: case Type::Category::Address:
case Type::Category::Contract:
body = body =
Whiskers("converted := <convert>(value)") Whiskers("converted := <convert>(value)")
("convert", conversionFunction(IntegerType(160), _to)) ("convert", conversionFunction(IntegerType(160), _to))
@ -3265,61 +3266,44 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to)
break; break;
case Type::Category::Integer: case Type::Category::Integer:
case Type::Category::RationalNumber: case Type::Category::RationalNumber:
case Type::Category::Contract:
{ {
solAssert(_from.mobileType(), "");
if (RationalNumberType const* rational = dynamic_cast<RationalNumberType const*>(&_from)) if (RationalNumberType const* rational = dynamic_cast<RationalNumberType const*>(&_from))
solUnimplementedAssert(!rational->isFractional(), "Not yet implemented - FixedPointType."); if (rational->isFractional())
solAssert(toCategory == Type::Category::FixedPoint, "");
if (toCategory == Type::Category::FixedBytes) if (toCategory == Type::Category::FixedBytes)
{ {
solAssert(
fromCategory == Type::Category::Integer || fromCategory == Type::Category::RationalNumber,
"Invalid conversion to FixedBytesType requested."
);
FixedBytesType const& toBytesType = dynamic_cast<FixedBytesType const&>(_to); FixedBytesType const& toBytesType = dynamic_cast<FixedBytesType const&>(_to);
body = body =
Whiskers("converted := <shiftLeft>(<clean>(value))") Whiskers("converted := <shiftLeft>(<clean>(value))")
("shiftLeft", shiftLeftFunction(256 - toBytesType.numBytes() * 8)) ("shiftLeft", shiftLeftFunction(256 - toBytesType.numBytes() * 8))
("clean", cleanupFunction(_from)) ("clean", cleanupFunction(_from))
.render(); .render();
} }
else if (toCategory == Type::Category::Enum) else if (toCategory == Type::Category::Enum)
{
solAssert(_from.mobileType(), "");
body = body =
Whiskers("converted := <cleanEnum>(<cleanInt>(value))") Whiskers("converted := <cleanEnum>(<cleanInt>(value))")
("cleanEnum", cleanupFunction(_to)) ("cleanEnum", cleanupFunction(_to))
// "mobileType()" returns integer type for rational ("cleanInt", cleanupFunction(_from))
("cleanInt", cleanupFunction(*_from.mobileType()))
.render(); .render();
}
else if (toCategory == Type::Category::FixedPoint) else if (toCategory == Type::Category::FixedPoint)
solUnimplemented("Not yet implemented - FixedPointType."); solUnimplemented("Not yet implemented - FixedPointType.");
else if (toCategory == Type::Category::Address) else if (toCategory == Type::Category::Address || toCategory == Type::Category::Contract)
body = body =
Whiskers("converted := <convert>(value)") Whiskers("converted := <convert>(value)")
("convert", conversionFunction(_from, IntegerType(160))) ("convert", conversionFunction(_from, IntegerType(160)))
.render(); .render();
else else if (toCategory == Type::Category::Integer)
{ {
solAssert( IntegerType const& to = dynamic_cast<IntegerType const&>(_to);
toCategory == Type::Category::Integer ||
toCategory == Type::Category::Contract,
"");
IntegerType const addressType(160);
IntegerType const& to =
toCategory == Type::Category::Integer ?
dynamic_cast<IntegerType const&>(_to) :
addressType;
// Clean according to the "to" type, except if this is // Clean according to the "to" type, except if this is
// a widening conversion. // a widening conversion.
IntegerType const* cleanupType = &to; IntegerType const* cleanupType = &to;
if (fromCategory != Type::Category::RationalNumber) if (fromCategory == Type::Category::Integer)
{ {
IntegerType const& from = IntegerType const& from = dynamic_cast<IntegerType const&>(_from);
fromCategory == Type::Category::Integer ?
dynamic_cast<IntegerType const&>(_from) :
addressType;
if (to.numBits() > from.numBits()) if (to.numBits() > from.numBits())
cleanupType = &from; cleanupType = &from;
} }
@ -3328,6 +3312,8 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to)
("cleanInt", cleanupFunction(*cleanupType)) ("cleanInt", cleanupFunction(*cleanupType))
.render(); .render();
} }
else
solAssert(false, "");
break; break;
} }
case Type::Category::Bool: case Type::Category::Bool:

View File

@ -275,11 +275,7 @@ object \"C_54\" {
} }
function convert_t_contract$_C_$54_to_t_address(value) -> converted { function convert_t_contract$_C_$54_to_t_address(value) -> converted {
converted := convert_t_contract$_C_$54_to_t_uint160(value) converted := convert_t_uint160_to_t_address(value)
}
function convert_t_contract$_C_$54_to_t_uint160(value) -> converted {
converted := cleanup_t_uint160(value)
} }
function convert_t_int256_to_t_int256(value) -> converted { function convert_t_int256_to_t_int256(value) -> converted {
@ -290,6 +286,14 @@ object \"C_54\" {
converted := cleanup_t_int256(value) converted := cleanup_t_int256(value)
} }
function convert_t_uint160_to_t_address(value) -> converted {
converted := convert_t_uint160_to_t_uint160(value)
}
function convert_t_uint160_to_t_uint160(value) -> converted {
converted := cleanup_t_uint160(value)
}
function extract_from_storage_value_dynamict_int256(slot_value, offset) -> value { function extract_from_storage_value_dynamict_int256(slot_value, offset) -> value {
value := cleanup_from_storage_t_int256(shift_right_unsigned_dynamic(mul(offset, 8), slot_value)) value := cleanup_from_storage_t_int256(shift_right_unsigned_dynamic(mul(offset, 8), slot_value))
} }
@ -875,11 +879,7 @@ object \"D_72\" {
} }
function convert_t_contract$_C_$54_to_t_address(value) -> converted { function convert_t_contract$_C_$54_to_t_address(value) -> converted {
converted := convert_t_contract$_C_$54_to_t_uint160(value) converted := convert_t_uint160_to_t_address(value)
}
function convert_t_contract$_C_$54_to_t_uint160(value) -> converted {
converted := cleanup_t_uint160(value)
} }
function convert_t_int256_to_t_int256(value) -> converted { function convert_t_int256_to_t_int256(value) -> converted {
@ -890,6 +890,14 @@ object \"D_72\" {
converted := cleanup_t_int256(value) converted := cleanup_t_int256(value)
} }
function convert_t_uint160_to_t_address(value) -> converted {
converted := convert_t_uint160_to_t_uint160(value)
}
function convert_t_uint160_to_t_uint160(value) -> converted {
converted := cleanup_t_uint160(value)
}
function extract_from_storage_value_dynamict_int256(slot_value, offset) -> value { function extract_from_storage_value_dynamict_int256(slot_value, offset) -> value {
value := cleanup_from_storage_t_int256(shift_right_unsigned_dynamic(mul(offset, 8), slot_value)) value := cleanup_from_storage_t_int256(shift_right_unsigned_dynamic(mul(offset, 8), slot_value))
} }

View File

@ -27,5 +27,5 @@ contract C {
// compileViaYul: also // compileViaYul: also
// ---- // ----
// test() -> 9, 7 // test() -> 9, 7
// gas legacy: 121594 // gas legacy: 125064
// t2() -> 9 // t2() -> 9