Addmod and mulmod.

This commit is contained in:
chriseth 2015-11-18 17:12:39 +01:00
parent b4e666ccf4
commit 0cf8d022ae
4 changed files with 38 additions and 0 deletions

View File

@ -40,6 +40,10 @@ m_magicVariables(vector<shared_ptr<MagicVariableDeclaration const>>{make_shared<
make_shared<MagicVariableDeclaration>("now", make_shared<IntegerType>(256)),
make_shared<MagicVariableDeclaration>("suicide",
make_shared<FunctionType>(strings{"address"}, strings{}, FunctionType::Location::Suicide)),
make_shared<MagicVariableDeclaration>("addmod",
make_shared<FunctionType>(strings{"uint256", "uint256", "uint256"}, strings{"uint256"}, FunctionType::Location::AddMod)),
make_shared<MagicVariableDeclaration>("mulmod",
make_shared<FunctionType>(strings{"uint256", "uint256", "uint256"}, strings{"uint256"}, FunctionType::Location::MulMod)),
make_shared<MagicVariableDeclaration>("sha3",
make_shared<FunctionType>(strings(), strings{"bytes32"}, FunctionType::Location::SHA3, true)),
make_shared<MagicVariableDeclaration>("log0",

View File

@ -747,6 +747,8 @@ public:
SetGas, ///< modify the default gas value for the function call
SetValue, ///< modify the default value transfer for the function call
BlockHash, ///< BLOCKHASH
AddMod, ///< ADDMOD
MulMod, ///< MULMOD
ArrayPush, ///< .push() to a dynamically sized array in storage
ByteArrayPush ///< .push() to a dynamically sized byte array in storage
};

View File

@ -637,6 +637,20 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
m_context << eth::Instruction::BLOCKHASH;
break;
}
case Location::AddMod:
case Location::MulMod:
{
for (unsigned i = 0; i < 3; i ++)
{
arguments[2 - i]->accept(*this);
utils().convertType(*arguments[2 - i]->annotation().type, IntegerType(256));
}
if (function.location() == Location::AddMod)
m_context << eth::Instruction::ADDMOD;
else
m_context << eth::Instruction::MULMOD;
break;
}
case Location::ECRecover:
case Location::SHA256:
case Location::RIPEMD160:

View File

@ -5831,6 +5831,24 @@ BOOST_AUTO_TEST_CASE(memory_overwrite)
BOOST_CHECK(callContractFunction("f()") == encodeDyn(string("b23a5")));
}
BOOST_AUTO_TEST_CASE(addmod_mulmod)
{
char const* sourceCode = R"(
contract C {
function test() returns (uint) {
// Note that this only works because computation on literals is done using
// unbounded integers.
if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7))
return 1;
if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7))
return 2;
return 0;
}
}
)";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(0)));
}
BOOST_AUTO_TEST_SUITE_END()
}