Merge pull request #8777 from ethereum/sol_yul_simplefunctions

[Sol - Yul] Add some built-in functions.
This commit is contained in:
chriseth 2020-05-04 16:07:10 +02:00 committed by GitHub
commit 1aef9c7d20
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 5 deletions

View File

@ -585,7 +585,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
case FunctionType::Kind::Internal:
{
vector<string> args;
for (unsigned i = 0; i < arguments.size(); ++i)
for (size_t i = 0; i < arguments.size(); ++i)
if (functionType->takesArbitraryParameters())
args.emplace_back(IRVariable(*arguments[i]).commaSeparatedList());
else
@ -829,15 +829,43 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
{
break;
}
case FunctionType::Kind::GasLeft:
case FunctionType::Kind::AddMod:
case FunctionType::Kind::MulMod:
{
define(_functionCall) << "gas()\n";
static map<FunctionType::Kind, string> functions = {
{FunctionType::Kind::AddMod, "addmod"},
{FunctionType::Kind::MulMod, "mulmod"},
};
solAssert(functions.find(functionType->kind()) != functions.end(), "");
solAssert(arguments.size() == 3 && parameterTypes.size() == 3, "");
IRVariable modulus(m_context.newYulVariable(), *(parameterTypes[2]));
define(modulus, *arguments[2]);
Whiskers templ("if iszero(<modulus>) { invalid() }\n");
m_code << templ("modulus", modulus.name()).render();
string args;
for (size_t i = 0; i < 2; ++i)
args += expressionAsType(*arguments[i], *(parameterTypes[i])) + ", ";
args += modulus.name();
define(_functionCall) << functions[functionType->kind()] << "(" << args << ")\n";
break;
}
case FunctionType::Kind::GasLeft:
case FunctionType::Kind::Selfdestruct:
case FunctionType::Kind::BlockHash:
{
solAssert(arguments.size() == 1, "");
define(_functionCall) << "selfdestruct(" << expressionAsType(*arguments.front(), *parameterTypes.front()) << ")\n";
static map<FunctionType::Kind, string> functions = {
{FunctionType::Kind::GasLeft, "gas"},
{FunctionType::Kind::Selfdestruct, "selfdestruct"},
{FunctionType::Kind::BlockHash, "blockhash"},
};
solAssert(functions.find(functionType->kind()) != functions.end(), "");
string args;
for (size_t i = 0; i < arguments.size(); ++i)
args += (args.empty() ? "" : ", ") + expressionAsType(*arguments[i], *(parameterTypes[i]));
define(_functionCall) << functions[functionType->kind()] << "(" << args << ")\n";
break;
}
case FunctionType::Kind::Log0:

View File

@ -18,6 +18,8 @@ contract C {
}
}
// ====
// compileViaYul: also
// ----
// f(uint256): 0 -> FAILURE
// g(uint256): 0 -> FAILURE

View File

@ -0,0 +1,17 @@
contract C {
function f() public returns(bytes32) {
return blockhash(1);
}
function g() public returns(bytes32) {
return blockhash(2);
}
function h() public returns(bytes32) {
return blockhash(3);
}
}
// ====
// compileViaYul: also
// ----
// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738
// g() -> 0x3737373737373737373737373737373737373737373737373737373737373739
// h() -> 0x373737373737373737373737373737373737373737373737373737373737373a