Group decoding function cases.

This commit is contained in:
chriseth 2020-12-07 14:14:19 +01:00
parent c996d74041
commit 251f722919
4 changed files with 62 additions and 60 deletions

View File

@ -219,23 +219,18 @@ string ABIFunctions::tupleDecoder(TypePointers const& _types, bool _fromMemory)
valueReturnParams.emplace_back("value" + to_string(stackPos));
stackPos++;
}
bool dynamic = decodingTypes[i]->isDynamicallyEncoded();
Whiskers elementTempl(
dynamic ?
R"(
Whiskers elementTempl(R"(
{
let offset := <load>(add(headStart, <pos>))
if gt(offset, 0xffffffffffffffff) { <revertString> }
<?dynamic>
let offset := <load>(add(headStart, <pos>))
if gt(offset, 0xffffffffffffffff) { <revertString> }
<!dynamic>
let offset := <pos>
</dynamic>
<values> := <abiDecode>(add(headStart, offset), dataEnd)
}
)" :
R"(
{
let offset := <pos>
<values> := <abiDecode>(add(headStart, offset), dataEnd)
}
)"
);
)");
elementTempl("dynamic", decodingTypes[i]->isDynamicallyEncoded());
// TODO add test
elementTempl("revertString", revertReasonIfDebug("ABI decoding: invalid tuple offset"));
elementTempl("load", _fromMemory ? "mload" : "calldataload");
@ -1357,19 +1352,16 @@ string ABIFunctions::abiDecodingFunctionStruct(StructType const& _type, bool _fr
solAssert(!member.type->containsNestedMapping(), "");
auto decodingType = member.type->decodingType();
solAssert(decodingType, "");
bool dynamic = decodingType->isDynamicallyEncoded();
Whiskers memberTempl(
dynamic ?
R"(
Whiskers memberTempl(R"(
<?dynamic>
let offset := <load>(add(headStart, <pos>))
if gt(offset, 0xffffffffffffffff) { <revertString> }
mstore(add(value, <memoryOffset>), <abiDecode>(add(headStart, offset), end))
)" :
R"(
<!dynamic>
let offset := <pos>
mstore(add(value, <memoryOffset>), <abiDecode>(add(headStart, offset), end))
)"
);
</dynamic>
mstore(add(value, <memoryOffset>), <abiDecode>(add(headStart, offset), end))
)");
memberTempl("dynamic", decodingType->isDynamicallyEncoded());
// TODO add test
memberTempl("revertString", revertReasonIfDebug("ABI decoding: invalid struct offset"));
memberTempl("load", _fromMemory ? "mload" : "calldataload");

View File

