Merge pull request #10513 from ethereum/groupDecoder

Group decoding function cases.
This commit is contained in:
chriseth 2020-12-07 14:40:19 +01:00 committed by GitHub
commit 73a2843f05
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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)); valueReturnParams.emplace_back("value" + to_string(stackPos));
stackPos++; stackPos++;
} }
bool dynamic = decodingTypes[i]->isDynamicallyEncoded(); Whiskers elementTempl(R"(
Whiskers elementTempl(
dynamic ?
R"(
{ {
<?dynamic>
let offset := <load>(add(headStart, <pos>)) let offset := <load>(add(headStart, <pos>))
if gt(offset, 0xffffffffffffffff) { <revertString> } if gt(offset, 0xffffffffffffffff) { <revertString> }
<values> := <abiDecode>(add(headStart, offset), dataEnd) <!dynamic>
}
)" :
R"(
{
let offset := <pos> let offset := <pos>
</dynamic>
<values> := <abiDecode>(add(headStart, offset), dataEnd) <values> := <abiDecode>(add(headStart, offset), dataEnd)
} }
)" )");
); elementTempl("dynamic", decodingTypes[i]->isDynamicallyEncoded());
// TODO add test // TODO add test
elementTempl("revertString", revertReasonIfDebug("ABI decoding: invalid tuple offset")); elementTempl("revertString", revertReasonIfDebug("ABI decoding: invalid tuple offset"));
elementTempl("load", _fromMemory ? "mload" : "calldataload"); elementTempl("load", _fromMemory ? "mload" : "calldataload");
@ -1357,19 +1352,16 @@ string ABIFunctions::abiDecodingFunctionStruct(StructType const& _type, bool _fr
solAssert(!member.type->containsNestedMapping(), ""); solAssert(!member.type->containsNestedMapping(), "");
auto decodingType = member.type->decodingType(); auto decodingType = member.type->decodingType();
solAssert(decodingType, ""); solAssert(decodingType, "");
bool dynamic = decodingType->isDynamicallyEncoded(); Whiskers memberTempl(R"(
Whiskers memberTempl( <?dynamic>
dynamic ?
R"(
let offset := <load>(add(headStart, <pos>)) let offset := <load>(add(headStart, <pos>))
if gt(offset, 0xffffffffffffffff) { <revertString> } if gt(offset, 0xffffffffffffffff) { <revertString> }
mstore(add(value, <memoryOffset>), <abiDecode>(add(headStart, offset), end)) <!dynamic>
)" :
R"(
let offset := <pos> let offset := <pos>
</dynamic>
mstore(add(value, <memoryOffset>), <abiDecode>(add(headStart, offset), end)) mstore(add(value, <memoryOffset>), <abiDecode>(add(headStart, offset), end))
)" )");
); memberTempl("dynamic", decodingType->isDynamicallyEncoded());
// TODO add test // TODO add test
memberTempl("revertString", revertReasonIfDebug("ABI decoding: invalid struct offset")); memberTempl("revertString", revertReasonIfDebug("ABI decoding: invalid struct offset"));
memberTempl("load", _fromMemory ? "mload" : "calldataload"); memberTempl("load", _fromMemory ? "mload" : "calldataload");

View File

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

View File

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

File diff suppressed because one or more lines are too long