aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2015-06-26 00:52:19 +0800
committerchriseth <c@ethdev.com>2015-06-26 00:52:19 +0800
commite4a1a5446b2a835b2fc528dcf4dfbb2c27acf12e (patch)
tree6076ec5424ba49a3d49d00434d65f888dd3d8c99
parent639a3137980cd5cca4c893f4ded809be86765f4c (diff)
parent5664f62613d2bf63ba6b5d8928972d7cc6e5b255 (diff)
downloaddexon-solidity-e4a1a5446b2a835b2fc528dcf4dfbb2c27acf12e.tar.gz
dexon-solidity-e4a1a5446b2a835b2fc528dcf4dfbb2c27acf12e.tar.zst
dexon-solidity-e4a1a5446b2a835b2fc528dcf4dfbb2c27acf12e.zip
Merge pull request #2276 from chriseth/sol_memoryArrays7
Copy routines for non-byte arrays.
-rw-r--r--libsolidity/SolidityEndToEndTest.cpp121
-rw-r--r--libsolidity/solidityExecutionFramework.h8
2 files changed, 129 insertions, 0 deletions
diff --git a/libsolidity/SolidityEndToEndTest.cpp b/libsolidity/SolidityEndToEndTest.cpp
index d397dc59..75793abf 100644
--- a/libsolidity/SolidityEndToEndTest.cpp
+++ b/libsolidity/SolidityEndToEndTest.cpp
@@ -4517,6 +4517,105 @@ BOOST_AUTO_TEST_CASE(bytes_in_constructors_packer)
);
}
+BOOST_AUTO_TEST_CASE(arrays_from_and_to_storage)
+{
+ char const* sourceCode = R"(
+ contract Test {
+ uint24[] public data;
+ function set(uint24[] _data) returns (uint) {
+ data = _data;
+ return data.length;
+ }
+ function get() returns (uint24[]) {
+ 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()))
+ );
+ BOOST_CHECK(callContractFunction("data(uint256)", u256(7)) == encodeArgs(u256(8)));
+ BOOST_CHECK(callContractFunction("data(uint256)", u256(15)) == encodeArgs(u256(16)));
+ BOOST_CHECK(callContractFunction("data(uint256)", u256(18)) == encodeArgs());
+ BOOST_CHECK(callContractFunction("get()") == encodeArgs(u256(0x20), u256(data.size()), data));
+}
+
+BOOST_AUTO_TEST_CASE(arrays_complex_from_and_to_storage)
+{
+ char const* sourceCode = R"(
+ contract Test {
+ uint24[3][] public data;
+ function set(uint24[3][] _data) returns (uint) {
+ data = _data;
+ return data.length;
+ }
+ function get() returns (uint24[3][]) {
+ 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[3][])", u256(0x20), u256(data.size() / 3), data) ==
+ encodeArgs(u256(data.size() / 3))
+ );
+ BOOST_CHECK(callContractFunction("data(uint256,uint256)", u256(2), u256(2)) == encodeArgs(u256(9)));
+ BOOST_CHECK(callContractFunction("data(uint256,uint256)", u256(5), u256(1)) == encodeArgs(u256(17)));
+ BOOST_CHECK(callContractFunction("data(uint256,uint256)", u256(6), u256(0)) == encodeArgs());
+ BOOST_CHECK(callContractFunction("get()") == encodeArgs(u256(0x20), u256(data.size() / 3), data));
+}
+
+BOOST_AUTO_TEST_CASE(arrays_complex_memory_index_access)
+{
+ char const* sourceCode = R"(
+ contract Test {
+ function set(uint24[3][] _data, uint a, uint b) returns (uint l, uint e) {
+ l = _data.length;
+ e = _data[a][b];
+ }
+ }
+ )";
+ 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[3][],uint256,uint256)",
+ u256(0x60),
+ u256(3),
+ u256(2),
+ u256(data.size() / 3),
+ data
+ ) == encodeArgs(u256(data.size() / 3), u256(data[3 * 3 + 2])));
+}
+
+BOOST_AUTO_TEST_CASE(bytes_memory_index_access)
+{
+ char const* sourceCode = R"(
+ contract Test {
+ function set(bytes _data, uint i) returns (uint l, byte c) {
+ l = _data.length;
+ c = _data[i];
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "Test");
+
+ string data("abcdefgh");
+ BOOST_REQUIRE(callContractFunction(
+ "set(bytes,uint256)",
+ u256(0x40),
+ u256(3),
+ u256(data.size()),
+ data
+ ) == encodeArgs(u256(data.size()), string("d")));
+}
+
BOOST_AUTO_TEST_CASE(storage_array_ref)
{
char const* sourceCode = R"(
@@ -4570,6 +4669,28 @@ BOOST_AUTO_TEST_CASE(storage_array_ref)
BOOST_CHECK(callContractFunction("find(uint256)", u256(400)) == encodeArgs(u256(-1)));
}
+BOOST_AUTO_TEST_CASE(memory_types_initialisation)
+{
+ char const* sourceCode = R"(
+ contract Test {
+ mapping(uint=>uint) data;
+ function stat() returns (uint[5])
+ {
+ data[2] = 3; // make sure to use some memory
+ }
+ function dyn() returns (uint[]) { stat(); }
+ function nested() returns (uint[3][]) { stat(); }
+ function nestedStat() returns (uint[3][7]) { stat(); }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "Test");
+
+ BOOST_CHECK(callContractFunction("stat()") == encodeArgs(vector<u256>(5)));
+ BOOST_CHECK(callContractFunction("dyn()") == encodeArgs(u256(0x20), u256(0)));
+ BOOST_CHECK(callContractFunction("nested()") == encodeArgs(u256(0x20), u256(0)));
+ BOOST_CHECK(callContractFunction("nestedStat()") == encodeArgs(vector<u256>(3 * 7)));
+}
+
BOOST_AUTO_TEST_SUITE_END()
}
diff --git a/libsolidity/solidityExecutionFramework.h b/libsolidity/solidityExecutionFramework.h
index 0079d82b..200940a4 100644
--- a/libsolidity/solidityExecutionFramework.h
+++ b/libsolidity/solidityExecutionFramework.h
@@ -127,6 +127,14 @@ public:
return _padLeft ? padding + _value : _value + padding;
}
static bytes encode(std::string const& _value) { return encode(asBytes(_value), false); }
+ template <class _T>
+ static bytes encode(std::vector<_T> const& _value)
+ {
+ bytes ret;
+ for (auto const& v: _value)
+ ret += encode(v);
+ return ret;
+ }
template <class FirstArg, class... Args>
static bytes encodeArgs(FirstArg const& _firstArg, Args const&... _followingArgs)