Merge pull request #546 from chriseth/fixiszero

Correctly use not/bnot/iszero.
This commit is contained in:
chriseth 2016-05-14 00:58:55 +02:00
commit 4b445b898e
3 changed files with 25 additions and 5 deletions

View File

@ -265,7 +265,7 @@ idea is that assembly libraries will be used to enhance the language in such way
// by using o_code = new bytes(size) // by using o_code = new bytes(size)
o_code := mload(0x40) o_code := mload(0x40)
// new "memory end" including padding // new "memory end" including padding
mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), bnot(0x1f)))) mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f))))
// store length in memory // store length in memory
mstore(o_code, size) mstore(o_code, size)
// actually retrieve the code, this needs assembly // actually retrieve the code, this needs assembly
@ -349,7 +349,7 @@ The opcodes `pushi` and `jumpdest` cannot be used directly.
+-----------------------+------+---------------------------------------------------------------+ +-----------------------+------+---------------------------------------------------------------+
| exp(x, y) | | x to the power of y | | exp(x, y) | | x to the power of y |
+-----------------------+------+---------------------------------------------------------------+ +-----------------------+------+---------------------------------------------------------------+
| bnot(x) | | ~x, every bit of x is negated | | not(x) | | ~x, every bit of x is negated |
+-----------------------+------+---------------------------------------------------------------+ +-----------------------+------+---------------------------------------------------------------+
| lt(x, y) | | 1 if x < y, 0 otherwise | | lt(x, y) | | 1 if x < y, 0 otherwise |
+-----------------------+------+---------------------------------------------------------------+ +-----------------------+------+---------------------------------------------------------------+
@ -361,7 +361,7 @@ The opcodes `pushi` and `jumpdest` cannot be used directly.
+-----------------------+------+---------------------------------------------------------------+ +-----------------------+------+---------------------------------------------------------------+
| eq(x, y) | | 1 if x == y, 0 otherwise | | eq(x, y) | | 1 if x == y, 0 otherwise |
+-----------------------+------+---------------------------------------------------------------+ +-----------------------+------+---------------------------------------------------------------+
| not(x) | | 1 if x == 0, 0 otherwise | | iszero(x) | | 1 if x == 0, 0 otherwise |
+-----------------------+------+---------------------------------------------------------------+ +-----------------------+------+---------------------------------------------------------------+
| and(x, y) | | bitwise and of x and y | | and(x, y) | | bitwise and of x and y |
+-----------------------+------+---------------------------------------------------------------+ +-----------------------+------+---------------------------------------------------------------+

View File

@ -39,13 +39,13 @@ const std::map<std::string, Instruction> dev::solidity::c_instructions =
{ "MOD", Instruction::MOD }, { "MOD", Instruction::MOD },
{ "SMOD", Instruction::SMOD }, { "SMOD", Instruction::SMOD },
{ "EXP", Instruction::EXP }, { "EXP", Instruction::EXP },
{ "BNOT", Instruction::NOT }, { "NOT", Instruction::NOT },
{ "LT", Instruction::LT }, { "LT", Instruction::LT },
{ "GT", Instruction::GT }, { "GT", Instruction::GT },
{ "SLT", Instruction::SLT }, { "SLT", Instruction::SLT },
{ "SGT", Instruction::SGT }, { "SGT", Instruction::SGT },
{ "EQ", Instruction::EQ }, { "EQ", Instruction::EQ },
{ "NOT", Instruction::ISZERO }, { "ISZERO", Instruction::ISZERO },
{ "AND", Instruction::AND }, { "AND", Instruction::AND },
{ "OR", Instruction::OR }, { "OR", Instruction::OR },
{ "XOR", Instruction::XOR }, { "XOR", Instruction::XOR },

View File

@ -6736,6 +6736,26 @@ BOOST_AUTO_TEST_CASE(internal_library_function_return_var_size)
BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(2))); BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(2)));
} }
BOOST_AUTO_TEST_CASE(iszero_bnot_correct)
{
// A long time ago, some opcodes were renamed, which involved the opcodes
// "iszero" and "not".
char const* sourceCode = R"(
contract C {
function f() returns (bool) {
bytes32 x = 1;
assembly { x := not(x) }
if (x != ~bytes32(1)) return false;
assembly { x := iszero(x) }
if (x != bytes32(0)) return false;
return true;
}
}
)";
compileAndRun(sourceCode, 0, "C");
BOOST_CHECK(callContractFunction("f()") == encodeArgs(true));
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()
} }