| 3061 | } |
| 3062 | |
| 3063 | std::string YulUtilFunctions::writeToMemoryFunction(Type const& _type) |
| 3064 | { |
| 3065 | std::string const functionName = "write_to_memory_" + _type.identifier(); |
| 3066 | |
| 3067 | return m_functionCollector.createFunction(functionName, [&] { |
| 3068 | solAssert(!dynamic_cast<StringLiteralType const*>(&_type), ""); |
| 3069 | if (auto ref = dynamic_cast<ReferenceType const*>(&_type)) |
| 3070 | { |
| 3071 | solAssert( |
| 3072 | ref->location() == DataLocation::Memory, |
| 3073 | "Can only update types with location memory." |
| 3074 | ); |
| 3075 | |
| 3076 | return Whiskers(R"( |
| 3077 | function <functionName>(memPtr, value) { |
| 3078 | mstore(memPtr, value) |
| 3079 | } |
| 3080 | )") |
| 3081 | ("functionName", functionName) |
| 3082 | .render(); |
| 3083 | } |
| 3084 | else if ( |
| 3085 | _type.category() == Type::Category::Function && |
| 3086 | dynamic_cast<FunctionType const&>(_type).kind() == FunctionType::Kind::External |
| 3087 | ) |
| 3088 | { |
| 3089 | return Whiskers(R"( |
| 3090 | function <functionName>(memPtr, addr, selector) { |
| 3091 | mstore(memPtr, <combine>(addr, selector)) |
| 3092 | } |
| 3093 | )") |
| 3094 | ("functionName", functionName) |
| 3095 | ("combine", combineExternalFunctionIdFunction()) |
| 3096 | .render(); |
| 3097 | } |
| 3098 | else if (_type.isValueType()) |
| 3099 | { |
| 3100 | return Whiskers(R"( |
| 3101 | function <functionName>(memPtr, value) { |
| 3102 | mstore(memPtr, <cleanup>(value)) |
| 3103 | } |
| 3104 | )") |
| 3105 | ("functionName", functionName) |
| 3106 | ("cleanup", cleanupFunction(_type)) |
| 3107 | .render(); |
| 3108 | } |
| 3109 | else // Should never happen |
| 3110 | { |
| 3111 | solAssert( |
| 3112 | false, |
| 3113 | "Memory store of type " + _type.toString(true) + " not allowed." |
| 3114 | ); |
| 3115 | } |
| 3116 | }); |
| 3117 | } |
| 3118 | |
| 3119 | std::string YulUtilFunctions::extractFromStorageValueDynamic(Type const& _type) |
| 3120 | { |
no test coverage detected