[Sol->Yul] Implementing push for nested storage arrays and storage arrays of structs.

This commit is contained in:
Djordje Mijovic 2020-09-28 14:41:27 +02:00
parent 756e21a888
commit 818afcbec2
7 changed files with 53 additions and 5 deletions

View File

@ -1047,8 +1047,6 @@ string YulUtilFunctions::storageArrayPushZeroFunction(ArrayType const& _type)
solUnimplementedAssert(!_type.isByteArray(), "Byte Arrays not yet implemented!"); solUnimplementedAssert(!_type.isByteArray(), "Byte Arrays not yet implemented!");
solUnimplementedAssert(_type.baseType()->storageBytes() <= 32, "Base type is not yet implemented."); solUnimplementedAssert(_type.baseType()->storageBytes() <= 32, "Base type is not yet implemented.");
solAssert(_type.baseType()->isValueType(), "");
string functionName = "array_push_zero_" + _type.identifier(); string functionName = "array_push_zero_" + _type.identifier();
return m_functionCollector.createFunction(functionName, [&]() { return m_functionCollector.createFunction(functionName, [&]() {
return Whiskers(R"( return Whiskers(R"(
@ -1057,15 +1055,12 @@ string YulUtilFunctions::storageArrayPushZeroFunction(ArrayType const& _type)
if iszero(lt(oldLen, <maxArrayLength>)) { <panic>() } if iszero(lt(oldLen, <maxArrayLength>)) { <panic>() }
sstore(array, add(oldLen, 1)) sstore(array, add(oldLen, 1))
slot, offset := <indexAccess>(array, oldLen) slot, offset := <indexAccess>(array, oldLen)
<storeValue>(slot, offset, <zeroValueFunction>())
})") })")
("functionName", functionName) ("functionName", functionName)
("panic", panicFunction()) ("panic", panicFunction())
("fetchLength", arrayLengthFunction(_type)) ("fetchLength", arrayLengthFunction(_type))
("indexAccess", storageArrayIndexAccessFunction(_type)) ("indexAccess", storageArrayIndexAccessFunction(_type))
("storeValue", updateStorageValueFunction(*_type.baseType(), *_type.baseType()))
("maxArrayLength", (u256(1) << 64).str()) ("maxArrayLength", (u256(1) << 64).str())
("zeroValueFunction", zeroValueFunction(*_type.baseType()))
.render(); .render();
}); });
} }

View File

@ -0,0 +1,17 @@
contract C {
uint8 b = 23;
uint120[][] s;
uint8 a = 17;
function f() public {
s.push();
assert(s.length == 1);
assert(s[0].length == 0);
s[0].push();
assert(s[0].length == 1);
assert(s[0][0] == 0);
}
}
// ====
// compileViaYul: also
// ----
// f() ->

View File

@ -39,6 +39,8 @@ contract c {
} }
} }
// ====
// compileViaYul: also
// ---- // ----
// getLengths() -> 0, 0 // getLengths() -> 0, 0
// setLengths(uint256,uint256): 48, 49 -> // setLengths(uint256,uint256): 48, 49 ->

View File

@ -24,6 +24,8 @@ contract C {
array2d.push().push() = value; array2d.push().push() = value;
} }
} }
// ====
// compileViaYul: also
// ---- // ----
// l() -> 0 // l() -> 0
// f(uint256,uint256): 42, 64 -> // f(uint256,uint256): 42, 64 ->

View File

@ -18,6 +18,8 @@ contract C {
n[1][1].b = 10; n[1][1].b = 10;
} }
} }
// ====
// compileViaYul: also
// ---- // ----
// m(uint256,uint256): 0, 0 -> 0x00, 0x00 // m(uint256,uint256): 0, 0 -> 0x00, 0x00
// m(uint256,uint256): 1, 0 -> 1, 2 // m(uint256,uint256): 1, 0 -> 1, 2

View File

@ -16,6 +16,8 @@ contract C {
n[1][1].b = 10; n[1][1].b = 10;
} }
} }
// ====
// compileViaYul: also
// ---- // ----
// m(uint256,uint256): 0, 0 -> FAILURE // m(uint256,uint256): 0, 0 -> FAILURE
// m(uint256,uint256): 1, 0 -> 1, 2 // m(uint256,uint256): 1, 0 -> 1, 2

View File

@ -0,0 +1,28 @@
contract C {
struct S {
uint256 x;
uint128 y;
uint32 z;
uint128[3] a1;
uint128[] a2;
}
uint8 b = 23;
S[] s;
uint8 a = 17;
function f() public {
s.push();
assert(s[0].x == 0);
assert(s[0].y == 0);
assert(s[0].z == 0);
assert(s[0].a1[0] == 0);
assert(s[0].a1[1] == 0);
assert(s[0].a1[2] == 0);
assert(s[0].a2.length == 0);
assert(b == 23);
assert(a == 17);
}
}
// ====
// compileViaYul: also
// ----
// f() ->