Skip to content

Commit

Permalink
[Sol->Yul] Implementing conversion from struct storage to struct stor…
Browse files Browse the repository at this point in the history
…age pointer
  • Loading branch information
mijovic committed Oct 6, 2020
1 parent 8e202ae commit 2e7ec99
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 19 deletions.
46 changes: 27 additions & 19 deletions libsolidity/codegen/YulUtilFunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -851,7 +851,6 @@ std::string YulUtilFunctions::resizeDynamicArrayFunction(ArrayType const& _type)
solAssert(_type.isDynamicallySized(), "");
solUnimplementedAssert(!_type.isByteArray(), "Byte Arrays not yet implemented!");
solUnimplementedAssert(_type.baseType()->storageBytes() <= 32, "...");
solUnimplementedAssert(_type.baseType()->storageSize() == 1, "");

string functionName = "resize_array_" + _type.identifier();
return m_functionCollector.createFunction(functionName, [&]() {
Expand Down Expand Up @@ -2335,27 +2334,36 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to)
auto const& toStructType = dynamic_cast<StructType const &>(_to);
solAssert(fromStructType.structDefinition() == toStructType.structDefinition(), "");

solUnimplementedAssert(!fromStructType.isDynamicallyEncoded(), "");
solUnimplementedAssert(toStructType.location() == DataLocation::Memory, "");
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();
}
if (
fromStructType.location() == DataLocation::Storage &&
toStructType.location() == DataLocation::Storage &&
toStructType.isPointer()
)
body = "converted := value";
else
{
solAssert(fromStructType.location() == DataLocation::Storage, "");
solUnimplementedAssert(!fromStructType.isDynamicallyEncoded(), "");
solUnimplementedAssert(toStructType.location() == DataLocation::Memory, "");
solUnimplementedAssert(fromStructType.location() != DataLocation::Memory, "");

body = Whiskers(R"(
converted := <readFromStorage>(value)
)")
("readFromStorage", readFromStorage(toStructType, 0, true))
.render();
if (fromStructType.location() == DataLocation::CallData)
{
body = Whiskers(R"(
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 #
2 changes: 2 additions & 0 deletions test/libsolidity/semanticTests/array/push_no_args_struct.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ contract C {
}

}
// ====
// compileViaYul: also
// ----
// l() -> 0
// f(uint256): 42 ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ contract C {
}
}

// ====
// compileViaYul: also
// ----
// f() -> true
// a() -> 7
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,7 @@ contract C {
return (s.f(), h(s));
}
}
// ====
// compileViaYul: also
// ----
// g() -> 7, 7
2 changes: 2 additions & 0 deletions test/libsolidity/semanticTests/structs/recursive_struct_2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,7 @@ contract C {
assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }
}
}
// ====
// compileViaYul: also
// ----
// f() -> 0, 0, 0, 0
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,7 @@ contract test {
}
}

// ====
// compileViaYul: also
// ----
// deleteMember() -> 0
2 changes: 2 additions & 0 deletions test/libsolidity/semanticTests/structs/struct_reference.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ contract test {
inner.recursive[0].z = inner.recursive[1].z + 1;
}
}
// ====
// compileViaYul: also
// ----
// check() -> false
// set() ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,7 @@ contract C {
}
}

// ====
// compileViaYul: also
// ----
// f() -> true

0 comments on commit 2e7ec99

Please sign in to comment.