mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
[Sol->Yul] Implementing conversion of struct to struct pointer.
Co-authored-by: Daniel Kirchner <daniel@ekpyron.org>
This commit is contained in:
parent
fa69378f4f
commit
ad8d840ee7
@ -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!");
|
||||||
|
@ -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 #
|
||||||
|
@ -31,6 +31,8 @@ contract C {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// ====
|
||||||
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// l() -> 0
|
// l() -> 0
|
||||||
// f(uint256): 42 ->
|
// f(uint256): 42 ->
|
||||||
|
@ -18,6 +18,8 @@ contract C {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ====
|
||||||
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// f() -> true
|
// f() -> true
|
||||||
// a() -> 7
|
// a() -> 7
|
||||||
|
@ -21,5 +21,7 @@ contract C {
|
|||||||
return (s.f(), h(s));
|
return (s.f(), h(s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// ====
|
||||||
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// g() -> 7, 7
|
// g() -> 7, 7
|
||||||
|
@ -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
|
||||||
|
@ -16,5 +16,7 @@ contract test {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ====
|
||||||
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// deleteMember() -> 0
|
// deleteMember() -> 0
|
||||||
|
@ -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() ->
|
||||||
|
@ -22,5 +22,7 @@ contract C {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ====
|
||||||
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// f() -> true
|
// f() -> true
|
||||||
|
Loading…
Reference in New Issue
Block a user