[Sol->Yul] Implementing bytes copying from calldata to memory.

This commit is contained in:
Djordje Mijovic 2020-07-23 12:54:13 +02:00
parent da189a6678
commit 96258c7e75
11 changed files with 53 additions and 0 deletions

View File

@ -2406,6 +2406,29 @@ string YulUtilFunctions::conversionFunctionSpecial(Type const& _from, Type const
.render();
}
if (_from.category() == Type::Category::Array && _to.category() == Type::Category::Array)
{
auto const& fromArrayType = dynamic_cast<ArrayType const&>(_from);
auto const& toArrayType = dynamic_cast<ArrayType const&>(_to);
solAssert(!fromArrayType.baseType()->isDynamicallyEncoded(), "");
solUnimplementedAssert(fromArrayType.isByteArray() && toArrayType.isByteArray(), "");
solUnimplementedAssert(toArrayType.location() == DataLocation::Memory, "");
solUnimplementedAssert(fromArrayType.location() == DataLocation::CallData, "");
solUnimplementedAssert(toArrayType.isDynamicallySized(), "");
Whiskers templ(R"(
function <functionName>(offset, length) -> converted {
converted := <allocateMemoryArray>(length)
<copyToMemory>(offset, add(converted, 0x20), length)
}
)");
templ("functionName", functionName);
templ("allocateMemoryArray", allocateMemoryArrayFunction(toArrayType));
templ("copyToMemory", copyToMemoryFunction(fromArrayType.location() == DataLocation::CallData));
return templ.render();
}
solUnimplementedAssert(
_from.category() == Type::Category::StringLiteral,
"Type conversion " + _from.toString() + " -> " + _to.toString() + " not yet implemented."

View File

@ -43,6 +43,7 @@ contract C {
}
}
// ====
// compileViaYul: also
// EVMVersion: >homestead
// ----
// g() -> 32, 196, hex"eccb829a", 32, 1, 32, 32, 1, 42, hex"00000000000000000000000000000000000000000000000000000000"

View File

@ -14,6 +14,7 @@ contract C {
}
}
// ====
// compileViaYul: also
// EVMVersion: >homestead
// ----
// f(uint256[]): 0x20, 2, 1, 1 -> 0x20, 0x84, hex"304a4c23", 0x20, 2, 1, 1, hex"00000000000000000000000000000000000000000000000000000000"

View File

@ -16,6 +16,7 @@ contract C {
}
}
// ====
// compileViaYul: also
// EVMVersion: >homestead
// ----
// f(uint256,bytes32): 1, left(0x01) -> 0x20, 0x44, hex"b63240b0", 1, left(0x01), hex"00000000000000000000000000000000000000000000000000000000"

View File

@ -15,6 +15,7 @@ contract C {
}
}
// ====
// compileViaYul: also
// EVMVersion: >homestead
// ----
// f(uint256,uint256): 1, 1 -> 0x20, 0x44, hex"78b86ac6", 1, 1, hex"00000000000000000000000000000000000000000000000000000000"

View File

@ -10,6 +10,8 @@ contract C {
return (a.length, m.length, m);
}
}
// ====
// compileViaYul: also
// ----
// f(bytes[]): 0x20, 0x1, 0x20, 0x2, hex"6162000000000000000000000000000000000000000000000000000000000000" -> 0x1, 0x2, 0x60, 0x2, hex"6162000000000000000000000000000000000000000000000000000000000000"
// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex"7878787878787878787878787878787878787878787878787878787878787878" -> 0x1, 0x20, 0x60, 0x20, hex"7878787878787878787878787878787878787878787878787878787878787878"

View File

@ -0,0 +1,9 @@
contract C {
function f(bytes calldata data) external returns (bytes32) {
return keccak256(bytes(data));
}
}
// ====
// compileViaYul: also
// ----
// f(bytes): 0x20, 0x08, "abcdefgh" -> 0x48624fa43c68d5c552855a4e2919e74645f683f5384f72b5b051b71ea41d4f2d

View File

@ -0,0 +1,9 @@
contract C {
function f(bytes calldata data) external returns (bytes memory) {
return abi.encode(bytes(data));
}
}
// ====
// compileViaYul: also
// ----
// f(bytes): 0x20, 0x08, "abcdefgh" -> 0x20, 0x60, 0x20, 8, 44048183304486788309563647967830685498285570828042699209880294173606615711744

View File

@ -11,5 +11,7 @@ contract C {
return (a.length, m1.length, uint8(m1[0]), s1);
}
}
// ====
// compileViaYul: also
// ----
// f(string[]): 0x20, 0x1, 0x20, 0x2, hex"6162000000000000000000000000000000000000000000000000000000000000" -> 1, 2, 97, 0x80, 2, "ab"

View File

@ -13,5 +13,7 @@ contract C {
return (_x.f()[0], _x.g()[0]);
}
}
// ====
// compileViaYul: also
// ----
// f(bytes): 0x20, 4, "abcd" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000

View File

@ -13,5 +13,7 @@ contract C {
return (_x.f(), _x.g());
}
}
// ====
// compileViaYul: also
// ----
// f(bytes): 0x20, 4, "abcd" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000