@ -10,7 +10,7 @@
"ast":
{
"nodeType": "YulBlock",
"src": "0:823:1",
"src": "0:825:1",
"statements":
[
{
@ -406,7 +406,7 @@
"body":
{
"nodeType": "YulBlock",
"src": "498:322:1",
"src": "498:324:1",
"statements":
[
{
@ -499,12 +499,12 @@
},
{
"nodeType": "YulBlock",
"src": "570:243:1",
"src": "570:245:1",
"statements":
[
{
"nodeType": "YulVariableDeclaration",
"src": "584:45:1",
"src": "585:45:1",
"value":
{
"arguments":
@ -515,12 +515,12 @@
{
"name": "headStart",
"nodeType": "YulIdentifier",
"src": "615:9:1"
"src": "616:9:1"
},
{
"kind": "number",
"nodeType": "YulLiteral",
"src": "626:1:1",
"src": "627:1:1",
"type": "",
"value": "0"
}
@ -529,27 +529,27 @@
{
"name": "add",
"nodeType": "YulIdentifier",
"src": "611:3:1"
"src": "612:3:1"
},
"nodeType": "YulFunctionCall",
"src": "611:17:1"
"src": "612:17:1"
}
],
"functionName":
{
"name": "calldataload",
"nodeType": "YulIdentifier",
"src": "598:12:1"
"src": "599:12:1"
},
"nodeType": "YulFunctionCall",
"src": "598:31:1"
"src": "599:31:1"
},
"variables":
[
{
"name": "offset",
"nodeType": "YulTypedName",
"src": "588:6:1",
"src": "589:6:1",
"type": ""
}
]
@ -558,7 +558,7 @@
"body":
{
"nodeType": "YulBlock",
"src": "676:16:1",
"src": "677:16:1",
"statements":
[
{
@ -569,14 +569,14 @@
{
"kind": "number",
"nodeType": "YulLiteral",
"src": "685:1:1",
"src": "686:1:1",
"type": "",
"value": "0"
},
{
"kind": "number",
"nodeType": "YulLiteral",
"src": "688:1:1",
"src": "689:1:1",
"type": "",
"value": "0"
}
@ -585,13 +585,13 @@
{
"name": "revert",
"nodeType": "YulIdentifier",
"src": "678:6:1"
"src": "679:6:1"
},
"nodeType": "YulFunctionCall",
"src": "678:12:1"
"src": "679:12:1"
},
"nodeType": "YulExpressionStatement",
"src": "678:12:1"
"src": "679:12:1"
}
]
},
@ -602,12 +602,12 @@
{
"name": "offset",
"nodeType": "YulIdentifier",
"src": "648:6:1"
"src": "649:6:1"
},
{
"kind": "number",
"nodeType": "YulLiteral",
"src": "656:18:1",
"src": "657:18:1",
"type": "",
"value": "0xffffffffffffffff"
}
@ -616,17 +616,17 @@
{
"name": "gt",
"nodeType": "YulIdentifier",
"src": "645:2:1"
"src": "646:2:1"
},
"nodeType": "YulFunctionCall",
"src": "645:30:1"
"src": "646:30:1"
},
"nodeType": "YulIf",
"src": "642:2:1"
"src": "643:2:1"
},
{
"nodeType": "YulAssignment",
"src": "705:98:1",
"src": "707:98:1",
"value":
{
"arguments":
@ -637,49 +637,49 @@
{
"name": "headStart",
"nodeType": "YulIdentifier",
"src": "775:9:1"
"src": "777:9:1"
},
{
"name": "offset",
"nodeType": "YulIdentifier",
"src": "786:6:1"
"src": "788:6:1"
}
],
"functionName":
{
"name": "add",
"nodeType": "YulIdentifier",
"src": "771:3:1"
"src": "773:3:1"
},
"nodeType": "YulFunctionCall",
"src": "771:22:1"
"src": "773:22:1"
},
{
"name": "dataEnd",
"nodeType": "YulIdentifier",
"src": "795:7:1"
"src": "797:7:1"
}
],
"functionName":
{
"name": "abi_decode_t_array$_t_uint256_$dyn_calldata_ptr",
"nodeType": "YulIdentifier",
"src": "723:47:1"
"src": "725:47:1"
},
"nodeType": "YulFunctionCall",
"src": "723:80:1"
"src": "725:80:1"
},
"variableNames":
[
{
"name": "value0",
"nodeType": "YulIdentifier",
"src": "705:6:1"
"src": "707:6:1"
},
{
"name": "value1",
"nodeType": "YulIdentifier",
"src": "713:6:1"
"src": "715:6:1"
}
]
}
@ -719,11 +719,11 @@
"type": ""
}
],
"src": "397:423:1"
"src": "397:425:1"
}
]
},
"contents": "{\n\n // uint256[]\n function abi_decode_t_array$_t_uint256_$dyn_calldata_ptr(offset, end) -> arrayPos, length {\n if iszero(slt(add(offset, 0x1f), end)) { revert(0, 0) }\n length := calldataload(offset)\n if gt(length, 0xffffffffffffffff) { revert(0, 0) }\n arrayPos := add(offset, 0x20)\n if gt(add(arrayPos, mul(length, 0x20)), end) { revert(0, 0) }\n }\n\n function abi_decode_tuple_t_array$_t_uint256_$dyn_calldata_ptr(headStart, dataEnd) -> value0, value1 {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n\n {\n let offset := calldataload(add(headStart, 0))\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n value0, value1 := abi_decode_t_array$_t_uint256_$dyn_calldata_ptr(add(headStart, offset), dataEnd)\n }\n\n }\n\n}\n",
"contents": "{\n\n // uint256[]\n function abi_decode_t_array$_t_uint256_$dyn_calldata_ptr(offset, end) -> arrayPos, length {\n if iszero(slt(add(offset, 0x1f), end)) { revert(0, 0) }\n length := calldataload(offset)\n if gt(length, 0xffffffffffffffff) { revert(0, 0) }\n arrayPos := add(offset, 0x20)\n if gt(add(arrayPos, mul(length, 0x20)), end) { revert(0, 0) }\n }\n\n function abi_decode_tuple_t_array$_t_uint256_$dyn_calldata_ptr(headStart, dataEnd) -> value0, value1 {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n\n {\n\n let offset := calldataload(add(headStart, 0))\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n\n value0, value1 := abi_decode_t_array$_t_uint256_$dyn_calldata_ptr(add(headStart, offset), dataEnd)\n }\n\n }\n\n}\n",
"id": 1,
"language": "Yul",
"name": "#utility.yul"

View File

@ -57,22 +57,30 @@ object "C_80" {
if slt(sub(dataEnd, headStart), 128) { revert(0, 0) }
{
let offset := 0
value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd)
}
{
let offset := 32
value1 := abi_decode_t_uint256(add(headStart, offset), dataEnd)
}
{
let offset := 64
value2 := abi_decode_t_uint256(add(headStart, offset), dataEnd)
}
{
let offset := 96
value3 := abi_decode_t_uint256(add(headStart, offset), dataEnd)
}

File diff suppressed because one or more lines are too long