diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 98c0b2169..feaacce1d 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -884,6 +884,45 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) m_code << templ.render(); break; } + case FunctionType::Kind::ABIDecode: + { + Whiskers templ(R"( + let := (, add(, )) + )"); + + TypePointer firstArgType = arguments.front()->annotation().type; + TypePointers targetTypes; + + if (TupleType const* targetTupleType = dynamic_cast(_functionCall.annotation().type)) + targetTypes = targetTupleType->components(); + else + targetTypes = TypePointers{_functionCall.annotation().type}; + + if ( + auto referenceType = dynamic_cast(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: { solAssert(arguments.size() == parameterTypes.size(), ""); @@ -1369,7 +1408,6 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess) else if (member == "data") { IRVariable var(_memberAccess); - declare(var); define(var.part("offset")) << "0\n"; define(var.part("length")) << "calldatasize()\n"; } diff --git a/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_dynamic_array.sol b/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_dynamic_array.sol index 180d89ec1..4a67993ee 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_dynamic_array.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_dynamic_array.sol @@ -4,5 +4,7 @@ contract C { } } +// ==== +// compileViaYul: also // ---- // f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 diff --git a/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_static_array.sol b/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_static_array.sol index 270a5abc0..eeb8bfc70 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_static_array.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_static_array.sol @@ -8,5 +8,7 @@ contract C { } } +// ==== +// compileViaYul: also // ---- // f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6 diff --git a/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_static_array_v2.sol b/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_static_array_v2.sol index 46450f704..27c022cfd 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_static_array_v2.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_static_array_v2.sol @@ -11,5 +11,7 @@ contract C { } } +// ==== +// compileViaYul: also // ---- // f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6 diff --git a/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_trivial.sol b/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_trivial.sol index 7b873951f..f02d75d17 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_trivial.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_trivial.sol @@ -4,5 +4,7 @@ contract C { } } +// ==== +// compileViaYul: also // ---- // f(bytes): 0x20, 0x20, 0x21 -> 33 diff --git a/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_decode_simple.sol b/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_decode_simple.sol index 1fbcfa53d..b0205606f 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_decode_simple.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_decode_simple.sol @@ -5,5 +5,7 @@ contract C { } } +// ==== +// compileViaYul: also // ---- // f() -> 0x21, 0x40, 0x7, "abcdefg" diff --git a/test/libsolidity/semanticTests/abiEncoderV1/decode_slice.sol b/test/libsolidity/semanticTests/abiEncoderV1/decode_slice.sol index 35cb15077..33e32e065 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/decode_slice.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/decode_slice.sol @@ -5,5 +5,8 @@ contract C { f = abi.decode(msg.data[4 + 32 : 4 + 32 + 32], (uint256)); } } + +// ==== +// compileViaYul: also // ---- // f(uint256,uint256): 42, 23 -> 42, 23, 42, 23 diff --git a/test/libsolidity/semanticTests/abiEncoderV1/dynamic_memory_copy.sol b/test/libsolidity/semanticTests/abiEncoderV1/dynamic_memory_copy.sol index ef2b07cb5..450dfa4d5 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/dynamic_memory_copy.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/dynamic_memory_copy.sol @@ -18,6 +18,9 @@ contract C { } } } + +// ==== +// compileViaYul: also // ---- // test(bytes): 0x20, 0x80, 0x40, 0x60, 0, 0 -> false, false // test(bytes): 0x20, 0xC0, 0x40, 0x80, 1, 0x42, 1, 0x42 -> false, false diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_decode_calldata.sol b/test/libsolidity/semanticTests/abiencodedecode/abi_decode_calldata.sol index 6b6e55e02..0574c4dd2 100644 --- a/test/libsolidity/semanticTests/abiencodedecode/abi_decode_calldata.sol +++ b/test/libsolidity/semanticTests/abiencodedecode/abi_decode_calldata.sol @@ -7,5 +7,8 @@ contract C { return abi.decode(data, (uint256, bytes)); } } + +// ==== +// compileViaYul: also // ---- // f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, "abcdefg" -> 0x21, 0x40, 0x7, "abcdefg" diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple.sol b/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple.sol index 9ae6602f3..b3eb6724d 100644 --- a/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple.sol +++ b/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple.sol @@ -3,5 +3,8 @@ contract C { return abi.decode(data, (uint256, bytes)); } } + +// ==== +// compileViaYul: also // ---- // f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, "abcdefg" -> 0x21, 0x40, 0x7, "abcdefg" diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol b/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol index af37480a3..d08e2ff82 100644 --- a/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol +++ b/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol @@ -6,5 +6,6 @@ contract C { return abi.decode(data, (uint256, bytes)); } } + // ---- // f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, "abcdefg" -> 0x21, 0x40, 0x7, "abcdefg"