[Sol->Yul] Implementing conversion of struct to struct pointer.

Co-authored-by: Daniel Kirchner <daniel@ekpyron.org>
This commit is contained in:
Djordje Mijovic 2020-10-06 14:08:00 +02:00
parent fa69378f4f
commit ad8d840ee7
9 changed files with 43 additions and 21 deletions

View File

@ -851,7 +851,6 @@ std::string YulUtilFunctions::resizeDynamicArrayFunction(ArrayType const& _type)
solAssert(_type.isDynamicallySized(), ""); solAssert(_type.isDynamicallySized(), "");
solUnimplementedAssert(!_type.isByteArray(), "Byte Arrays not yet implemented!"); solUnimplementedAssert(!_type.isByteArray(), "Byte Arrays not yet implemented!");
solUnimplementedAssert(_type.baseType()->storageBytes() <= 32, "..."); solUnimplementedAssert(_type.baseType()->storageBytes() <= 32, "...");
solUnimplementedAssert(_type.baseType()->storageSize() == 1, "");
string functionName = "resize_array_" + _type.identifier(); string functionName = "resize_array_" + _type.identifier();
return m_functionCollector.createFunction(functionName, [&]() { return m_functionCollector.createFunction(functionName, [&]() {
@ -2317,27 +2316,32 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to)
auto const& toStructType = dynamic_cast<StructType const &>(_to); auto const& toStructType = dynamic_cast<StructType const &>(_to);
solAssert(fromStructType.structDefinition() == toStructType.structDefinition(), ""); solAssert(fromStructType.structDefinition() == toStructType.structDefinition(), "");
solUnimplementedAssert(!fromStructType.isDynamicallyEncoded(), ""); if (fromStructType.location() == toStructType.location() && toStructType.isPointer())
solUnimplementedAssert(toStructType.location() == DataLocation::Memory, ""); body = "converted := value";
solUnimplementedAssert(fromStructType.location() != DataLocation::Memory, "");
if (fromStructType.location() == DataLocation::CallData)
{
body = Whiskers(R"(
converted := <abiDecode>(value, calldatasize())
)")("abiDecode", ABIFunctions(m_evmVersion, m_revertStrings, m_functionCollector).tupleDecoder(
{&toStructType}
)).render();
}
else else
{ {
solAssert(fromStructType.location() == DataLocation::Storage, ""); solUnimplementedAssert(toStructType.location() == DataLocation::Memory, "");
solUnimplementedAssert(fromStructType.location() != DataLocation::Memory, "");
body = Whiskers(R"( if (fromStructType.location() == DataLocation::CallData)
converted := <readFromStorage>(value) {
)") solUnimplementedAssert(!fromStructType.isDynamicallyEncoded(), "");
("readFromStorage", readFromStorage(toStructType, 0, true)) body = Whiskers(R"(
.render(); converted := <abiDecode>(value, calldatasize())
)")("abiDecode", ABIFunctions(m_evmVersion, m_revertStrings, m_functionCollector).tupleDecoder(
{&toStructType}
)).render();
}
else
{
solAssert(fromStructType.location() == DataLocation::Storage, "");
body = Whiskers(R"(
converted := <readFromStorage>(value)
)")
("readFromStorage", readFromStorage(toStructType, 0, true))
.render();
}
} }
break; break;
@ -2780,22 +2784,24 @@ string YulUtilFunctions::storageSetToZeroFunction(Type const& _type)
else if (_type.category() == Type::Category::Array) else if (_type.category() == Type::Category::Array)
return Whiskers(R"( return Whiskers(R"(
function <functionName>(slot, offset) { function <functionName>(slot, offset) {
if iszero(eq(offset, 0)) { panic() } if iszero(eq(offset, 0)) { <panic>() }
<clearArray>(slot) <clearArray>(slot)
} }
)") )")
("functionName", functionName) ("functionName", functionName)
("clearArray", clearStorageArrayFunction(dynamic_cast<ArrayType const&>(_type))) ("clearArray", clearStorageArrayFunction(dynamic_cast<ArrayType const&>(_type)))
("panic", panicFunction())
.render(); .render();
else if (_type.category() == Type::Category::Struct) else if (_type.category() == Type::Category::Struct)
return Whiskers(R"( return Whiskers(R"(
function <functionName>(slot, offset) { function <functionName>(slot, offset) {
if iszero(eq(offset, 0)) { panic() } if iszero(eq(offset, 0)) { <panic>() }
<clearStruct>(slot) <clearStruct>(slot)
} }
)") )")
("functionName", functionName) ("functionName", functionName)
("clearStruct", clearStorageStructFunction(dynamic_cast<StructType const&>(_type))) ("clearStruct", clearStorageStructFunction(dynamic_cast<StructType const&>(_type)))
("panic", panicFunction())
.render(); .render();
else else
solUnimplemented("setToZero for type " + _type.identifier() + " not yet implemented!"); solUnimplemented("setToZero for type " + _type.identifier() + " not yet implemented!");

View File

@ -16,5 +16,7 @@ contract C {
} }
} }
// ====
// compileViaYul: also
// ---- // ----
// f() -> true # This code interprets x as an array length and thus will go out of gas. neither of the two should throw due to out-of-bounds access # // f() -> true # This code interprets x as an array length and thus will go out of gas. neither of the two should throw due to out-of-bounds access #

View File

@ -31,6 +31,8 @@ contract C {
} }
} }
// ====
// compileViaYul: also
// ---- // ----
// l() -> 0 // l() -> 0
// f(uint256): 42 -> // f(uint256): 42 ->

View File

@ -18,6 +18,8 @@ contract C {
} }
} }
// ====
// compileViaYul: also
// ---- // ----
// f() -> true // f() -> true
// a() -> 7 // a() -> 7

View File

@ -21,5 +21,7 @@ contract C {
return (s.f(), h(s)); return (s.f(), h(s));
} }
} }
// ====
// compileViaYul: also
// ---- // ----
// g() -> 7, 7 // g() -> 7, 7

View File

@ -20,5 +20,7 @@ contract C {
assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) } assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }
} }
} }
// ====
// compileViaYul: also
// ---- // ----
// f() -> 0, 0, 0, 0 // f() -> 0, 0, 0, 0

View File

@ -16,5 +16,7 @@ contract test {
} }
} }
// ====
// compileViaYul: also
// ---- // ----
// deleteMember() -> 0 // deleteMember() -> 0

View File

@ -18,6 +18,8 @@ contract test {
inner.recursive[0].z = inner.recursive[1].z + 1; inner.recursive[0].z = inner.recursive[1].z + 1;
} }
} }
// ====
// compileViaYul: also
// ---- // ----
// check() -> false // check() -> false
// set() -> // set() ->

View File

@ -22,5 +22,7 @@ contract C {
} }
} }
// ====
// compileViaYul: also
// ---- // ----
// f() -> true // f() -> true