| 116 | } |
| 117 | |
| 118 | std::string ABIFunctions::tupleEncoderPacked( |
| 119 | TypePointers const& _givenTypes, |
| 120 | TypePointers _targetTypes, |
| 121 | bool _reversed |
| 122 | ) |
| 123 | { |
| 124 | EncodingOptions options; |
| 125 | options.encodeAsLibraryTypes = false; |
| 126 | options.encodeFunctionFromStack = true; |
| 127 | options.padded = false; |
| 128 | options.dynamicInplace = true; |
| 129 | |
| 130 | for (Type const*& t: _targetTypes) |
| 131 | { |
| 132 | solAssert(t, ""); |
| 133 | t = t->fullEncodingType(options.encodeAsLibraryTypes, true, !options.padded); |
| 134 | solAssert(t, ""); |
| 135 | } |
| 136 | |
| 137 | std::string functionName = std::string("abi_encode_tuple_packed_"); |
| 138 | for (auto const& t: _givenTypes) |
| 139 | functionName += t->identifier() + "_"; |
| 140 | functionName += "_to_"; |
| 141 | for (auto const& t: _targetTypes) |
| 142 | functionName += t->identifier() + "_"; |
| 143 | functionName += options.toFunctionNameSuffix(); |
| 144 | if (_reversed) |
| 145 | functionName += "_reversed"; |
| 146 | |
| 147 | return createFunction(functionName, [&]() { |
| 148 | // Note that the values are in reverse due to the difference in calling semantics. |
| 149 | Whiskers templ(R"( |
| 150 | function <functionName>(pos <valueParams>) -> end { |
| 151 | <encodeElements> |
| 152 | end := pos |
| 153 | } |
| 154 | )"); |
| 155 | templ("functionName", functionName); |
| 156 | std::string encodeElements; |
| 157 | size_t stackPos = 0; |
| 158 | for (size_t i = 0; i < _givenTypes.size(); ++i) |
| 159 | { |
| 160 | solAssert(_givenTypes[i], ""); |
| 161 | solAssert(_targetTypes[i], ""); |
| 162 | size_t sizeOnStack = _givenTypes[i]->sizeOnStack(); |
| 163 | bool dynamic = _targetTypes[i]->isDynamicallyEncoded(); |
| 164 | Whiskers elementTempl( |
| 165 | dynamic ? |
| 166 | std::string(R"( |
| 167 | pos := <abiEncode>(<values> pos) |
| 168 | )") : |
| 169 | std::string(R"( |
| 170 | <abiEncode>(<values> pos) |
| 171 | pos := add(pos, <calldataEncodedSize>) |
| 172 | )") |
| 173 | ); |
| 174 | std::string values = suffixedVariableNameList("value", stackPos, stackPos + sizeOnStack); |
| 175 | elementTempl("values", values.empty() ? "" : values + ", "); |
no test coverage detected