mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Implemented codegen for UserDefinedValueType
This commit is contained in:
parent
ce75790e8d
commit
54484e9795
@ -772,6 +772,33 @@ void CompilerUtils::convertType(
|
||||
Type::Category stackTypeCategory = _typeOnStack.category();
|
||||
Type::Category targetTypeCategory = _targetType.category();
|
||||
|
||||
if (stackTypeCategory == Type::Category::UserDefinedValueType)
|
||||
{
|
||||
solAssert(_cleanupNeeded, "");
|
||||
auto& userDefined = dynamic_cast<UserDefinedValueType const&>(_typeOnStack);
|
||||
solAssert(_typeOnStack == _targetType || _targetType == userDefined.underlyingType(), "");
|
||||
return convertType(
|
||||
userDefined.underlyingType(),
|
||||
_targetType,
|
||||
_cleanupNeeded,
|
||||
_chopSignBits,
|
||||
_asPartOfArgumentDecoding
|
||||
);
|
||||
}
|
||||
if (targetTypeCategory == Type::Category::UserDefinedValueType)
|
||||
{
|
||||
solAssert(_cleanupNeeded, "");
|
||||
auto& userDefined = dynamic_cast<UserDefinedValueType const&>(_targetType);
|
||||
solAssert(_typeOnStack.isImplicitlyConvertibleTo(userDefined.underlyingType()), "");
|
||||
return convertType(
|
||||
_typeOnStack,
|
||||
userDefined.underlyingType(),
|
||||
_cleanupNeeded,
|
||||
_chopSignBits,
|
||||
_asPartOfArgumentDecoding
|
||||
);
|
||||
}
|
||||
|
||||
if (auto contrType = dynamic_cast<ContractType const*>(&_typeOnStack))
|
||||
solAssert(!contrType->isSuper(), "Cannot convert magic variable \"super\"");
|
||||
|
||||
|
@ -957,6 +957,35 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
|
||||
);
|
||||
break;
|
||||
}
|
||||
case FunctionType::Kind::Wrap:
|
||||
case FunctionType::Kind::Unwrap:
|
||||
{
|
||||
solAssert(arguments.size() == 1, "");
|
||||
Type const* argumentType = arguments.at(0)->annotation().type;
|
||||
Type const* functionCallType = _functionCall.annotation().type;
|
||||
solAssert(argumentType, "");
|
||||
solAssert(functionCallType, "");
|
||||
FunctionType::Kind kind = functionType->kind();
|
||||
if (kind == FunctionType::Kind::Wrap)
|
||||
{
|
||||
solAssert(
|
||||
argumentType->isImplicitlyConvertibleTo(
|
||||
dynamic_cast<UserDefinedValueType const&>(*functionCallType).underlyingType()
|
||||
),
|
||||
""
|
||||
);
|
||||
solAssert(argumentType->isImplicitlyConvertibleTo(*function.parameterTypes()[0]), "");
|
||||
}
|
||||
else
|
||||
solAssert(
|
||||
dynamic_cast<UserDefinedValueType const&>(*argumentType) ==
|
||||
dynamic_cast<UserDefinedValueType const&>(*function.parameterTypes()[0]),
|
||||
""
|
||||
);
|
||||
|
||||
acceptAndConvert(*arguments[0], *function.parameterTypes()[0]);
|
||||
break;
|
||||
}
|
||||
case FunctionType::Kind::BlockHash:
|
||||
{
|
||||
acceptAndConvert(*arguments[0], *function.parameterTypes()[0], true);
|
||||
@ -2157,6 +2186,10 @@ void ExpressionCompiler::endVisit(Identifier const& _identifier)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
else if (dynamic_cast<UserDefinedValueTypeDefinition const*>(declaration))
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
else if (dynamic_cast<StructDefinition const*>(declaration))
|
||||
{
|
||||
// no-op
|
||||
|
@ -3168,6 +3168,16 @@ string YulUtilFunctions::allocateAndInitializeMemoryStructFunction(StructType co
|
||||
|
||||
string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to)
|
||||
{
|
||||
if (_from.category() == Type::Category::UserDefinedValueType)
|
||||
{
|
||||
solAssert(_from == _to || _to == dynamic_cast<UserDefinedValueType const&>(_from).underlyingType(), "");
|
||||
return conversionFunction(dynamic_cast<UserDefinedValueType const&>(_from).underlyingType(), _to);
|
||||
}
|
||||
if (_to.category() == Type::Category::UserDefinedValueType)
|
||||
{
|
||||
solAssert(_from == _to || _from.isImplicitlyConvertibleTo(dynamic_cast<UserDefinedValueType const&>(_to).underlyingType()), "");
|
||||
return conversionFunction(_from, dynamic_cast<UserDefinedValueType const&>(_to).underlyingType());
|
||||
}
|
||||
if (_from.category() == Type::Category::Function)
|
||||
{
|
||||
solAssert(_to.category() == Type::Category::Function, "");
|
||||
@ -3696,6 +3706,9 @@ string YulUtilFunctions::arrayConversionFunction(ArrayType const& _from, ArrayTy
|
||||
|
||||
string YulUtilFunctions::cleanupFunction(Type const& _type)
|
||||
{
|
||||
if (auto userDefinedValueType = dynamic_cast<UserDefinedValueType const*>(&_type))
|
||||
return cleanupFunction(userDefinedValueType->underlyingType());
|
||||
|
||||
string functionName = string("cleanup_") + _type.identifier();
|
||||
return m_functionCollector.createFunction(functionName, [&]() {
|
||||
Whiskers templ(R"(
|
||||
@ -3816,6 +3829,7 @@ string YulUtilFunctions::validatorFunction(Type const& _type, bool _revertOnFail
|
||||
case Type::Category::Mapping:
|
||||
case Type::Category::FixedBytes:
|
||||
case Type::Category::Contract:
|
||||
case Type::Category::UserDefinedValueType:
|
||||
{
|
||||
templ("condition", "eq(value, " + cleanupFunction(_type) + "(value))");
|
||||
break;
|
||||
|
@ -1051,6 +1051,24 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
|
||||
);
|
||||
break;
|
||||
}
|
||||
case FunctionType::Kind::Wrap:
|
||||
case FunctionType::Kind::Unwrap:
|
||||
{
|
||||
solAssert(arguments.size() == 1, "");
|
||||
FunctionType::Kind kind = functionType->kind();
|
||||
if (kind == FunctionType::Kind::Wrap)
|
||||
solAssert(
|
||||
type(*arguments.at(0)).isImplicitlyConvertibleTo(
|
||||
dynamic_cast<UserDefinedValueType const&>(type(_functionCall)).underlyingType()
|
||||
),
|
||||
""
|
||||
);
|
||||
else
|
||||
solAssert(type(*arguments.at(0)).category() == Type::Category::UserDefinedValueType, "");
|
||||
|
||||
define(_functionCall, *arguments.at(0));
|
||||
break;
|
||||
}
|
||||
case FunctionType::Kind::Assert:
|
||||
case FunctionType::Kind::Require:
|
||||
{
|
||||
@ -2004,6 +2022,8 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
|
||||
}
|
||||
else if (EnumType const* enumType = dynamic_cast<EnumType const*>(&actualType))
|
||||
define(_memberAccess) << to_string(enumType->memberValue(_memberAccess.memberName())) << "\n";
|
||||
else if (dynamic_cast<UserDefinedValueType const*>(&actualType))
|
||||
solAssert(member == "wrap" || member == "unwrap", "");
|
||||
else if (auto const* arrayType = dynamic_cast<ArrayType const*>(&actualType))
|
||||
solAssert(arrayType->isByteArray() && member == "concat", "");
|
||||
else
|
||||
@ -2314,6 +2334,10 @@ void IRGeneratorForStatements::endVisit(Identifier const& _identifier)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
else if (dynamic_cast<UserDefinedValueTypeDefinition const*>(declaration))
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
else
|
||||
{
|
||||
solAssert(false, "Identifier type not expected in expression context.");
|
||||
|
Loading…
Reference in New Issue
Block a user