| 2737 | } |
| 2738 | |
| 2739 | std::string YulUtilFunctions::mappingIndexAccessFunction(MappingType const& _mappingType, Type const& _keyType) |
| 2740 | { |
| 2741 | std::string functionName = "mapping_index_access_" + _mappingType.identifier() + "_of_" + _keyType.identifier(); |
| 2742 | return m_functionCollector.createFunction(functionName, [&]() { |
| 2743 | if (_mappingType.keyType()->isDynamicallySized()) |
| 2744 | return Whiskers(R"( |
| 2745 | function <functionName>(slot <?+key>,</+key> <key>) -> dataSlot { |
| 2746 | dataSlot := <hash>(<key> <?+key>,</+key> slot) |
| 2747 | } |
| 2748 | )") |
| 2749 | ("functionName", functionName) |
| 2750 | ("key", suffixedVariableNameList("key_", 0, _keyType.sizeOnStack())) |
| 2751 | ("hash", packedHashFunction( |
| 2752 | {&_keyType, TypeProvider::uint256()}, |
| 2753 | {_mappingType.keyType(), TypeProvider::uint256()} |
| 2754 | )) |
| 2755 | .render(); |
| 2756 | else |
| 2757 | { |
| 2758 | solAssert(CompilerUtils::freeMemoryPointer >= 0x40, ""); |
| 2759 | solAssert(!_mappingType.keyType()->isDynamicallyEncoded(), ""); |
| 2760 | solAssert(_mappingType.keyType()->calldataEncodedSize(false) <= 0x20, ""); |
| 2761 | Whiskers templ(R"( |
| 2762 | function <functionName>(slot <key>) -> dataSlot { |
| 2763 | mstore(0, <convertedKey>) |
| 2764 | mstore(0x20, slot) |
| 2765 | dataSlot := keccak256(0, 0x40) |
| 2766 | } |
| 2767 | )"); |
| 2768 | templ("functionName", functionName); |
| 2769 | templ("key", _keyType.sizeOnStack() == 1 ? ", key" : ""); |
| 2770 | if (_keyType.sizeOnStack() == 0) |
| 2771 | templ("convertedKey", conversionFunction(_keyType, *_mappingType.keyType()) + "()"); |
| 2772 | else |
| 2773 | templ("convertedKey", conversionFunction(_keyType, *_mappingType.keyType()) + "(key)"); |
| 2774 | return templ.render(); |
| 2775 | } |
| 2776 | }); |
| 2777 | } |
| 2778 | |
| 2779 | std::string YulUtilFunctions::readFromStorage( |
| 2780 | Type const& _type, |
no test coverage detected