aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian <c@ethdev.com>2014-11-05 04:29:36 +0800
committerChristian <c@ethdev.com>2014-11-06 09:36:39 +0800
commit04e7977ea13fcac51e274f867ec1cd664a723bc7 (patch)
tree03ff0d2b7a4e690e65b6046dea687f6542d69d55
parent010710353a4097f5dc94e42130ce22e6f0c72beb (diff)
downloaddexon-solidity-04e7977ea13fcac51e274f867ec1cd664a723bc7.tar.gz
dexon-solidity-04e7977ea13fcac51e274f867ec1cd664a723bc7.tar.zst
dexon-solidity-04e7977ea13fcac51e274f867ec1cd664a723bc7.zip
Type promotion fixes and tests.
-rw-r--r--solidityCompiler.cpp8
-rw-r--r--solidityEndToEndTest.cpp42
-rw-r--r--solidityExpressionCompiler.cpp33
3 files changed, 63 insertions, 20 deletions
diff --git a/solidityCompiler.cpp b/solidityCompiler.cpp
index 69d33133..192fd61a 100644
--- a/solidityCompiler.cpp
+++ b/solidityCompiler.cpp
@@ -119,10 +119,10 @@ BOOST_AUTO_TEST_CASE(different_argument_numbers)
byte(Instruction::JUMPDEST), // beginning of g
byte(Instruction::PUSH1), 0x0,
byte(Instruction::DUP1), // initialized e and h
- byte(Instruction::PUSH1), byte(0x20 + shift), // ret address
- byte(Instruction::PUSH1), 0x1,
- byte(Instruction::PUSH1), 0x2,
- byte(Instruction::PUSH1), 0x3,
+ byte(Instruction::PUSH1), 0x29 + shift, // ret address
+ byte(Instruction::PUSH1), 0x1, byte(Instruction::PUSH1), 0xff, byte(Instruction::AND),
+ byte(Instruction::PUSH1), 0x2, byte(Instruction::PUSH1), 0xff, byte(Instruction::AND),
+ byte(Instruction::PUSH1), 0x3, byte(Instruction::PUSH1), 0xff, byte(Instruction::AND),
byte(Instruction::PUSH1), byte(0x1 + shift),
// stack here: ret e h 0x20 1 2 3 0x1
byte(Instruction::JUMP),
diff --git a/solidityEndToEndTest.cpp b/solidityEndToEndTest.cpp
index b4da53ba..c60d6887 100644
--- a/solidityEndToEndTest.cpp
+++ b/solidityEndToEndTest.cpp
@@ -192,6 +192,21 @@ BOOST_AUTO_TEST_CASE(many_local_variables)
== toBigEndian(u256(0x121121)));
}
+BOOST_AUTO_TEST_CASE(packing_unpacking_types)
+{
+ char const* sourceCode = "contract test {\n"
+ " function run(bool a, uint32 b, uint64 c) returns(uint256 y) {\n"
+ " if (a) y = 1;\n"
+ " y = y * 0x100000000 | ~b;\n"
+ " y = y * 0x10000000000000000 | ~c;\n"
+ " }\n"
+ "}\n";
+ ExecutionFramework framework;
+ framework.compileAndRun(sourceCode);
+ BOOST_CHECK(framework.callFunction(0, fromHex("01""0f0f0f0f""f0f0f0f0f0f0f0f0"))
+ == fromHex("00000000000000000000000000000000000000""01""f0f0f0f0""0f0f0f0f0f0f0f0f"));
+}
+
BOOST_AUTO_TEST_CASE(multiple_return_values)
{
char const* sourceCode = "contract test {\n"
@@ -244,7 +259,32 @@ BOOST_AUTO_TEST_CASE(sign_extension)
"}\n";
ExecutionFramework framework;
framework.compileAndRun(sourceCode);
- BOOST_CHECK(framework.callFunction(0, bytes()) == bytes(32, 0xff));
+ BOOST_CHECK(framework.callFunction(0, bytes()) == toBigEndian(u256(0xff)));
+}
+
+BOOST_AUTO_TEST_CASE(small_unsigned_types)
+{
+ char const* sourceCode = "contract test {\n"
+ " function run() returns(uint256 y) {\n"
+ " uint32 x = uint32(0xffffff) * 0xffffff;\n"
+ " return x / 0x100;"
+ " }\n"
+ "}\n";
+ ExecutionFramework framework;
+ framework.compileAndRun(sourceCode);
+ BOOST_CHECK(framework.callFunction(0, bytes()) == toBigEndian(u256(0xfffe0000)));
+}
+
+BOOST_AUTO_TEST_CASE(small_signed_types)
+{
+ char const* sourceCode = "contract test {\n"
+ " function run() returns(int256 y) {\n"
+ " return -int32(10) * -int64(20);\n"
+ " }\n"
+ "}\n";
+ ExecutionFramework framework;
+ framework.compileAndRun(sourceCode);
+ BOOST_CHECK(framework.callFunction(0, bytes()) == toBigEndian(u256(200)));
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/solidityExpressionCompiler.cpp b/solidityExpressionCompiler.cpp
index 561cc3bd..3be909c3 100644
--- a/solidityExpressionCompiler.cpp
+++ b/solidityExpressionCompiler.cpp
@@ -154,8 +154,8 @@ BOOST_AUTO_TEST_CASE(comparison)
"}\n";
bytes code = compileFirstExpression(sourceCode);
- bytes expectation({byte(eth::Instruction::PUSH2), 0x10, 0xaa,
- byte(eth::Instruction::PUSH2), 0x11, 0xaa,
+ bytes expectation({byte(eth::Instruction::PUSH2), 0x10, 0xaa, byte(eth::Instruction::PUSH2), 0xff, 0xff, byte(eth::Instruction::AND),
+ byte(eth::Instruction::PUSH2), 0x11, 0xaa, byte(eth::Instruction::PUSH2), 0xff, 0xff, byte(eth::Instruction::AND),
byte(eth::Instruction::GT),
byte(eth::Instruction::PUSH1), 0x1,
byte(eth::Instruction::EQ),
@@ -172,16 +172,16 @@ BOOST_AUTO_TEST_CASE(short_circuiting)
bytes expectation({byte(eth::Instruction::PUSH1), 0xa,
byte(eth::Instruction::PUSH1), 0x8,
- byte(eth::Instruction::ADD),
- byte(eth::Instruction::PUSH1), 0x4,
+ byte(eth::Instruction::ADD), byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
+ byte(eth::Instruction::PUSH1), 0x4, byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
byte(eth::Instruction::GT),
byte(eth::Instruction::ISZERO), // after this we have 10 + 8 >= 4
byte(eth::Instruction::DUP1),
- byte(eth::Instruction::PUSH1), 0x14,
+ byte(eth::Instruction::PUSH1), 0x20,
byte(eth::Instruction::JUMPI), // short-circuit if it is true
byte(eth::Instruction::POP),
- byte(eth::Instruction::PUSH1), 0x2,
- byte(eth::Instruction::PUSH1), 0x9,
+ byte(eth::Instruction::PUSH1), 0x2, byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
+ byte(eth::Instruction::PUSH1), 0x9, byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
byte(eth::Instruction::EQ),
byte(eth::Instruction::ISZERO), // after this we have 2 != 9
byte(eth::Instruction::JUMPDEST),
@@ -197,10 +197,11 @@ BOOST_AUTO_TEST_CASE(arithmetics)
" function f() { var x = (1 * (2 / (3 % (4 + (5 - (6 | (7 & (8 ^ 9)))))))); }"
"}\n";
bytes code = compileFirstExpression(sourceCode);
-
bytes expectation({byte(eth::Instruction::PUSH1), 0x1,
byte(eth::Instruction::PUSH1), 0x2,
+ byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
byte(eth::Instruction::PUSH1), 0x3,
+ byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
byte(eth::Instruction::PUSH1), 0x4,
byte(eth::Instruction::PUSH1), 0x5,
byte(eth::Instruction::PUSH1), 0x6,
@@ -213,8 +214,10 @@ BOOST_AUTO_TEST_CASE(arithmetics)
byte(eth::Instruction::SWAP1),
byte(eth::Instruction::SUB),
byte(eth::Instruction::ADD),
+ byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
byte(eth::Instruction::SWAP1),
byte(eth::Instruction::MOD),
+ byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
byte(eth::Instruction::SWAP1),
byte(eth::Instruction::DIV),
byte(eth::Instruction::MUL)});
@@ -231,8 +234,8 @@ BOOST_AUTO_TEST_CASE(unary_operators)
bytes expectation({byte(eth::Instruction::PUSH1), 0x1,
byte(eth::Instruction::PUSH1), 0x0,
byte(eth::Instruction::SUB),
- byte(eth::Instruction::NOT),
- byte(eth::Instruction::PUSH1), 0x2,
+ byte(eth::Instruction::NOT), byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
+ byte(eth::Instruction::PUSH1), 0x2, byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
byte(eth::Instruction::EQ),
byte(eth::Instruction::ISZERO)});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
@@ -305,7 +308,7 @@ BOOST_AUTO_TEST_CASE(assignment)
byte(eth::Instruction::POP),
byte(eth::Instruction::DUP2),
// Stack here: a+b b a+b
- byte(eth::Instruction::PUSH1), 0x2,
+ byte(eth::Instruction::PUSH1), 0x2, byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
byte(eth::Instruction::MUL)});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -320,17 +323,17 @@ BOOST_AUTO_TEST_CASE(function_call)
{{"test", "f", "a"}, {"test", "f", "b"}});
// Stack: a, b
- bytes expectation({byte(eth::Instruction::PUSH1), 0x0a,
+ bytes expectation({byte(eth::Instruction::PUSH1), 0x0d,
byte(eth::Instruction::DUP3),
- byte(eth::Instruction::PUSH1), 0x01,
+ byte(eth::Instruction::PUSH1), 0x01, byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
byte(eth::Instruction::ADD),
// Stack here: a b <ret label> (a+1)
byte(eth::Instruction::DUP3),
- byte(eth::Instruction::PUSH1), 0x14,
+ byte(eth::Instruction::PUSH1), 0x1a,
byte(eth::Instruction::JUMP),
byte(eth::Instruction::JUMPDEST),
// Stack here: a b g(a+1, b)
- byte(eth::Instruction::PUSH1), 0x02,
+ byte(eth::Instruction::PUSH1), 0x02, byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
byte(eth::Instruction::MUL),
// Stack here: a b g(a+1, b)*2
byte(eth::Instruction::DUP3),