| 2874 | } |
| 2875 | |
| 2876 | std::string YulUtilFunctions::readFromStorageReferenceType(Type const& _type) |
| 2877 | { |
| 2878 | if (auto const* arrayType = dynamic_cast<ArrayType const*>(&_type)) |
| 2879 | { |
| 2880 | solAssert(arrayType->dataStoredIn(DataLocation::Memory), ""); |
| 2881 | return copyArrayFromStorageToMemoryFunction( |
| 2882 | dynamic_cast<ArrayType const&>(*arrayType->copyForLocation(DataLocation::Storage, false)), |
| 2883 | *arrayType |
| 2884 | ); |
| 2885 | } |
| 2886 | solAssert(_type.category() == Type::Category::Struct, ""); |
| 2887 | |
| 2888 | std::string functionName = "read_from_storage_reference_type_" + _type.identifier(); |
| 2889 | |
| 2890 | auto const& structType = dynamic_cast<StructType const&>(_type); |
| 2891 | solAssert(structType.location() == DataLocation::Memory, ""); |
| 2892 | MemberList::MemberMap structMembers = structType.nativeMembers(nullptr); |
| 2893 | std::vector<std::map<std::string, std::string>> memberSetValues(structMembers.size()); |
| 2894 | for (size_t i = 0; i < structMembers.size(); ++i) |
| 2895 | { |
| 2896 | auto const& [memberSlotDiff, memberStorageOffset] = structType.storageOffsetsOfMember(structMembers[i].name); |
| 2897 | solAssert(structMembers[i].type->isValueType() || memberStorageOffset == 0, ""); |
| 2898 | |
| 2899 | memberSetValues[i]["setMember"] = Whiskers(R"( |
| 2900 | { |
| 2901 | let <memberValues> := <readFromStorage>(add(slot, <memberSlotDiff>)) |
| 2902 | <writeToMemory>(add(value, <memberMemoryOffset>), <memberValues>) |
| 2903 | } |
| 2904 | )") |
| 2905 | ("memberValues", suffixedVariableNameList("memberValue_", 0, structMembers[i].type->stackItems().size())) |
| 2906 | ("memberMemoryOffset", structType.memoryOffsetOfMember(structMembers[i].name).str()) |
| 2907 | ("memberSlotDiff", memberSlotDiff.str()) |
| 2908 | ("readFromStorage", readFromStorage(*structMembers[i].type, memberStorageOffset, true, VariableDeclaration::Location::Unspecified)) |
| 2909 | ("writeToMemory", writeToMemoryFunction(*structMembers[i].type)) |
| 2910 | .render(); |
| 2911 | } |
| 2912 | |
| 2913 | return m_functionCollector.createFunction(functionName, [&] { |
| 2914 | return Whiskers(R"( |
| 2915 | function <functionName>(slot) -> value { |
| 2916 | value := <allocStruct>() |
| 2917 | <#member> |
| 2918 | <setMember> |
| 2919 | </member> |
| 2920 | } |
| 2921 | )") |
| 2922 | ("functionName", functionName) |
| 2923 | ("allocStruct", allocateMemoryStructFunction(structType)) |
| 2924 | ("member", memberSetValues) |
| 2925 | .render(); |
| 2926 | }); |
| 2927 | } |
| 2928 | |
| 2929 | std::string YulUtilFunctions::readFromMemory(Type const& _type) |
| 2930 | { |
nothing calls this directly
no test coverage detected