| 3957 | } |
| 3958 | |
| 3959 | std::string YulUtilFunctions::cleanupFunction(Type const& _type) |
| 3960 | { |
| 3961 | if (auto userDefinedValueType = dynamic_cast<UserDefinedValueType const*>(&_type)) |
| 3962 | return cleanupFunction(userDefinedValueType->underlyingType()); |
| 3963 | |
| 3964 | std::string functionName = std::string("cleanup_") + _type.identifier(); |
| 3965 | return m_functionCollector.createFunction(functionName, [&]() { |
| 3966 | Whiskers templ(R"( |
| 3967 | function <functionName>(value) -> cleaned { |
| 3968 | <body> |
| 3969 | } |
| 3970 | )"); |
| 3971 | templ("functionName", functionName); |
| 3972 | switch (_type.category()) |
| 3973 | { |
| 3974 | case Type::Category::Address: |
| 3975 | templ("body", "cleaned := " + cleanupFunction(IntegerType(160)) + "(value)"); |
| 3976 | break; |
| 3977 | case Type::Category::Integer: |
| 3978 | { |
| 3979 | IntegerType const& type = dynamic_cast<IntegerType const&>(_type); |
| 3980 | if (type.numBits() == 256) |
| 3981 | templ("body", "cleaned := value"); |
| 3982 | else if (type.isSigned()) |
| 3983 | templ("body", "cleaned := signextend(" + std::to_string(type.numBits() / 8 - 1) + ", value)"); |
| 3984 | else |
| 3985 | templ("body", "cleaned := and(value, " + toCompactHexWithPrefix((u256(1) << type.numBits()) - 1) + ")"); |
| 3986 | break; |
| 3987 | } |
| 3988 | case Type::Category::RationalNumber: |
| 3989 | templ("body", "cleaned := value"); |
| 3990 | break; |
| 3991 | case Type::Category::Bool: |
| 3992 | templ("body", "cleaned := iszero(iszero(value))"); |
| 3993 | break; |
| 3994 | case Type::Category::FixedPoint: |
| 3995 | solUnimplemented("Fixed point types not implemented."); |
| 3996 | break; |
| 3997 | case Type::Category::Function: |
| 3998 | switch (dynamic_cast<FunctionType const&>(_type).kind()) |
| 3999 | { |
| 4000 | case FunctionType::Kind::External: |
| 4001 | templ("body", "cleaned := " + cleanupFunction(FixedBytesType(24)) + "(value)"); |
| 4002 | break; |
| 4003 | case FunctionType::Kind::Internal: |
| 4004 | templ("body", "cleaned := value"); |
| 4005 | break; |
| 4006 | default: |
| 4007 | solAssert(false, ""); |
| 4008 | break; |
| 4009 | } |
| 4010 | break; |
| 4011 | case Type::Category::Array: |
| 4012 | case Type::Category::Struct: |
| 4013 | case Type::Category::Mapping: |
| 4014 | solAssert(_type.dataStoredIn(DataLocation::Storage), "Cleanup requested for non-storage reference type."); |
| 4015 | templ("body", "cleaned := value"); |
| 4016 | break; |
no test coverage detected