| 3151 | } |
| 3152 | |
| 3153 | std::string YulUtilFunctions::cleanupFromStorageFunction(Type const& _type) |
| 3154 | { |
| 3155 | solAssert(_type.isValueType(), ""); |
| 3156 | |
| 3157 | std::string functionName = std::string("cleanup_from_storage_") + _type.identifier(); |
| 3158 | return m_functionCollector.createFunction(functionName, [&] { |
| 3159 | Whiskers templ(R"( |
| 3160 | function <functionName>(value) -> cleaned { |
| 3161 | cleaned := <cleaned> |
| 3162 | } |
| 3163 | )"); |
| 3164 | templ("functionName", functionName); |
| 3165 | |
| 3166 | Type const* encodingType = &_type; |
| 3167 | if (_type.category() == Type::Category::UserDefinedValueType) |
| 3168 | encodingType = _type.encodingType(); |
| 3169 | unsigned storageBytes = encodingType->storageBytes(); |
| 3170 | if (IntegerType const* intType = dynamic_cast<IntegerType const*>(encodingType)) |
| 3171 | if (intType->isSigned() && storageBytes != 32) |
| 3172 | { |
| 3173 | templ("cleaned", "signextend(" + std::to_string(storageBytes - 1) + ", value)"); |
| 3174 | return templ.render(); |
| 3175 | } |
| 3176 | |
| 3177 | if (storageBytes == 32) |
| 3178 | templ("cleaned", "value"); |
| 3179 | else if (encodingType->leftAligned()) |
| 3180 | templ("cleaned", shiftLeftFunction(256 - 8 * storageBytes) + "(value)"); |
| 3181 | else |
| 3182 | templ("cleaned", "and(value, " + toCompactHexWithPrefix((u256(1) << (8 * storageBytes)) - 1) + ")"); |
| 3183 | |
| 3184 | return templ.render(); |
| 3185 | }); |
| 3186 | } |
| 3187 | |
| 3188 | std::string YulUtilFunctions::prepareStoreFunction(Type const& _type) |
| 3189 | { |
nothing calls this directly
no test coverage detected