aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaweł Bylica <pawel.bylica@imapp.pl>2015-05-12 17:53:46 +0800
committerPaweł Bylica <pawel.bylica@imapp.pl>2015-05-12 17:53:46 +0800
commitd5841327a2f0d8a990082bf4c16597e2b1f85926 (patch)
tree42349a63fea8cd2298d0e71b037375342c5d3a8b
parent5c283ffeefa9c77877aa98a739aff88760a60e31 (diff)
parentfba1cc6e980beb61214b9320e5feee00d756cfc2 (diff)
downloaddexon-solidity-d5841327a2f0d8a990082bf4c16597e2b1f85926.tar.gz
dexon-solidity-d5841327a2f0d8a990082bf4c16597e2b1f85926.tar.zst
dexon-solidity-d5841327a2f0d8a990082bf4c16597e2b1f85926.zip
Merge remote-tracking branch 'upstream/develop' into feature/vm_gas_counter_refactor
Conflicts: evmjit/libevmjit-cpp/JitVM.cpp libevm/VMFactory.cpp libevm/VMFactory.h
-rw-r--r--CMakeLists.txt17
-rw-r--r--TestHelper.cpp9
-rw-r--r--TestHelper.h1
-rw-r--r--libsolidity/SolidityABIJSON.cpp43
-rw-r--r--libsolidity/SolidityCompiler.cpp10
-rw-r--r--libsolidity/SolidityEndToEndTest.cpp101
-rw-r--r--libsolidity/SolidityNameAndTypeResolution.cpp22
-rw-r--r--libsolidity/SolidityOptimizer.cpp61
8 files changed, 239 insertions, 25 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a97bb86f..39a235c5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -25,6 +25,11 @@ add_subdirectory(libethereum)
add_subdirectory(libevm)
add_subdirectory(libnatspec)
add_subdirectory(libp2p)
+
+if (JSCONSOLE)
+ add_subdirectory(libjsengine)
+endif()
+
if (SOLIDITY)
add_subdirectory(libsolidity)
endif ()
@@ -41,6 +46,10 @@ include_directories(${Boost_INCLUDE_DIRS})
include_directories(${CRYPTOPP_INCLUDE_DIRS})
include_directories(${JSON_RPC_CPP_INCLUDE_DIRS})
+if (JSCONSOLE)
+ include_directories(${V8_INCLUDE_DIRS})
+endif()
+
# search for test names and create ctest tests
enable_testing()
foreach(file ${SRC_LIST})
@@ -65,14 +74,22 @@ target_link_libraries(testeth ${CURL_LIBRARIES})
target_link_libraries(testeth ethereum)
target_link_libraries(testeth ethcore)
target_link_libraries(testeth secp256k1)
+
+if (JSCONSOLE)
+ target_link_libraries(testeth jsengine)
+endif()
+
if (SOLIDITY)
target_link_libraries(testeth solidity)
endif ()
+
target_link_libraries(testeth testutils)
+
if (GUI AND NOT JUSTTESTS)
target_link_libraries(testeth webthree)
target_link_libraries(testeth natspec)
endif()
+
if (JSONRPC)
target_link_libraries(testeth web3jsonrpc)
target_link_libraries(testeth ${JSON_RPC_CPP_CLIENT_LIBRARIES})
diff --git a/TestHelper.cpp b/TestHelper.cpp
index 144a1a28..dede4703 100644
--- a/TestHelper.cpp
+++ b/TestHelper.cpp
@@ -288,7 +288,7 @@ void ImportTest::checkExpectedState(State const& _stateExpect, State const& _sta
{
addressOptions = _expectedStateOptions.at(a.first);
}
- catch(std::out_of_range)
+ catch(std::out_of_range const&)
{
BOOST_ERROR("expectedStateOptions map does not match expectedState in checkExpectedState!");
break;
@@ -305,7 +305,7 @@ void ImportTest::checkExpectedState(State const& _stateExpect, State const& _sta
if (addressOptions.m_bHasStorage)
{
- map<u256, u256> stateStorage = _statePost.storage(a.first);
+ unordered_map<u256, u256> stateStorage = _statePost.storage(a.first);
for (auto const& s: _stateExpect.storage(a.first))
CHECK(stateStorage[s.first] == s.second,
"Check State: " << a.first << ": incorrect storage [" << s.first << "] = " << toHex(stateStorage[s.first]) << ", expected [" << s.first << "] = " << toHex(s.second));
@@ -707,10 +707,9 @@ Options::Options()
{
auto arg = std::string{argv[i]};
if (arg == "--jit")
- {
- jit = true;
eth::VMFactory::setKind(eth::VMKind::JIT);
- }
+ else if (arg == "--vm=smart")
+ eth::VMFactory::setKind(eth::VMKind::Smart);
else if (arg == "--vmtrace")
vmtrace = true;
else if (arg == "--filltests")
diff --git a/TestHelper.h b/TestHelper.h
index 02f509e4..00b520d0 100644
--- a/TestHelper.h
+++ b/TestHelper.h
@@ -179,7 +179,6 @@ void checkAddresses(mapType& _expectedAddrs, mapType& _resultAddrs)
class Options
{
public:
- bool jit = false; ///< Use JIT
bool vmtrace = false; ///< Create EVM execution tracer // TODO: Link with log verbosity?
bool fillTests = false; ///< Create JSON test files from execution results
bool stats = false; ///< Execution time stats
diff --git a/libsolidity/SolidityABIJSON.cpp b/libsolidity/SolidityABIJSON.cpp
index 26d0110b..f9bf78d0 100644
--- a/libsolidity/SolidityABIJSON.cpp
+++ b/libsolidity/SolidityABIJSON.cpp
@@ -525,6 +525,49 @@ BOOST_AUTO_TEST_CASE(constructor_abi)
checkInterface(sourceCode, interface);
}
+
+BOOST_AUTO_TEST_CASE(return_param_in_abi)
+{
+ // bug #1801
+ char const* sourceCode = R"(
+ contract test {
+ enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }
+ function test(ActionChoices param) {}
+ function ret() returns(ActionChoices){
+ ActionChoices action = ActionChoices.GoLeft;
+ return action;
+ }
+ }
+ )";
+
+ char const* interface = R"(
+ [
+ {
+ "constant" : false,
+ "inputs" : [],
+ "name" : "ret",
+ "outputs" : [
+ {
+ "name" : "",
+ "type" : "uint8"
+ }
+ ],
+ "type" : "function"
+ },
+ {
+ "inputs": [
+ {
+ "name": "param",
+ "type": "uint8"
+ }
+ ],
+ "type": "constructor"
+ }
+ ]
+ )";
+ checkInterface(sourceCode, interface);
+}
+
BOOST_AUTO_TEST_SUITE_END()
}
diff --git a/libsolidity/SolidityCompiler.cpp b/libsolidity/SolidityCompiler.cpp
index 7b0ceedb..aa83c465 100644
--- a/libsolidity/SolidityCompiler.cpp
+++ b/libsolidity/SolidityCompiler.cpp
@@ -96,7 +96,7 @@ BOOST_AUTO_TEST_CASE(smoke_test)
"}\n";
bytes code = compileContract(sourceCode);
- unsigned boilerplateSize = 70;
+ unsigned boilerplateSize = 73;
bytes expectation({byte(Instruction::JUMPDEST),
byte(Instruction::PUSH1), 0x0, // initialize local variable x
byte(Instruction::PUSH1), 0x2,
@@ -114,8 +114,8 @@ BOOST_AUTO_TEST_CASE(ifStatement)
" function f() { bool x; if (x) 77; else if (!x) 78; else 79; }"
"}\n";
bytes code = compileContract(sourceCode);
- unsigned shift = 57;
- unsigned boilerplateSize = 70;
+ unsigned shift = 60;
+ unsigned boilerplateSize = 73;
bytes expectation({byte(Instruction::JUMPDEST),
byte(Instruction::PUSH1), 0x0,
byte(Instruction::DUP1),
@@ -155,8 +155,8 @@ BOOST_AUTO_TEST_CASE(loops)
" function f() { while(true){1;break;2;continue;3;return;4;} }"
"}\n";
bytes code = compileContract(sourceCode);
- unsigned shift = 57;
- unsigned boilerplateSize = 70;
+ unsigned shift = 60;
+ unsigned boilerplateSize = 73;
bytes expectation({byte(Instruction::JUMPDEST),
byte(Instruction::JUMPDEST),
byte(Instruction::PUSH1), 0x1,
diff --git a/libsolidity/SolidityEndToEndTest.cpp b/libsolidity/SolidityEndToEndTest.cpp
index f168ad45..ed5f1acd 100644
--- a/libsolidity/SolidityEndToEndTest.cpp
+++ b/libsolidity/SolidityEndToEndTest.cpp
@@ -2962,12 +2962,13 @@ BOOST_AUTO_TEST_CASE(bytes_in_arguments)
}
)";
compileAndRun(sourceCode);
+
string innercalldata1 = asString(FixedHash<4>(dev::sha3("f(uint256,uint256)")).asBytes() + encodeArgs(8, 9));
- bytes calldata1 = encodeArgs(u256(innercalldata1.length()), 12, innercalldata1, 13);
string innercalldata2 = asString(FixedHash<4>(dev::sha3("g(uint256)")).asBytes() + encodeArgs(3));
bytes calldata = encodeArgs(
- 12, u256(innercalldata1.length()), u256(innercalldata2.length()), 13,
- innercalldata1, innercalldata2);
+ 12, 32 * 4, u256(32 * 4 + 32 + (innercalldata1.length() + 31) / 32 * 32), 13,
+ u256(innercalldata1.length()), innercalldata1,
+ u256(innercalldata2.length()), innercalldata2);
BOOST_CHECK(callContractFunction("test(uint256,bytes,bytes,uint256)", calldata)
== encodeArgs(12, (8 + 9) * 3, 13, u256(innercalldata1.length())));
}
@@ -3383,9 +3384,10 @@ BOOST_AUTO_TEST_CASE(external_array_args)
compileAndRun(sourceCode);
bytes params = encodeArgs(
1, 2, 3, 4, 5, 6, 7, 8, // a
- 3, // b.length
+ 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
);
BOOST_CHECK(callContractFunction("test(uint256[8],uint256[],uint256[5],uint256,uint256,uint256)", params) == encodeArgs(1, 12, 23));
@@ -3422,8 +3424,8 @@ BOOST_AUTO_TEST_CASE(bytes_index_access)
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33};
- BOOST_CHECK(callContractFunction("direct(bytes,uint256)", u256(array.length()), 32, array) == encodeArgs(32));
- BOOST_CHECK(callContractFunction("storageCopyRead(bytes,uint256)", u256(array.length()), 32, array) == encodeArgs(32));
+ BOOST_CHECK(callContractFunction("direct(bytes,uint256)", 64, 33, u256(array.length()), array) == encodeArgs(33));
+ BOOST_CHECK(callContractFunction("storageCopyRead(bytes,uint256)", 64, 33, u256(array.length()), array) == encodeArgs(33));
BOOST_CHECK(callContractFunction("storageWrite()") == encodeArgs(0x193));
}
@@ -3474,6 +3476,7 @@ BOOST_AUTO_TEST_CASE(array_copy_calldata_storage)
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("store(uint256[9],uint8[3][])", encodeArgs(
21, 22, 23, 24, 25, 26, 27, 28, 29, // a
+ u256(32 * (9 + 1)),
4, // size of b
1, 2, 3, // b[0]
11, 12, 13, // b[1]
@@ -3502,7 +3505,7 @@ BOOST_AUTO_TEST_CASE(array_copy_nested_array)
)";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("test(uint256[2][])", encodeArgs(
- 3,
+ 32, 3,
7, 8,
9, 10,
11, 12
@@ -3910,6 +3913,90 @@ BOOST_AUTO_TEST_CASE(external_types_in_calls)
BOOST_CHECK(callContractFunction("nonexisting") == encodeArgs(u256(9)));
}
+BOOST_AUTO_TEST_CASE(proper_order_of_overwriting_of_attributes)
+{
+ // bug #1798
+ char const* sourceCode = R"(
+ contract init {
+ function isOk() returns (bool) { return false; }
+ bool public ok = false;
+ }
+ contract fix {
+ function isOk() returns (bool) { return true; }
+ bool public ok = true;
+ }
+
+ contract init_fix is init, fix {
+ function checkOk() returns (bool) { return ok; }
+ }
+ contract fix_init is fix, init {
+ function checkOk() returns (bool) { return ok; }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "init_fix");
+ BOOST_CHECK(callContractFunction("isOk()") == encodeArgs(true));
+ BOOST_CHECK(callContractFunction("ok()") == encodeArgs(true));
+
+ compileAndRun(sourceCode, 0, "fix_init");
+ BOOST_CHECK(callContractFunction("isOk()") == encodeArgs(false));
+ BOOST_CHECK(callContractFunction("ok()") == encodeArgs(false));
+}
+
+BOOST_AUTO_TEST_CASE(proper_overwriting_accessor_by_function)
+{
+ // bug #1798
+ char const* sourceCode = R"(
+ contract attribute {
+ bool ok = false;
+ }
+ contract func {
+ function ok() returns (bool) { return true; }
+ }
+
+ contract attr_func is attribute, func {
+ function checkOk() returns (bool) { return ok(); }
+ }
+ contract func_attr is func, attribute {
+ function checkOk() returns (bool) { return ok; }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "attr_func");
+ BOOST_CHECK(callContractFunction("ok()") == encodeArgs(true));
+ compileAndRun(sourceCode, 0, "func_attr");
+ BOOST_CHECK(callContractFunction("checkOk()") == encodeArgs(false));
+}
+
+
+BOOST_AUTO_TEST_CASE(overwriting_inheritance)
+{
+ // bug #1798
+ char const* sourceCode = R"(
+ contract A {
+ function ok() returns (uint) { return 1; }
+ }
+ contract B {
+ function ok() returns (uint) { return 2; }
+ }
+ contract C {
+ uint ok = 6;
+ }
+ contract AB is A, B {
+ function ok() returns (uint) { return 4; }
+ }
+ contract reversedE is C, AB {
+ function checkOk() returns (uint) { return ok(); }
+ }
+ contract E is AB, C {
+ function checkOk() returns (uint) { return ok; }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "reversedE");
+ BOOST_CHECK(callContractFunction("checkOk()") == encodeArgs(4));
+ compileAndRun(sourceCode, 0, "E");
+ BOOST_CHECK(callContractFunction("checkOk()") == encodeArgs(6));
+}
+
+
BOOST_AUTO_TEST_SUITE_END()
}
diff --git a/libsolidity/SolidityNameAndTypeResolution.cpp b/libsolidity/SolidityNameAndTypeResolution.cpp
index c317dad9..4ec7b8bd 100644
--- a/libsolidity/SolidityNameAndTypeResolution.cpp
+++ b/libsolidity/SolidityNameAndTypeResolution.cpp
@@ -508,6 +508,28 @@ BOOST_AUTO_TEST_CASE(function_external_types)
}
}
+BOOST_AUTO_TEST_CASE(enum_external_type)
+{
+ // bug #1801
+ ASTPointer<SourceUnit> sourceUnit;
+ char const* text = R"(
+ contract Test {
+ enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }
+ function boo(ActionChoices enumArg) external returns (uint ret) {
+ ret = 5;
+ }
+ })";
+ ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseTextAndResolveNames(text), "Parsing and name Resolving failed");
+ for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
+ if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
+ {
+ auto functions = contract->getDefinedFunctions();
+ if (functions.empty())
+ continue;
+ BOOST_CHECK_EQUAL("boo(uint8)", functions[0]->externalSignature());
+ }
+}
+
BOOST_AUTO_TEST_CASE(function_external_call_allowed_conversion)
{
char const* text = R"(
diff --git a/libsolidity/SolidityOptimizer.cpp b/libsolidity/SolidityOptimizer.cpp
index 9cdaa588..3cb6a536 100644
--- a/libsolidity/SolidityOptimizer.cpp
+++ b/libsolidity/SolidityOptimizer.cpp
@@ -83,14 +83,28 @@ public:
"\nOptimized: " + toHex(optimizedOutput));
}
- AssemblyItems getCSE(AssemblyItems const& _input)
+ AssemblyItems addDummyLocations(AssemblyItems const& _input)
{
// add dummy locations to each item so that we can check that they are not deleted
AssemblyItems input = _input;
for (AssemblyItem& item: input)
item.setLocation(SourceLocation(1, 3, make_shared<string>("")));
+ return input;
+ }
+
+ eth::KnownState createInitialState(AssemblyItems const& _input)
+ {
+ eth::KnownState state;
+ for (auto const& item: addDummyLocations(_input))
+ state.feedItem(item);
+ return state;
+ }
+
+ AssemblyItems getCSE(AssemblyItems const& _input, eth::KnownState const& _state = eth::KnownState())
+ {
+ AssemblyItems input = addDummyLocations(_input);
- eth::CommonSubexpressionEliminator cse;
+ eth::CommonSubexpressionEliminator cse(_state);
BOOST_REQUIRE(cse.feedItems(input.begin(), input.end()) == input.end());
AssemblyItems output = cse.getOptimizedItems();
@@ -101,9 +115,13 @@ public:
return output;
}
- void checkCSE(AssemblyItems const& _input, AssemblyItems const& _expectation)
+ void checkCSE(
+ AssemblyItems const& _input,
+ AssemblyItems const& _expectation,
+ KnownState const& _state = eth::KnownState()
+ )
{
- AssemblyItems output = getCSE(_input);
+ AssemblyItems output = getCSE(_input, _state);
BOOST_CHECK_EQUAL_COLLECTIONS(_expectation.begin(), _expectation.end(), output.begin(), output.end());
}
@@ -113,8 +131,12 @@ public:
// Running it four times should be enough for these tests.
for (unsigned i = 0; i < 4; ++i)
{
- eth::ControlFlowGraph cfg(output);
- output = cfg.optimisedItems();
+ ControlFlowGraph cfg(output);
+ AssemblyItems optItems;
+ for (BasicBlock const& block: cfg.optimisedBlocks())
+ copy(output.begin() + block.begin, output.begin() + block.end,
+ back_inserter(optItems));
+ output = move(optItems);
}
BOOST_CHECK_EQUAL_COLLECTIONS(_expectation.begin(), _expectation.end(), output.begin(), output.end());
}
@@ -231,7 +253,8 @@ BOOST_AUTO_TEST_CASE(function_calls)
BOOST_AUTO_TEST_CASE(cse_intermediate_swap)
{
- eth::CommonSubexpressionEliminator cse;
+ eth::KnownState state;
+ eth::CommonSubexpressionEliminator cse(state);
AssemblyItems input{
Instruction::SWAP1, Instruction::POP, Instruction::ADD, u256(0), Instruction::SWAP1,
Instruction::SLOAD, Instruction::SWAP1, u256(100), Instruction::EXP, Instruction::SWAP1,
@@ -754,6 +777,30 @@ BOOST_AUTO_TEST_CASE(cse_sha3_twice_same_content_noninterfering_store_in_between
BOOST_CHECK_EQUAL(1, count(output.begin(), output.end(), AssemblyItem(Instruction::SHA3)));
}
+BOOST_AUTO_TEST_CASE(cse_with_initially_known_stack)
+{
+ eth::KnownState state = createInitialState(AssemblyItems{
+ u256(0x12),
+ u256(0x20),
+ Instruction::ADD
+ });
+ AssemblyItems input{
+ u256(0x12 + 0x20)
+ };
+ checkCSE(input, AssemblyItems{Instruction::DUP1}, state);
+}
+
+BOOST_AUTO_TEST_CASE(cse_equality_on_initially_known_stack)
+{
+ eth::KnownState state = createInitialState(AssemblyItems{Instruction::DUP1});
+ AssemblyItems input{
+ Instruction::EQ
+ };
+ AssemblyItems output = getCSE(input, state);
+ // check that it directly pushes 1 (true)
+ BOOST_CHECK(find(output.begin(), output.end(), AssemblyItem(u256(1))) != output.end());
+}
+
BOOST_AUTO_TEST_CASE(control_flow_graph_remove_unused)
{
// remove parts of the code that are unused