diff --git a/libethereum/State.cpp b/libethereum/State.cpp index fd00761e1..e02b06bcd 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -1017,7 +1017,7 @@ u256 State::execute(bytesConstRef _rlp, bytes* o_output, bool _commit) ctrace << "Executing" << e.t() << "on" << h; ctrace << toHex(e.t().rlp()); #endif -#if ETH_TRACE +#if ETH_VMTRACE e.go(e.simpleTrace()); #else e.go(); diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index f58c157d9..cf641935a 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -62,6 +62,8 @@ bool ExpressionCompiler::visit(Assignment const& _assignment) m_context << eth::Instruction::SWAP1 << eth::Instruction::DUP2; m_currentLValue.retrieveValue(_assignment, true); appendOrdinaryBinaryOperatorCode(Token::AssignmentToBinaryOp(op), *_assignment.getType()); + if (m_currentLValue.storesReferenceOnStack()) + m_context << eth::Instruction::SWAP1; } m_currentLValue.storeValue(_assignment); m_currentLValue.reset(); diff --git a/libsolidity/InterfaceHandler.cpp b/libsolidity/InterfaceHandler.cpp index 5b5682ff1..60971fbb9 100644 --- a/libsolidity/InterfaceHandler.cpp +++ b/libsolidity/InterfaceHandler.cpp @@ -56,6 +56,7 @@ std::unique_ptr InterfaceHandler::getABIInterface(ContractDefinitio }; method["name"] = f->getName(); + method["const"] = f->isDeclaredConst(); method["inputs"] = populateParameters(f->getParameters()); method["outputs"] = populateParameters(f->getReturnParameters()); methods.append(method); diff --git a/libsolidity/Token.h b/libsolidity/Token.h index 32656096a..897d6eaaa 100644 --- a/libsolidity/Token.h +++ b/libsolidity/Token.h @@ -107,9 +107,9 @@ namespace solidity T(COMMA, ",", 1) \ T(OR, "||", 4) \ T(AND, "&&", 5) \ - T(BIT_OR, "|", 6) \ - T(BIT_XOR, "^", 7) \ - T(BIT_AND, "&", 8) \ + T(BIT_OR, "|", 8) \ + T(BIT_XOR, "^", 9) \ + T(BIT_AND, "&", 10) \ T(SHL, "<<", 11) \ T(SAR, ">>", 11) \ T(SHR, ">>>", 11) \ @@ -122,13 +122,13 @@ namespace solidity /* Compare operators sorted by precedence. */ \ /* IsCompareOp() relies on this block of enum values */ \ /* being contiguous and sorted in the same order! */ \ - T(EQ, "==", 9) \ - T(NE, "!=", 9) \ - T(LT, "<", 10) \ - T(GT, ">", 10) \ - T(LTE, "<=", 10) \ - T(GTE, ">=", 10) \ - K(IN, "in", 10) \ + T(EQ, "==", 6) \ + T(NE, "!=", 6) \ + T(LT, "<", 7) \ + T(GT, ">", 7) \ + T(LTE, "<=", 7) \ + T(GTE, ">=", 7) \ + K(IN, "in", 7) \ \ /* Unary operators. */ \ /* IsUnaryOp() relies on this block of enum values */ \ diff --git a/test/SolidityABIJSON.cpp b/test/SolidityABIJSON.cpp index c734009c3..62ab0458c 100644 --- a/test/SolidityABIJSON.cpp +++ b/test/SolidityABIJSON.cpp @@ -76,6 +76,7 @@ BOOST_AUTO_TEST_CASE(basic_test) char const* interface = R"([ { "name": "f", + "const": false, "inputs": [ { "name": "a", @@ -114,6 +115,7 @@ BOOST_AUTO_TEST_CASE(multiple_methods) char const* interface = R"([ { "name": "f", + "const": false, "inputs": [ { "name": "a", @@ -129,6 +131,7 @@ BOOST_AUTO_TEST_CASE(multiple_methods) }, { "name": "g", + "const": false, "inputs": [ { "name": "b", @@ -156,6 +159,7 @@ BOOST_AUTO_TEST_CASE(multiple_params) char const* interface = R"([ { "name": "f", + "const": false, "inputs": [ { "name": "a", @@ -189,6 +193,7 @@ BOOST_AUTO_TEST_CASE(multiple_methods_order) char const* interface = R"([ { "name": "c", + "const": false, "inputs": [ { "name": "b", @@ -204,6 +209,7 @@ BOOST_AUTO_TEST_CASE(multiple_methods_order) }, { "name": "f", + "const": false, "inputs": [ { "name": "a", @@ -222,6 +228,53 @@ BOOST_AUTO_TEST_CASE(multiple_methods_order) checkInterface(sourceCode, interface); } +BOOST_AUTO_TEST_CASE(const_function) +{ + char const* sourceCode = "contract test {\n" + " function foo(uint a, uint b) returns(uint d) { return a + b; }\n" + " function boo(uint32 a) const returns(uint b) { return a * 4; }\n" + "}\n"; + + char const* interface = R"([ + { + "name": "boo", + "const": true, + "inputs": [{ + "name": "a", + "type": "uint32" + }], + "outputs": [ + { + "name": "b", + "type": "uint256" + } + ] + }, + { + "name": "foo", + "const": false, + "inputs": [ + { + "name": "a", + "type": "uint256" + }, + { + "name": "b", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "d", + "type": "uint256" + } + ] + } + ])"; + + checkInterface(sourceCode, interface); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index aa74f8186..9559e3702 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -504,6 +504,41 @@ BOOST_AUTO_TEST_CASE(state_smoke_test) BOOST_CHECK(callContractFunction(0, bytes(1, 0x00)) == toBigEndian(u256(0x3))); } +BOOST_AUTO_TEST_CASE(compound_assign) +{ + char const* sourceCode = "contract test {\n" + " uint value1;\n" + " uint value2;\n" + " function f(uint x, uint y) returns (uint w) {\n" + " uint value3 = y;" + " value1 += x;\n" + " value3 *= x;" + " value2 *= value3 + value1;\n" + " return value2 += 7;" + " }\n" + "}\n"; + compileAndRun(sourceCode); + + u256 value1; + u256 value2; + auto f = [&](u256 const& _x, u256 const& _y) -> u256 + { + u256 value3 = _y; + value1 += _x; + value3 *= _x; + value2 *= value3 + value1; + return value2 += 7; + }; + testSolidityAgainstCpp(0, f, u256(0), u256(6)); + testSolidityAgainstCpp(0, f, u256(1), u256(3)); + testSolidityAgainstCpp(0, f, u256(2), u256(25)); + testSolidityAgainstCpp(0, f, u256(3), u256(69)); + testSolidityAgainstCpp(0, f, u256(4), u256(84)); + testSolidityAgainstCpp(0, f, u256(5), u256(2)); + testSolidityAgainstCpp(0, f, u256(6), u256(51)); + testSolidityAgainstCpp(0, f, u256(7), u256(48)); +} + BOOST_AUTO_TEST_CASE(simple_mapping) { char const* sourceCode = "contract test {\n" diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index 0bda0a1fd..25bff71f7 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -311,6 +311,16 @@ BOOST_AUTO_TEST_CASE(forward_function_reference) BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); } +BOOST_AUTO_TEST_CASE(comparison_bitop_precedence) +{ + char const* text = "contract First {\n" + " function fun() returns (bool ret) {\n" + " return 1 & 2 == 8 & 9 && 1 ^ 2 < 4 | 6;\n" + " }\n" + "}\n"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/stRefundTestFiller.json b/test/stRefundTestFiller.json index 4060bbb72..6b2b2fc15 100644 --- a/test/stRefundTestFiller.json +++ b/test/stRefundTestFiller.json @@ -141,5 +141,168 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } + }, + + "refund50_1" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 1 ]] 0 [[ 2 ]] 0 [[ 3 ]] 0 [[ 4 ]] 0 [[ 5 ]] 0 }", + "storage" : { + "0x01" : "0x01", + "0x02" : "0x01", + "0x03" : "0x01", + "0x04" : "0x01", + "0x05" : "0x01" + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000", + "nonce" : 0, + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "10000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "refund50_2" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 10 ]] 1 [[ 11 ]] 1 [[ 1 ]] 0 [[ 2 ]] 0 [[ 3 ]] 0 [[ 4 ]] 0 [[ 5 ]] 0 }", + "storage" : { + "0x01" : "0x01", + "0x02" : "0x01", + "0x03" : "0x01", + "0x04" : "0x01", + "0x05" : "0x01" + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000", + "nonce" : 0, + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "10000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "refund500" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ @@1 @@2 [[ 10 ]] (EXP 2 0xff) [[ 11 ]] (BALANCE (ADDRESS)) [[ 1 ]] 0 [[ 2 ]] 0 [[ 3 ]] 0 [[ 4 ]] 0 [[ 5 ]] 0 [[ 6 ]] 0 }", + "storage" : { + "0x01" : "0x01", + "0x02" : "0x01", + "0x03" : "0x01", + "0x04" : "0x01", + "0x05" : "0x01", + "0x06" : "0x01" + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000", + "nonce" : 0, + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "10000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "refund600" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ @@1 @@2 [[ 10 ]] (EXP 2 0xffff) [[ 11 ]] (BALANCE (ADDRESS)) [[ 1 ]] 0 [[ 2 ]] 0 [[ 3 ]] 0 [[ 4 ]] 0 [[ 5 ]] 0 [[ 6 ]] 0 }", + "storage" : { + "0x01" : "0x01", + "0x02" : "0x01", + "0x03" : "0x01", + "0x04" : "0x01", + "0x05" : "0x01", + "0x06" : "0x01" + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000", + "nonce" : 0, + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "10000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } } + }