diff options
author | chriseth <c@ethdev.com> | 2015-06-26 00:52:19 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2015-06-26 00:52:19 +0800 |
commit | e4a1a5446b2a835b2fc528dcf4dfbb2c27acf12e (patch) | |
tree | 6076ec5424ba49a3d49d00434d65f888dd3d8c99 /libsolidity | |
parent | 639a3137980cd5cca4c893f4ded809be86765f4c (diff) | |
parent | 5664f62613d2bf63ba6b5d8928972d7cc6e5b255 (diff) | |
download | dexon-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.
Diffstat (limited to 'libsolidity')
-rw-r--r-- | libsolidity/SolidityEndToEndTest.cpp | 121 | ||||
-rw-r--r-- | libsolidity/solidityExecutionFramework.h | 8 |
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) |