mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #9014 from ethereum/sol-yul-abidecode
[Sol - Yul] Add support for ABIDecode.
This commit is contained in:
commit
0aa3fb5026
@ -882,6 +882,45 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
|
|||||||
m_code << templ.render();
|
m_code << templ.render();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case FunctionType::Kind::ABIDecode:
|
||||||
|
{
|
||||||
|
Whiskers templ(R"(
|
||||||
|
<?+retVars>let <retVars> := </+retVars> <abiDecode>(<offset>, add(<offset>, <length>))
|
||||||
|
)");
|
||||||
|
|
||||||
|
TypePointer firstArgType = arguments.front()->annotation().type;
|
||||||
|
TypePointers targetTypes;
|
||||||
|
|
||||||
|
if (TupleType const* targetTupleType = dynamic_cast<TupleType const*>(_functionCall.annotation().type))
|
||||||
|
targetTypes = targetTupleType->components();
|
||||||
|
else
|
||||||
|
targetTypes = TypePointers{_functionCall.annotation().type};
|
||||||
|
|
||||||
|
if (
|
||||||
|
auto referenceType = dynamic_cast<ReferenceType const*>(firstArgType);
|
||||||
|
referenceType && referenceType->dataStoredIn(DataLocation::CallData)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
solAssert(referenceType->isImplicitlyConvertibleTo(*TypeProvider::bytesCalldata()), "");
|
||||||
|
IRVariable var = convert(*arguments[0], *TypeProvider::bytesCalldata());
|
||||||
|
templ("abiDecode", m_context.abiFunctions().tupleDecoder(targetTypes, false));
|
||||||
|
templ("offset", var.part("offset").name());
|
||||||
|
templ("length", var.part("length").name());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IRVariable var = convert(*arguments[0], *TypeProvider::bytesMemory());
|
||||||
|
templ("abiDecode", m_context.abiFunctions().tupleDecoder(targetTypes, true));
|
||||||
|
templ("offset", "add(" + var.part("mpos").name() + ", 32)");
|
||||||
|
templ("length",
|
||||||
|
m_utils.arrayLengthFunction(*TypeProvider::bytesMemory()) + "(" + var.part("mpos").name() + ")"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
templ("retVars", IRVariable(_functionCall).commaSeparatedList());
|
||||||
|
|
||||||
|
m_code << templ.render();
|
||||||
|
break;
|
||||||
|
}
|
||||||
case FunctionType::Kind::Revert:
|
case FunctionType::Kind::Revert:
|
||||||
{
|
{
|
||||||
solAssert(arguments.size() == parameterTypes.size(), "");
|
solAssert(arguments.size() == parameterTypes.size(), "");
|
||||||
@ -1367,7 +1406,6 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
|
|||||||
else if (member == "data")
|
else if (member == "data")
|
||||||
{
|
{
|
||||||
IRVariable var(_memberAccess);
|
IRVariable var(_memberAccess);
|
||||||
declare(var);
|
|
||||||
define(var.part("offset")) << "0\n";
|
define(var.part("offset")) << "0\n";
|
||||||
define(var.part("length")) << "calldatasize()\n";
|
define(var.part("length")) << "calldatasize()\n";
|
||||||
}
|
}
|
||||||
|
@ -4,5 +4,7 @@ contract C {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ====
|
||||||
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6
|
// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6
|
||||||
|
@ -8,5 +8,7 @@ contract C {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ====
|
||||||
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6
|
// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6
|
||||||
|
@ -11,5 +11,7 @@ contract C {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ====
|
||||||
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6
|
// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6
|
||||||
|
@ -4,5 +4,7 @@ contract C {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ====
|
||||||
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// f(bytes): 0x20, 0x20, 0x21 -> 33
|
// f(bytes): 0x20, 0x20, 0x21 -> 33
|
||||||
|
@ -5,5 +5,7 @@ contract C {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ====
|
||||||
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// f() -> 0x21, 0x40, 0x7, "abcdefg"
|
// f() -> 0x21, 0x40, 0x7, "abcdefg"
|
||||||
|
@ -5,5 +5,8 @@ contract C {
|
|||||||
f = abi.decode(msg.data[4 + 32 : 4 + 32 + 32], (uint256));
|
f = abi.decode(msg.data[4 + 32 : 4 + 32 + 32], (uint256));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ====
|
||||||
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// f(uint256,uint256): 42, 23 -> 42, 23, 42, 23
|
// f(uint256,uint256): 42, 23 -> 42, 23, 42, 23
|
||||||
|
@ -18,6 +18,9 @@ contract C {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ====
|
||||||
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// test(bytes): 0x20, 0x80, 0x40, 0x60, 0, 0 -> false, false
|
// test(bytes): 0x20, 0x80, 0x40, 0x60, 0, 0 -> false, false
|
||||||
// test(bytes): 0x20, 0xC0, 0x40, 0x80, 1, 0x42, 1, 0x42 -> false, false
|
// test(bytes): 0x20, 0xC0, 0x40, 0x80, 1, 0x42, 1, 0x42 -> false, false
|
||||||
|
@ -7,5 +7,8 @@ contract C {
|
|||||||
return abi.decode(data, (uint256, bytes));
|
return abi.decode(data, (uint256, bytes));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ====
|
||||||
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, "abcdefg" -> 0x21, 0x40, 0x7, "abcdefg"
|
// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, "abcdefg" -> 0x21, 0x40, 0x7, "abcdefg"
|
||||||
|
@ -3,5 +3,8 @@ contract C {
|
|||||||
return abi.decode(data, (uint256, bytes));
|
return abi.decode(data, (uint256, bytes));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ====
|
||||||
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, "abcdefg" -> 0x21, 0x40, 0x7, "abcdefg"
|
// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, "abcdefg" -> 0x21, 0x40, 0x7, "abcdefg"
|
||||||
|
@ -6,5 +6,6 @@ contract C {
|
|||||||
return abi.decode(data, (uint256, bytes));
|
return abi.decode(data, (uint256, bytes));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----
|
// ----
|
||||||
// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, "abcdefg" -> 0x21, 0x40, 0x7, "abcdefg"
|
// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, "abcdefg" -> 0x21, 0x40, 0x7, "abcdefg"
|
||||||
|
Loading…
Reference in New Issue
Block a user