Skip to content

Commit 73c2097

Browse files
committed
Implemented codegen for UserDefinedValueType
1 parent 6518ff2 commit 73c2097

File tree

3 files changed

+64
-1
lines changed

3 files changed

+64
-1
lines changed

libsolidity/codegen/CompilerUtils.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,33 @@ void CompilerUtils::convertType(
772772
Type::Category stackTypeCategory = _typeOnStack.category();
773773
Type::Category targetTypeCategory = _targetType.category();
774774

775+
if (stackTypeCategory == Type::Category::UserDefinedValueType)
776+
{
777+
solAssert(_typeOnStack.isExplicitlyConvertibleTo(_targetType), "");
778+
solAssert(_targetType.isValueType(), "");
779+
return
780+
convertType(
781+
_targetType,
782+
dynamic_cast<UserDefinedValueTypeType const&>(_typeOnStack).actualType(),
783+
_cleanupNeeded,
784+
_chopSignBits,
785+
_asPartOfArgumentDecoding
786+
);
787+
}
788+
if (_targetType.category() == Type::Category::UserDefinedValueType)
789+
{
790+
solAssert(_typeOnStack.isExplicitlyConvertibleTo(_targetType), "");
791+
solAssert(_typeOnStack.isValueType() || dynamic_cast<RationalNumberType const*>(&_typeOnStack), "");
792+
return
793+
convertType(
794+
_typeOnStack,
795+
dynamic_cast<UserDefinedValueTypeType const&>(_targetType).actualType(),
796+
_cleanupNeeded,
797+
_chopSignBits,
798+
_asPartOfArgumentDecoding
799+
);
800+
}
801+
775802
if (auto contrType = dynamic_cast<ContractType const*>(&_typeOnStack))
776803
solAssert(!contrType->isSuper(), "Cannot convert magic variable \"super\"");
777804

libsolidity/codegen/YulUtilFunctions.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3158,6 +3158,18 @@ string YulUtilFunctions::allocateAndInitializeMemoryStructFunction(StructType co
31583158

31593159
string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to)
31603160
{
3161+
if (_from.category() == Type::Category::UserDefinedValueType)
3162+
{
3163+
solAssert(_from.isExplicitlyConvertibleTo(_to), "");
3164+
solAssert(_to.isValueType(), "");
3165+
return conversionFunction(dynamic_cast<UserDefinedValueTypeType const&>(_from).actualType(), _to);
3166+
}
3167+
if (_to.category() == Type::Category::UserDefinedValueType)
3168+
{
3169+
solAssert(_from.isExplicitlyConvertibleTo(_to), "");
3170+
solAssert(_from.isValueType() || dynamic_cast<RationalNumberType const*>(&_from), "");
3171+
return conversionFunction(_from, dynamic_cast<UserDefinedValueTypeType const&>(_to).actualType());
3172+
}
31613173
if (_from.category() == Type::Category::Function)
31623174
{
31633175
solAssert(_to.category() == Type::Category::Function, "");
@@ -3431,6 +3443,15 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to)
34313443
body = "converted := value";
34323444
break;
34333445
}
3446+
case Type::Category::UserDefinedValueType:
3447+
{
3448+
auto& userDefinedValueTypeType = dynamic_cast<UserDefinedValueTypeType const&>(_from);
3449+
Type const* encodingType = userDefinedValueTypeType.encodingType();
3450+
solAssert(encodingType, "");
3451+
solAssert(_from == _to || *encodingType == _to, "");
3452+
body = "converted := value";
3453+
break;
3454+
}
34343455
default:
34353456
solAssert(false, "Invalid conversion from " + _from.canonicalName() + " to " + _to.canonicalName());
34363457
}
@@ -3783,6 +3804,14 @@ string YulUtilFunctions::cleanupFunction(Type const& _type)
37833804
case Type::Category::InaccessibleDynamic:
37843805
templ("body", "cleaned := 0");
37853806
break;
3807+
case Type::Category::UserDefinedValueType:
3808+
templ(
3809+
"body",
3810+
"cleaned := " +
3811+
cleanupFunction(dynamic_cast<UserDefinedValueTypeType const&>(_type).actualType()) +
3812+
"(value)"
3813+
);
3814+
break;
37863815
default:
37873816
solAssert(false, "Cleanup of type " + _type.identifier() + " requested.");
37883817
}
@@ -3816,6 +3845,7 @@ string YulUtilFunctions::validatorFunction(Type const& _type, bool _revertOnFail
38163845
case Type::Category::Mapping:
38173846
case Type::Category::FixedBytes:
38183847
case Type::Category::Contract:
3848+
case Type::Category::UserDefinedValueType:
38193849
{
38203850
templ("condition", "eq(value, " + cleanupFunction(_type) + "(value))");
38213851
break;

libsolidity/codegen/ir/IRGeneratorForStatements.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -869,8 +869,10 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
869869

870870
if (functionCallKind == FunctionCallKind::TypeConversion)
871871
{
872+
Type::Category category = _functionCall.expression().annotation().type->category();
872873
solAssert(
873-
_functionCall.expression().annotation().type->category() == Type::Category::TypeType,
874+
category == Type::Category::TypeType ||
875+
category == Type::Category::UserDefinedValueType,
874876
"Expected category to be TypeType"
875877
);
876878
solAssert(_functionCall.arguments().size() == 1, "Expected one argument for type conversion");
@@ -2300,6 +2302,10 @@ void IRGeneratorForStatements::endVisit(Identifier const& _identifier)
23002302
{
23012303
// no-op
23022304
}
2305+
else if (dynamic_cast<UserDefinedValueType const*>(declaration))
2306+
{
2307+
// no-op
2308+
}
23032309
else
23042310
{
23052311
solAssert(false, "Identifier type not expected in expression context.");

0 commit comments

Comments
 (0)