MCPcopy Create free account
hub / github.com/argotorg/solidity / tupleDecoder

Method tupleDecoder

libsolidity/codegen/ABIFunctions.cpp:192–260  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

190 });
191}
192std::string ABIFunctions::tupleDecoder(TypePointers const& _types, bool _fromMemory)
193{
194 std::string functionName = std::string("abi_decode_tuple_");
195 for (auto const& t: _types)
196 functionName += t->identifier();
197 if (_fromMemory)
198 functionName += "_fromMemory";
199
200 return createFunction(functionName, [&]() {
201 TypePointers decodingTypes;
202 for (auto const& t: _types)
203 decodingTypes.emplace_back(t->decodingType());
204
205 Whiskers templ(R"(
206 function <functionName>(headStart, dataEnd) <arrow> <valueReturnParams> {
207 if slt(sub(dataEnd, headStart), <minimumSize>) { <revertString>() }
208 <decodeElements>
209 }
210 )");
211 templ("functionName", functionName);
212 templ("revertString", revertReasonIfDebugFunction("ABI decoding: tuple data too short"));
213 templ("minimumSize", std::to_string(headSize(decodingTypes)));
214
215 std::string decodeElements;
216 std::vector<std::string> valueReturnParams;
217 size_t headPos = 0;
218 size_t stackPos = 0;
219 for (size_t i = 0; i < _types.size(); ++i)
220 {
221 solAssert(_types[i], "");
222 solAssert(decodingTypes[i], "");
223 size_t sizeOnStack = _types[i]->sizeOnStack();
224 solAssert(sizeOnStack == decodingTypes[i]->sizeOnStack(), "");
225 solAssert(sizeOnStack > 0, "");
226 std::vector<std::string> valueNamesLocal;
227 for (size_t j = 0; j < sizeOnStack; j++)
228 {
229 valueNamesLocal.emplace_back("value" + std::to_string(stackPos));
230 valueReturnParams.emplace_back("value" + std::to_string(stackPos));
231 stackPos++;
232 }
233 Whiskers elementTempl(R"(
234 {
235 <?dynamic>
236 let offset := <load>(add(headStart, <pos>))
237 if gt(offset, 0xffffffffffffffff) { <revertString>() }
238 <!dynamic>
239 let offset := <pos>
240 </dynamic>
241 <values> := <abiDecode>(add(headStart, offset), dataEnd)
242 }
243 )");
244 elementTempl("dynamic", decodingTypes[i]->isDynamicallyEncoded());
245 // TODO add test
246 elementTempl("revertString", revertReasonIfDebugFunction("ABI decoding: invalid tuple offset"));
247 elementTempl("load", _fromMemory ? "mload" : "calldataload");
248 elementTempl("values", boost::algorithm::join(valueNamesLocal, ", "));
249 elementTempl("pos", std::to_string(headPos));

Callers 5

abiDecodeV2Method · 0.80
endVisitMethod · 0.80

Calls 10

createFunctionFunction · 0.85
identifierMethod · 0.80
renderMethod · 0.80
calldataHeadSizeMethod · 0.80
to_stringFunction · 0.50
decodingTypeMethod · 0.45
sizeMethod · 0.45
sizeOnStackMethod · 0.45
isDynamicallyEncodedMethod · 0.45
emptyMethod · 0.45

Tested by

no test coverage detected