mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge branch 'develop' into evmjit-develop
Conflicts: evmjit/include/evmjit/JIT.h evmjit/libevmjit-cpp/Env.cpp evmjit/libevmjit-cpp/JitVM.h evmjit/libevmjit/ExecutionEngine.cpp evmjit/libevmjit/JIT.cpp
This commit is contained in:
commit
7557e4b73f
@ -327,7 +327,8 @@ void ImportTest::checkExpectedState(State const& _stateExpect, State const& _sta
|
|||||||
void ImportTest::exportTest(bytes const& _output, State const& _statePost)
|
void ImportTest::exportTest(bytes const& _output, State const& _statePost)
|
||||||
{
|
{
|
||||||
// export output
|
// export output
|
||||||
m_TestObject["out"] = toHex(_output, 2, HexPrefix::Add);
|
|
||||||
|
m_TestObject["out"] = _output.size() > 4096 ? "#" + toString(_output.size()) : toHex(_output, 2, HexPrefix::Add);
|
||||||
|
|
||||||
// export logs
|
// export logs
|
||||||
m_TestObject["logs"] = exportLog(_statePost.pending().size() ? _statePost.log(0) : LogEntries());
|
m_TestObject["logs"] = exportLog(_statePost.pending().size() ? _statePost.log(0) : LogEntries());
|
||||||
@ -489,7 +490,11 @@ LogEntries importLog(json_spirit::mArray& _a)
|
|||||||
void checkOutput(bytes const& _output, json_spirit::mObject& _o)
|
void checkOutput(bytes const& _output, json_spirit::mObject& _o)
|
||||||
{
|
{
|
||||||
int j = 0;
|
int j = 0;
|
||||||
if (_o["out"].type() == json_spirit::array_type)
|
|
||||||
|
if (_o["out"].get_str().find("#") == 0)
|
||||||
|
BOOST_CHECK((u256)_output.size() == toInt(_o["out"].get_str().substr(1)));
|
||||||
|
|
||||||
|
else if (_o["out"].type() == json_spirit::array_type)
|
||||||
for (auto const& d: _o["out"].get_array())
|
for (auto const& d: _o["out"].get_array())
|
||||||
{
|
{
|
||||||
BOOST_CHECK_MESSAGE(_output[j] == toInt(d), "Output byte [" << j << "] different!");
|
BOOST_CHECK_MESSAGE(_output[j] == toInt(d), "Output byte [" << j << "] different!");
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <test/libsolidity/solidityExecutionFramework.h>
|
#include <test/libsolidity/solidityExecutionFramework.h>
|
||||||
|
#include <libevmasm/GasMeter.h>
|
||||||
|
#include <libevmasm/KnownState.h>
|
||||||
#include <libsolidity/AST.h>
|
#include <libsolidity/AST.h>
|
||||||
#include <libsolidity/StructuralGasEstimator.h>
|
#include <libsolidity/StructuralGasEstimator.h>
|
||||||
#include <libsolidity/SourceReferenceFormatter.h>
|
#include <libsolidity/SourceReferenceFormatter.h>
|
||||||
@ -55,8 +57,21 @@ public:
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void testCreationTimeGas(string const& _sourceCode, string const& _contractName = "")
|
||||||
|
{
|
||||||
|
compileAndRun(_sourceCode);
|
||||||
|
auto state = make_shared<KnownState>();
|
||||||
|
GasMeter meter(state);
|
||||||
|
GasMeter::GasConsumption gas;
|
||||||
|
for (AssemblyItem const& item: *m_compiler.getAssemblyItems(_contractName))
|
||||||
|
gas += meter.estimateMax(item);
|
||||||
|
u256 bytecodeSize(m_compiler.getRuntimeBytecode(_contractName).size());
|
||||||
|
gas += bytecodeSize * c_createDataGas;
|
||||||
|
BOOST_REQUIRE(!gas.isInfinite);
|
||||||
|
BOOST_CHECK(gas.value == m_gasUsed);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
dev::solidity::CompilerStack m_compiler;
|
|
||||||
map<ASTNode const*, eth::GasMeter::GasConsumption> m_gasCosts;
|
map<ASTNode const*, eth::GasMeter::GasConsumption> m_gasCosts;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -91,6 +106,49 @@ BOOST_AUTO_TEST_CASE(non_overlapping_filtered_costs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(simple_contract)
|
||||||
|
{
|
||||||
|
// Tests a simple "deploy contract" code without constructor. The actual contract is not relevant.
|
||||||
|
char const* sourceCode = R"(
|
||||||
|
contract test {
|
||||||
|
bytes32 public shaValue;
|
||||||
|
function f(uint a) {
|
||||||
|
shaValue = sha3(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
testCreationTimeGas(sourceCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(store_sha3)
|
||||||
|
{
|
||||||
|
char const* sourceCode = R"(
|
||||||
|
contract test {
|
||||||
|
bytes32 public shaValue;
|
||||||
|
function test(uint a) {
|
||||||
|
shaValue = sha3(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
testCreationTimeGas(sourceCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(updating_store)
|
||||||
|
{
|
||||||
|
char const* sourceCode = R"(
|
||||||
|
contract test {
|
||||||
|
uint data;
|
||||||
|
uint data2;
|
||||||
|
function test() {
|
||||||
|
data = 1;
|
||||||
|
data = 2;
|
||||||
|
data2 = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
testCreationTimeGas(sourceCode);
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
}
|
}
|
@ -24,7 +24,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
#include <libdevcrypto/SHA3.h>
|
#include <libdevcore/Hash.h>
|
||||||
#include <test/libsolidity/solidityExecutionFramework.h>
|
#include <test/libsolidity/solidityExecutionFramework.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -1501,9 +1501,7 @@ BOOST_AUTO_TEST_CASE(sha256)
|
|||||||
compileAndRun(sourceCode);
|
compileAndRun(sourceCode);
|
||||||
auto f = [&](u256 const& _input) -> u256
|
auto f = [&](u256 const& _input) -> u256
|
||||||
{
|
{
|
||||||
h256 ret;
|
return dev::sha256(dev::ref(toBigEndian(_input)));
|
||||||
dev::sha256(dev::ref(toBigEndian(_input)), bytesRef(&ret[0], 32));
|
|
||||||
return ret;
|
|
||||||
};
|
};
|
||||||
testSolidityAgainstCpp("a(bytes32)", f, u256(4));
|
testSolidityAgainstCpp("a(bytes32)", f, u256(4));
|
||||||
testSolidityAgainstCpp("a(bytes32)", f, u256(5));
|
testSolidityAgainstCpp("a(bytes32)", f, u256(5));
|
||||||
@ -1520,9 +1518,7 @@ BOOST_AUTO_TEST_CASE(ripemd)
|
|||||||
compileAndRun(sourceCode);
|
compileAndRun(sourceCode);
|
||||||
auto f = [&](u256 const& _input) -> u256
|
auto f = [&](u256 const& _input) -> u256
|
||||||
{
|
{
|
||||||
h256 ret;
|
return h256(dev::ripemd160(h256(_input).ref()), h256::AlignLeft); // This should be aligned right. i guess it's fixed elsewhere?
|
||||||
dev::ripemd160(dev::ref(toBigEndian(_input)), bytesRef(&ret[0], 32));
|
|
||||||
return u256(ret);
|
|
||||||
};
|
};
|
||||||
testSolidityAgainstCpp("a(bytes32)", f, u256(4));
|
testSolidityAgainstCpp("a(bytes32)", f, u256(4));
|
||||||
testSolidityAgainstCpp("a(bytes32)", f, u256(5));
|
testSolidityAgainstCpp("a(bytes32)", f, u256(5));
|
||||||
@ -4027,6 +4023,92 @@ BOOST_AUTO_TEST_CASE(overwriting_inheritance)
|
|||||||
BOOST_CHECK(callContractFunction("checkOk()") == encodeArgs(6));
|
BOOST_CHECK(callContractFunction("checkOk()") == encodeArgs(6));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(struct_assign_reference_to_struct)
|
||||||
|
{
|
||||||
|
char const* sourceCode = R"(
|
||||||
|
contract test {
|
||||||
|
struct testStruct
|
||||||
|
{
|
||||||
|
uint m_value;
|
||||||
|
}
|
||||||
|
testStruct data1;
|
||||||
|
testStruct data2;
|
||||||
|
testStruct data3;
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
data1.m_value = 2;
|
||||||
|
}
|
||||||
|
function assign() returns (uint ret_local, uint ret_global, uint ret_global3, uint ret_global1)
|
||||||
|
{
|
||||||
|
testStruct x = data1; //x is a reference data1.m_value == 2 as well as x.m_value = 2
|
||||||
|
data2 = data1; // should copy data. data2.m_value == 2
|
||||||
|
|
||||||
|
ret_local = x.m_value; // = 2
|
||||||
|
ret_global = data2.m_value; // = 2
|
||||||
|
|
||||||
|
x.m_value = 3;
|
||||||
|
data3 = x; //should copy the data. data3.m_value == 3
|
||||||
|
ret_global3 = data3.m_value; // = 3
|
||||||
|
ret_global1 = data1.m_value; // = 3. Changed due to the assignment to x.m_value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
compileAndRun(sourceCode, 0, "test");
|
||||||
|
BOOST_CHECK(callContractFunction("assign()") == encodeArgs(2, 2, 3, 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(struct_delete_member)
|
||||||
|
{
|
||||||
|
char const* sourceCode = R"(
|
||||||
|
contract test {
|
||||||
|
struct testStruct
|
||||||
|
{
|
||||||
|
uint m_value;
|
||||||
|
}
|
||||||
|
testStruct data1;
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
data1.m_value = 2;
|
||||||
|
}
|
||||||
|
function deleteMember() returns (uint ret_value)
|
||||||
|
{
|
||||||
|
testStruct x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0
|
||||||
|
x.m_value = 4;
|
||||||
|
delete x.m_value;
|
||||||
|
ret_value = data1.m_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
compileAndRun(sourceCode, 0, "test");
|
||||||
|
auto res = callContractFunction("deleteMember()");
|
||||||
|
BOOST_CHECK(callContractFunction("deleteMember()") == encodeArgs(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(struct_delete_struct_in_mapping)
|
||||||
|
{
|
||||||
|
char const* sourceCode = R"(
|
||||||
|
contract test {
|
||||||
|
struct testStruct
|
||||||
|
{
|
||||||
|
uint m_value;
|
||||||
|
}
|
||||||
|
mapping (uint => testStruct) campaigns;
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
campaigns[0].m_value = 2;
|
||||||
|
}
|
||||||
|
function deleteIt() returns (uint)
|
||||||
|
{
|
||||||
|
delete campaigns[0];
|
||||||
|
return campaigns[0].m_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
compileAndRun(sourceCode, 0, "test");
|
||||||
|
auto res = callContractFunction("deleteIt()");
|
||||||
|
BOOST_CHECK(callContractFunction("deleteIt()") == encodeArgs(0));
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <libdevcore/Log.h>
|
#include <libdevcore/Log.h>
|
||||||
#include <libdevcrypto/SHA3.h>
|
#include <libdevcore/SHA3.h>
|
||||||
#include <libsolidity/Scanner.h>
|
#include <libsolidity/Scanner.h>
|
||||||
#include <libsolidity/Parser.h>
|
#include <libsolidity/Parser.h>
|
||||||
#include <libsolidity/NameAndTypeResolver.h>
|
#include <libsolidity/NameAndTypeResolver.h>
|
||||||
|
@ -44,11 +44,11 @@ public:
|
|||||||
|
|
||||||
bytes const& compileAndRun(std::string const& _sourceCode, u256 const& _value = 0, std::string const& _contractName = "")
|
bytes const& compileAndRun(std::string const& _sourceCode, u256 const& _value = 0, std::string const& _contractName = "")
|
||||||
{
|
{
|
||||||
dev::solidity::CompilerStack compiler(m_addStandardSources);
|
m_compiler.reset(false, m_addStandardSources);
|
||||||
compiler.addSource("", _sourceCode);
|
m_compiler.addSource("", _sourceCode);
|
||||||
ETH_TEST_REQUIRE_NO_THROW(compiler.compile(m_optimize), "Compiling contract failed");
|
ETH_TEST_REQUIRE_NO_THROW(m_compiler.compile(m_optimize), "Compiling contract failed");
|
||||||
|
|
||||||
bytes code = compiler.getBytecode(_contractName);
|
bytes code = m_compiler.getBytecode(_contractName);
|
||||||
sendMessage(code, true, _value);
|
sendMessage(code, true, _value);
|
||||||
BOOST_REQUIRE(!m_output.empty());
|
BOOST_REQUIRE(!m_output.empty());
|
||||||
return m_output;
|
return m_output;
|
||||||
@ -160,12 +160,14 @@ protected:
|
|||||||
BOOST_REQUIRE(executive.go());
|
BOOST_REQUIRE(executive.go());
|
||||||
m_state.noteSending(m_sender);
|
m_state.noteSending(m_sender);
|
||||||
executive.finalize();
|
executive.finalize();
|
||||||
|
m_gasUsed = executive.gasUsed();
|
||||||
m_output = executive.out().toVector();
|
m_output = executive.out().toVector();
|
||||||
m_logs = executive.logs();
|
m_logs = executive.logs();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool m_optimize = false;
|
bool m_optimize = false;
|
||||||
bool m_addStandardSources = false;
|
bool m_addStandardSources = false;
|
||||||
|
dev::solidity::CompilerStack m_compiler;
|
||||||
Address m_sender;
|
Address m_sender;
|
||||||
Address m_contractAddress;
|
Address m_contractAddress;
|
||||||
eth::State m_state;
|
eth::State m_state;
|
||||||
@ -173,6 +175,7 @@ protected:
|
|||||||
u256 const m_gas = 100000000;
|
u256 const m_gas = 100000000;
|
||||||
bytes m_output;
|
bytes m_output;
|
||||||
eth::LogEntries m_logs;
|
eth::LogEntries m_logs;
|
||||||
|
u256 m_gasUsed;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user