diff options
author | chriseth <c@ethdev.com> | 2016-03-02 05:56:39 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2016-03-30 08:37:00 +0800 |
commit | f0494307232e52dcc268f5f32d26cc89d7e98e3a (patch) | |
tree | 5a03eae3515eb50d67388e7d7d1193d016baaddf /test/libsolidity | |
parent | 949b00ed591303c531ed8fa73087b710b7a554de (diff) | |
download | dexon-solidity-f0494307232e52dcc268f5f32d26cc89d7e98e3a.tar.gz dexon-solidity-f0494307232e52dcc268f5f32d26cc89d7e98e3a.tar.zst dexon-solidity-f0494307232e52dcc268f5f32d26cc89d7e98e3a.zip |
Code generation (missing external access and source locations).
Diffstat (limited to 'test/libsolidity')
-rw-r--r-- | test/libsolidity/InlineAssembly.cpp | 41 | ||||
-rw-r--r-- | test/libsolidity/SolidityEndToEndTest.cpp | 89 |
2 files changed, 118 insertions, 12 deletions
diff --git a/test/libsolidity/InlineAssembly.cpp b/test/libsolidity/InlineAssembly.cpp index c435f5d6..153b3fa8 100644 --- a/test/libsolidity/InlineAssembly.cpp +++ b/test/libsolidity/InlineAssembly.cpp @@ -23,8 +23,9 @@ #include <string> #include <memory> #include <libdevcore/Log.h> +#include <libevmasm/Assembly.h> #include <libsolidity/parsing/Scanner.h> -#include <libsolidity/inlineasm/AsmParser.h> +#include <libsolidity/inlineasm/AsmStack.h> #include <libsolidity/interface/Exceptions.h> #include <libsolidity/ast/AST.h> #include "../TestHelper.h" @@ -40,32 +41,38 @@ namespace test namespace { -shared_ptr<InlineAssemblyBlock> parse(std::string const& _source, ErrorList& _errors) -{ - return InlineAssemblyParser(_errors).parse(std::make_shared<Scanner>(CharStream(_source))); -} -bool successParse(std::string const& _source) +bool successParse(std::string const& _source, bool _assemble = false) { - ErrorList errors; + assembly::InlineAssemblyStack stack; try { - auto assembly = parse(_source, errors); - if (!assembly) + if (!stack.parse(std::make_shared<Scanner>(CharStream(_source)))) return false; + if (_assemble) + { + stack.assemble(); + if (!stack.errors().empty()) + return false; + } } catch (FatalError const&) { - if (Error::containsErrorOfType(errors, Error::Type::ParserError)) + if (Error::containsErrorOfType(stack.errors(), Error::Type::ParserError)) return false; } - if (Error::containsErrorOfType(errors, Error::Type::ParserError)) + if (Error::containsErrorOfType(stack.errors(), Error::Type::ParserError)) return false; - BOOST_CHECK(Error::containsOnlyWarnings(errors)); + BOOST_CHECK(Error::containsOnlyWarnings(stack.errors())); return true; } +bool successAssemble(string const& _source) +{ + return successParse(_source, true); +} + } @@ -131,6 +138,16 @@ BOOST_AUTO_TEST_CASE(blocks) BOOST_CHECK(successParse("{ let x := 7 { let y := 3 } { let z := 2 } }")); } +BOOST_AUTO_TEST_CASE(string_literals) +{ + BOOST_CHECK(successAssemble("{ let x := \"12345678901234567890123456789012\" }")); +} + +BOOST_AUTO_TEST_CASE(oversize_string_literals) +{ + BOOST_CHECK(!successAssemble("{ let x := \"123456789012345678901234567890123\" }")); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 56f07415..663493c9 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -6486,6 +6486,95 @@ BOOST_AUTO_TEST_CASE(fixed_bytes_length_access) BOOST_CHECK(callContractFunction("f(bytes32)", "789") == encodeArgs(u256(32), u256(16), u256(8))); } +BOOST_AUTO_TEST_CASE(inline_assembly_write_to_stack) +{ + char const* sourceCode = R"( + contract C { + function f() returns (uint r, bytes32 r2) { + assembly { r := 7 r2 := "abcdef" } + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(7), string("abcdef"))); +} + +BOOST_AUTO_TEST_CASE(inline_assembly_read_and_write_stack) +{ + char const* sourceCode = R"( + contract C { + function f() returns (uint r) { + for (uint x = 0; x < 10; ++x) + assembly { r := add(r, x) } + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(45))); +} + +BOOST_AUTO_TEST_CASE(inline_assembly_memory_access) +{ + char const* sourceCode = R"( + contract C { + function test() returns (bytes) { + bytes memory x = new bytes(5); + for (uint i = 0; i < x.length; ++i) + x[i] = byte(i + 1); + assembly { mstore(add(x, 32), "12345678901234567890123456789012") } + return x; + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(0x20), u256(5), string("12345"))); +} + +BOOST_AUTO_TEST_CASE(inline_assembly_storage_access) +{ + char const* sourceCode = R"( + contract C { + uint16 x; + uint16 public y; + uint public z; + function f() { + // we know that z is aligned because it is too large, so we just discard its + // intra-slot offset value + assembly { 7 z pop sstore } + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("f()") == encodeArgs()); + BOOST_CHECK(callContractFunction("z()") == encodeArgs(u256(7))); +} + +BOOST_AUTO_TEST_CASE(inline_assembly_jumps) +{ + char const* sourceCode = R"( + contract C { + function f() { + assembly { + let n := calldataload(4) + let a := 1 + let b := a + loop: + jumpi(loopend, eq(n, 0)) + a add swap1 + n := sub(n, 1) + jump(loop) + loopend: + mstore(0, a) + return(0, 0x20) + } + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("f()", u256(5)) == encodeArgs(u256(13))); + BOOST_CHECK(callContractFunction("f()", u256(7)) == encodeArgs(u256(34))); +} + BOOST_AUTO_TEST_SUITE_END() } |