Support copying dynamically encoded structs from calldata to memory.

This commit is contained in:
Djordje Mijovic 2020-11-24 15:12:31 +01:00
parent 2d235bf7b0
commit 200227ab75
8 changed files with 45 additions and 10 deletions

View File

@ -1,6 +1,7 @@
### 0.7.6 (unreleased)
Language Features:
* Code generator: Support copying dynamically encoded structs from calldata to memory.
* The fallback function can now also have a single ``calldata`` argument (equaling ``msg.data``) and return ``bytes memory`` (which will not be ABI-encoded but returned as-is).
Compiler Features:

View File

@ -1106,11 +1106,22 @@ void CompilerUtils::convertType(
}
case DataLocation::CallData:
{
solUnimplementedAssert(!typeOnStack.isDynamicallyEncoded(), "");
if (typeOnStack.isDynamicallyEncoded())
{
solAssert(m_context.useABICoderV2(), "");
m_context.callYulFunction(
m_context.utilFunctions().conversionFunction(typeOnStack, targetType),
1,
1
);
}
else
{
m_context << Instruction::DUP1;
m_context << Instruction::CALLDATASIZE;
m_context << Instruction::SUB;
abiDecode({&targetType}, false);
}
break;
}
case DataLocation::Memory:

View File

@ -42,7 +42,7 @@ contract C {
}
}
// ====
// compileViaYul: true
// compileViaYul: also
// ----
// f((uint128, (uint128, uint256[][2], uint32)), uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33
// g(((uint128, uint256[][2], uint32)[2])): 0x20, 0x20, 0x40, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 22, 1, 2, 33

View File

@ -23,7 +23,7 @@ contract C {
}
}
// ====
// compileViaYul: true
// compileViaYul: also
// ----
// library: L
// f((uint128, (uint128, uint256[][2], uint32)), uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33

View File

@ -18,6 +18,6 @@ contract C {
}
}
// ====
// compileViaYul: true
// compileViaYul: also
// ----
// f(uint32, (uint128, uint256[][2], uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88

View File

@ -17,6 +17,6 @@ contract C {
}
}
// ====
// compileViaYul: true
// compileViaYul: also
// ----
// f(uint32, (uint128, uint256[][2], uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88

View File

@ -0,0 +1,23 @@
pragma experimental ABIEncoderV2;
contract C {
struct S {
uint256 a;
bytes b;
uint256 c;
}
function f(S calldata c)
external
pure
returns (uint256, byte, byte, uint256)
{
S memory m = c;
return (m.a, m.b[0], m.b[1], m.c);
}
}
// ====
// compileViaYul: also
// ----
// f((uint256,bytes,uint256)): 0x20, 42, 0x60, 23, 2, "ab" -> 42, "a", "b", 23

View File

@ -18,6 +18,6 @@ contract C {
}
}
// ====
// compileViaYul: true
// compileViaYul: also
// ----
// f(uint32, (uint128, uint256[][2], uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88