Merge branch 'develop' into ethash_reloaded

This commit is contained in:
Lefteris Karapetsas 2015-05-11 11:06:00 +02:00
commit b3a3b2f260
4 changed files with 156 additions and 8 deletions

View File

@ -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})

View File

@ -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));

View File

@ -3910,6 +3910,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()
}

View File

@ -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::CommonSubexpressionEliminator cse;
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(_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