Moving some more array tests to semanticTests.

This commit is contained in:
Djordje Mijovic 2020-11-13 12:14:30 +01:00
parent 29d480d0ed
commit 1428a939a6
14 changed files with 310 additions and 401 deletions

View File

@ -2854,145 +2854,6 @@ BOOST_AUTO_TEST_CASE(array_copy_storage_abi)
);
}
BOOST_AUTO_TEST_CASE(external_array_args)
{
char const* sourceCode = R"(
contract c {
function test(uint[8] calldata a, uint[] calldata b, uint[5] calldata c, uint a_index, uint b_index, uint c_index)
external returns (uint av, uint bv, uint cv) {
av = a[a_index];
bv = b[b_index];
cv = c[c_index];
}
}
)";
compileAndRun(sourceCode);
bytes params = encodeArgs(
1, 2, 3, 4, 5, 6, 7, 8, // a
32 * (8 + 1 + 5 + 1 + 1 + 1), // offset to b
21, 22, 23, 24, 25, // c
0, 1, 2, // (a,b,c)_index
3, // b.length
11, 12, 13 // b
);
ABI_CHECK(callContractFunction("test(uint256[8],uint256[],uint256[5],uint256,uint256,uint256)", params), encodeArgs(1, 12, 23));
}
BOOST_AUTO_TEST_CASE(bytes_index_access)
{
char const* sourceCode = R"(
contract c {
bytes data;
function direct(bytes calldata arg, uint index) external returns (uint) {
return uint(uint8(arg[index]));
}
function storageCopyRead(bytes calldata arg, uint index) external returns (uint) {
data = arg;
return uint(uint8(data[index]));
}
function storageWrite() external returns (uint) {
data = new bytes(35);
data[31] = 0x77;
data[32] = 0x14;
data[31] = 0x01;
data[31] |= 0x08;
data[30] = 0x01;
data[32] = 0x03;
return uint(uint8(data[30])) * 0x100 | uint(uint8(data[31])) * 0x10 | uint(uint8(data[32]));
}
}
)";
string array{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33};
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("direct(bytes,uint256)", 64, 33, u256(array.length()), array), encodeArgs(33));
ABI_CHECK(callContractFunction("storageCopyRead(bytes,uint256)", 64, 33, u256(array.length()), array), encodeArgs(33));
ABI_CHECK(callContractFunction("storageWrite()"), encodeArgs(0x193));
);
}
BOOST_AUTO_TEST_CASE(array_copy_calldata_storage)
{
char const* sourceCode = R"(
contract c {
uint[9] m_data;
uint[] m_data_dyn;
uint8[][] m_byte_data;
function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {
m_data = a;
m_data_dyn = a;
m_byte_data = b;
return b[3][1]; // note that access and declaration are reversed to each other
}
function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {
a = m_data.length;
b = m_data[7];
c = m_data_dyn.length;
d = m_data_dyn[7];
e = m_byte_data.length;
f = m_byte_data[3].length;
g = m_byte_data[3][1];
}
}
)";
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("store(uint256[9],uint8[3][])", encodeArgs(21, 22, 23, 24, 25, 26, 27, 28, 29, u256(32 * (9 + 1)), 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 )), encodeArgs(32));
ABI_CHECK(callContractFunction("retrieve()"), encodeArgs(9, 28, 9, 28, 4, 3, 32));
}
BOOST_AUTO_TEST_CASE(array_copy_including_array)
{
char const* sourceCode = R"(
contract c {
uint[3][90][] large;
uint[3][3][] small;
function test() public returns (uint r) {
for (uint i = 0; i < 7; i++) {
large.push();
small.push();
}
large[3][2][0] = 2;
large[1] = large[3];
small[3][2][0] = 2;
small[1] = small[2];
r = ((
small[3][2][0] * 0x100 |
small[1][2][0]) * 0x100 |
large[3][2][0]) * 0x100 |
large[1][2][0];
delete small;
delete large;
}
function clear() public returns (uint, uint) {
for (uint i = 0; i < 7; i++) {
large.push();
small.push();
}
small[3][2][0] = 0;
large[3][2][0] = 0;
while (small.length > 0)
small.pop();
while (large.length > 0)
large.pop();
return (small.length, large.length);
}
}
)";
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("test()"), encodeArgs(0x02000202));
BOOST_CHECK(storageEmpty(m_contractAddress));
ABI_CHECK(callContractFunction("clear()"), encodeArgs(0, 0));
BOOST_CHECK(storageEmpty(m_contractAddress));
}
//BOOST_AUTO_TEST_CASE(assignment_to_const_array_vars)
//{
// char const* sourceCode = R"(
@ -3305,159 +3166,6 @@ BOOST_AUTO_TEST_CASE(return_bytes_internal)
}
}
BOOST_AUTO_TEST_CASE(bytes_index_access_memory)
{
char const* sourceCode = R"(
contract Main {
function f(bytes memory _s1, uint i1, uint i2, uint i3) public returns (byte c1, byte c2, byte c3) {
c1 = _s1[i1];
c2 = intern(_s1, i2);
c3 = internIndirect(_s1)[i3];
}
function intern(bytes memory _s1, uint i) public returns (byte c) {
return _s1[i];
}
function internIndirect(bytes memory _s1) public returns (bytes memory) {
return _s1;
}
}
)";
compileAndRun(sourceCode, 0, "Main");
string s1("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz");
bytes dyn1 = encodeArgs(u256(s1.length()), s1);
bytes args1 = encodeArgs(u256(0x80), u256(3), u256(4), u256(5)) + dyn1;
BOOST_REQUIRE(
callContractFunction("f(bytes,uint256,uint256,uint256)", asString(args1)) ==
encodeArgs(string{s1[3]}, string{s1[4]}, string{s1[5]})
);
}
BOOST_AUTO_TEST_CASE(bytes_in_constructors_unpacker)
{
char const* sourceCode = R"(
contract Test {
uint public m_x;
bytes public m_s;
constructor(uint x, bytes memory s) {
m_x = x;
m_s = s;
}
}
)";
string s1("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz");
bytes dyn1 = encodeArgs(u256(s1.length()), s1);
u256 x = 7;
bytes args1 = encodeArgs(x, u256(0x40)) + dyn1;
compileAndRun(sourceCode, 0, "Test", args1);
BOOST_REQUIRE(callContractFunction("m_x()") == encodeArgs(x));
BOOST_REQUIRE(callContractFunction("m_s()") == encodeArgs(u256(0x20)) + dyn1);
}
BOOST_AUTO_TEST_CASE(bytes_in_constructors_packer)
{
char const* sourceCode = R"(
contract Base {
uint public m_x;
bytes m_s;
constructor(uint x, bytes memory s) {
m_x = x;
m_s = s;
}
function part(uint i) public returns (byte) {
return m_s[i];
}
}
contract Main is Base {
constructor(bytes memory s, uint x) Base(x, f(s)) {}
function f(bytes memory s) public returns (bytes memory) {
return s;
}
}
contract Creator {
function f(uint x, bytes memory s) public returns (uint r, byte ch) {
Main c = new Main(s, x);
r = c.m_x();
ch = c.part(x);
}
}
)";
compileAndRun(sourceCode, 0, "Creator");
string s1("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz");
bytes dyn1 = encodeArgs(u256(s1.length()), s1);
u256 x = 7;
bytes args1 = encodeArgs(x, u256(0x40)) + dyn1;
BOOST_REQUIRE(
callContractFunction("f(uint256,bytes)", asString(args1)) ==
encodeArgs(x, string{s1[unsigned(x)]})
);
}
BOOST_AUTO_TEST_CASE(arrays_in_constructors)
{
char const* sourceCode = R"(
contract Base {
uint public m_x;
address[] m_s;
constructor(uint x, address[] memory s) {
m_x = x;
m_s = s;
}
function part(uint i) public returns (address) {
return m_s[i];
}
}
contract Main is Base {
constructor(address[] memory s, uint x) Base(x, f(s)) {}
function f(address[] memory s) public returns (address[] memory) {
return s;
}
}
contract Creator {
function f(uint x, address[] memory s) public returns (uint r, address ch) {
Main c = new Main(s, x);
r = c.m_x();
ch = c.part(x);
}
}
)";
compileAndRun(sourceCode, 0, "Creator");
vector<u256> s1{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
bytes dyn1 = encodeArgs(u256(s1.size()), s1);
u256 x = 7;
bytes args1 = encodeArgs(x, u256(0x40)) + dyn1;
BOOST_REQUIRE(
callContractFunction("f(uint256,address[])", asString(args1)) ==
encodeArgs(x, s1[unsigned(x)])
);
}
BOOST_AUTO_TEST_CASE(arrays_from_and_to_storage)
{
char const* sourceCode = R"(
contract Test {
uint24[] public data;
function set(uint24[] memory _data) public returns (uint) {
data = _data;
return data.length;
}
function get() public returns (uint24[] memory) {
return data;
}
}
)";
compileAndRun(sourceCode, 0, "Test");
vector<u256> data{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18};
BOOST_REQUIRE(
callContractFunction("set(uint24[])", u256(0x20), u256(data.size()), data) ==
encodeArgs(u256(data.size()))
);
ABI_CHECK(callContractFunction("data(uint256)", u256(7)), encodeArgs(u256(8)));
ABI_CHECK(callContractFunction("data(uint256)", u256(15)), encodeArgs(u256(16)));
ABI_CHECK(callContractFunction("data(uint256)", u256(18)), encodeArgs());
ABI_CHECK(callContractFunction("get()"), encodeArgs(u256(0x20), u256(data.size()), data));
}
BOOST_AUTO_TEST_CASE(memory_types_initialisation)
{
char const* sourceCode = R"(
@ -3480,35 +3188,6 @@ BOOST_AUTO_TEST_CASE(memory_types_initialisation)
ABI_CHECK(callContractFunction("nestedStat()"), encodeArgs(vector<u256>(3 * 7)));
}
BOOST_AUTO_TEST_CASE(memory_arrays_delete)
{
char const* sourceCode = R"(
contract Test {
function del() public returns (uint24[3][4] memory) {
uint24[3][4] memory x;
for (uint24 i = 0; i < x.length; i ++)
for (uint24 j = 0; j < x[i].length; j ++)
x[i][j] = i * 0x10 + j;
delete x[1];
delete x[3][2];
return x;
}
}
)";
compileAndRun(sourceCode, 0, "Test");
vector<u256> data(3 * 4);
for (unsigned i = 0; i < 4; i++)
for (unsigned j = 0; j < 3; j++)
{
u256 v = 0;
if (!(i == 1 || (i == 3 && j == 2)))
v = i * 0x10 + j;
data[i * 3 + j] = v;
}
ABI_CHECK(callContractFunction("del()"), encodeArgs(data));
}
BOOST_AUTO_TEST_CASE(calldata_struct_short)
{
char const* sourceCode = R"(
@ -3557,86 +3236,6 @@ BOOST_AUTO_TEST_CASE(calldata_struct_function_type)
ABI_CHECK(callContractFunctionNoEncoding("f((function))", fn_C_h), encodeArgs(23));
}
BOOST_AUTO_TEST_CASE(calldata_bytes_array_bounds)
{
char const* sourceCode = R"(
pragma experimental ABIEncoderV2;
contract C {
function f(bytes[] calldata a, uint256 i) external returns (uint) {
return uint8(a[0][i]);
}
}
)";
compileAndRun(sourceCode, 0, "C");
ABI_CHECK(
callContractFunction("f(bytes[],uint256)", 0x40, 0, 1, 0x20, 2, bytes{'a', 'b'} + bytes(30, 0)),
encodeArgs('a')
);
ABI_CHECK(
callContractFunction("f(bytes[],uint256)", 0x40, 1, 1, 0x20, 2, bytes{'a', 'b'} + bytes(30, 0)),
encodeArgs('b')
);
ABI_CHECK(
callContractFunction("f(bytes[],uint256)", 0x40, 2, 1, 0x20, 2, bytes{'a', 'b'} + bytes(30, 0)),
encodeArgs()
);
}
BOOST_AUTO_TEST_CASE(calldata_array_two_dimensional)
{
vector<vector<u256>> data {
{ 0x0A01, 0x0A02, 0x0A03 },
{ 0x0B01, 0x0B02, 0x0B03, 0x0B04 }
};
for (bool outerDynamicallySized: { true, false })
{
string arrayType = outerDynamicallySized ? "uint256[][]" : "uint256[][2]";
string sourceCode = R"(
pragma experimental ABIEncoderV2;
contract C {
function test()" + arrayType + R"( calldata a) external returns (uint256) {
return a.length;
}
function test()" + arrayType + R"( calldata a, uint256 i) external returns (uint256) {
return a[i].length;
}
function test()" + arrayType + R"( calldata a, uint256 i, uint256 j) external returns (uint256) {
return a[i][j];
}
function reenc()" + arrayType + R"( calldata a, uint256 i, uint256 j) external returns (uint256) {
return this.test(a, i, j);
}
}
)";
compileAndRun(sourceCode, 0, "C");
bytes encoding = encodeArray(
outerDynamicallySized,
true,
data | boost::adaptors::transformed([&](vector<u256> const& _values) {
return encodeArray(true, false, _values);
})
);
ABI_CHECK(callContractFunction("test(" + arrayType + ")", 0x20, encoding), encodeArgs(data.size()));
for (size_t i = 0; i < data.size(); i++)
{
ABI_CHECK(callContractFunction("test(" + arrayType + ",uint256)", 0x40, i, encoding), encodeArgs(data[i].size()));
for (size_t j = 0; j < data[i].size(); j++)
{
ABI_CHECK(callContractFunction("test(" + arrayType + ",uint256,uint256)", 0x60, i, j, encoding), encodeArgs(data[i][j]));
ABI_CHECK(callContractFunction("reenc(" + arrayType + ",uint256,uint256)", 0x60, i, j, encoding), encodeArgs(data[i][j]));
}
// out of bounds access
ABI_CHECK(callContractFunction("test(" + arrayType + ",uint256,uint256)", 0x60, i, data[i].size(), encoding), encodeArgs());
}
// out of bounds access
ABI_CHECK(callContractFunction("test(" + arrayType + ",uint256)", 0x40, data.size(), encoding), encodeArgs());
}
}
BOOST_AUTO_TEST_CASE(calldata_array_dynamic_three_dimensional)
{
vector<vector<vector<u256>>> data {

View File

@ -0,0 +1,38 @@
pragma experimental ABIEncoderV2;
contract C {
function test(uint256[][2] calldata a) external returns (uint256) {
return a.length;
}
function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {
return a[i].length;
}
function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {
return a[i][j];
}
function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {
return this.test(a, i, j);
}
}
// ====
// compileViaYul: also
// ----
// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2
// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3
// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4
// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01
// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01
// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02
// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02
// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03
// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03
// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01
// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01
// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02
// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02
// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03
// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03
// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04
// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04
// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE
// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE
// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE

View File

@ -0,0 +1,38 @@
pragma experimental ABIEncoderV2;
contract C {
function test(uint256[][] calldata a) external returns (uint256) {
return a.length;
}
function test(uint256[][] calldata a, uint256 i) external returns (uint256) {
return a[i].length;
}
function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {
return a[i][j];
}
function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {
return this.test(a, i, j);
}
}
// ====
// compileViaYul: also
// ----
// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2
// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3
// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4
// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01
// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01
// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02
// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02
// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03
// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03
// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01
// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01
// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02
// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02
// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03
// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03
// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04
// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04
// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE
// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE
// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE

View File

@ -0,0 +1,12 @@
pragma experimental ABIEncoderV2;
contract C {
function f(bytes[] calldata a, uint256 i) external returns (uint) {
return uint8(a[0][i]);
}
}
// ====
// compileViaYul: also
// ----
// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61
// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62
// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE

View File

@ -0,0 +1,25 @@
contract c {
uint[9] m_data;
uint[] m_data_dyn;
uint8[][] m_byte_data;
function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {
m_data = a;
m_data_dyn = a;
m_byte_data = b;
return b[3][1]; // note that access and declaration are reversed to each other
}
function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {
a = m_data.length;
b = m_data[7];
c = m_data_dyn.length;
d = m_data_dyn[7];
e = m_byte_data.length;
f = m_byte_data[3].length;
g = m_byte_data[3][1];
}
}
// ====
// compileViaYul: also
// ----
// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32
// retrieve() -> 9, 28, 9, 28, 4, 3, 32

View File

@ -0,0 +1,40 @@
contract c {
uint[3][90][] large;
uint[3][3][] small;
function test() public returns (uint r) {
for (uint i = 0; i < 7; i++) {
large.push();
small.push();
}
large[3][2][0] = 2;
large[1] = large[3];
small[3][2][0] = 2;
small[1] = small[2];
r = ((
small[3][2][0] * 0x100 |
small[1][2][0]) * 0x100 |
large[3][2][0]) * 0x100 |
large[1][2][0];
delete small;
delete large;
}
function clear() public returns (uint, uint) {
for (uint i = 0; i < 7; i++) {
large.push();
small.push();
}
small[3][2][0] = 0;
large[3][2][0] = 0;
while (small.length > 0)
small.pop();
while (large.length > 0)
large.pop();
return (small.length, large.length);
}
}
// ----
// test() -> 0x02000202
// storage: empty
// clear() -> 0, 0
// storage: empty

View File

@ -0,0 +1,18 @@
contract Test {
uint24[] public data;
function set(uint24[] memory _data) public returns (uint) {
data = _data;
return data.length;
}
function get() public returns (uint24[] memory) {
return data;
}
}
// ====
// compileViaYul: also
// ----
// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18
// data(uint256): 7 -> 8
// data(uint256): 15 -> 16
// data(uint256): 18 -> FAILURE
// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18

View File

@ -0,0 +1,15 @@
contract Test {
function del() public returns (uint24[3][4] memory) {
uint24[3][4] memory x;
for (uint24 i = 0; i < x.length; i ++)
for (uint24 j = 0; j < x[i].length; j ++)
x[i][j] = i * 0x10 + j;
delete x[1];
delete x[3][2];
return x;
}
}
// ====
// compileViaYul: also
// ----
// del() -> 0, 1, 2, 0, 0, 0, 0x20, 0x21, 0x22, 0x30, 0x31, 0

View File

@ -0,0 +1,12 @@
contract c {
function test(uint[8] calldata a, uint[] calldata b, uint[5] calldata c, uint a_index, uint b_index, uint c_index)
external returns (uint av, uint bv, uint cv) {
av = a[a_index];
bv = b[b_index];
cv = c[c_index];
}
}
// ====
// compileViaYul: also
// ----
// test(uint256[8],uint256[],uint256[5],uint256,uint256,uint256): 1, 2, 3, 4, 5, 6, 7, 8, 0x220, 21, 22, 23, 24, 25, 0, 1, 2, 3, 11, 12, 13 -> 1, 12, 23

View File

@ -0,0 +1,27 @@
contract c {
bytes data;
function direct(bytes calldata arg, uint index) external returns (uint) {
return uint(uint8(arg[index]));
}
function storageCopyRead(bytes calldata arg, uint index) external returns (uint) {
data = arg;
return uint(uint8(data[index]));
}
function storageWrite() external returns (uint) {
data = new bytes(35);
data[31] = 0x77;
data[32] = 0x14;
data[31] = 0x01;
data[31] |= 0x08;
data[30] = 0x01;
data[32] = 0x03;
return uint(uint8(data[30])) * 0x100 | uint(uint8(data[31])) * 0x10 | uint(uint8(data[32]));
}
}
// ====
// compileViaYul: also
// ----
// direct(bytes,uint256): 0x40, 33, 34, 0x000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F, left(0x2021) -> 0x21
// storageCopyRead(bytes,uint256): 0x40, 33, 34, 0x000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F, left(0x2021) -> 0x21
// storageWrite() -> 0x193

View File

@ -0,0 +1,17 @@
contract Main {
function f(bytes memory _s1, uint i1, uint i2, uint i3) public returns (byte c1, byte c2, byte c3) {
c1 = _s1[i1];
c2 = intern(_s1, i2);
c3 = internIndirect(_s1)[i3];
}
function intern(bytes memory _s1, uint i) public returns (byte c) {
return _s1[i];
}
function internIndirect(bytes memory _s1) public returns (bytes memory) {
return _s1;
}
}
// ====
// compileViaYul: also
// ----
// f(bytes,uint256,uint256,uint256): 0x80, 3, 4, 5, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> "d", "e", "f"

View File

@ -0,0 +1,28 @@
contract Base {
uint public m_x;
address[] m_s;
constructor(uint x, address[] memory s) {
m_x = x;
m_s = s;
}
function part(uint i) public returns (address) {
return m_s[i];
}
}
contract Main is Base {
constructor(address[] memory s, uint x) Base(x, f(s)) {}
function f(address[] memory s) public returns (address[] memory) {
return s;
}
}
contract Creator {
function f(uint x, address[] memory s) public returns (uint r, address ch) {
Main c = new Main(s, x);
r = c.m_x();
ch = c.part(x);
}
}
// ====
// compileViaYul: also
// ----
// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8

View File

@ -0,0 +1,28 @@
contract Base {
uint public m_x;
bytes m_s;
constructor(uint x, bytes memory s) {
m_x = x;
m_s = s;
}
function part(uint i) public returns (byte) {
return m_s[i];
}
}
contract Main is Base {
constructor(bytes memory s, uint x) Base(x, f(s)) {}
function f(bytes memory s) public returns (bytes memory) {
return s;
}
}
contract Creator {
function f(uint x, bytes memory s) public returns (uint r, byte ch) {
Main c = new Main(s, x);
r = c.m_x();
ch = c.part(x);
}
}
// ====
// compileViaYul: also
// ----
// f(uint256,bytes): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> 7, "h"

View File

@ -0,0 +1,12 @@
contract Test {
uint public m_x;
bytes public m_s;
constructor(uint x, bytes memory s) {
m_x = x;
m_s = s;
}
}
// ----
// constructor(): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" ->
// m_x() -> 7
// m_s() -> 0x20, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz"