[Sol2Yul] Adding support for builtin revert(string)

This commit is contained in:
Djordje Mijovic 2020-05-04 23:04:03 +02:00
parent fc41f78146
commit e8f6f63e77
4 changed files with 40 additions and 3 deletions

View File

@ -737,7 +737,41 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
if (arguments.empty())
m_code << "revert(0, 0)\n";
else
solUnimplementedAssert(false, "");
{
solAssert(arguments.size() == 1, "");
if (m_context.revertStrings() == RevertStrings::Strip)
m_code << "revert(0, 0)\n";
else
{
solAssert(type(*arguments.front()).isImplicitlyConvertibleTo(*TypeProvider::stringMemory()),"");
Whiskers templ(R"({
let <pos> := <allocateTemporary>()
mstore(<pos>, <hash>)
let <end> := <encode>(add(<pos>, 4) <argumentVars>)
revert(<pos>, sub(<end>, <pos>))
})");
templ("pos", m_context.newYulVariable());
templ("end", m_context.newYulVariable());
templ(
"hash",
(u256(util::FixedHash<4>::Arith(util::FixedHash<4>(util::keccak256("Error(string)")))) << (256 - 32)).str()
);
templ("allocateTemporary", m_utils.allocationTemporaryMemoryFunction());
templ(
"argumentVars",
(type(*arguments.front()).sizeOnStack() > 0 ? ", " : "") +
IRVariable{*arguments.front()}.commaSeparatedList()
);
templ("encode", m_context.abiFunctions().tupleEncoder(
{&type(*arguments.front())},
{TypeProvider::stringMemory()}
));
m_code << templ.render();
}
}
break;
}

View File

@ -9,6 +9,7 @@ contract C {
}
}
// ====
// compileViaYul: also
// EVMVersion: >=byzantium
// revertStrings: debug
// ----

View File

@ -18,6 +18,7 @@ contract C {
}
}
// ====
// compileViaYul: also
// EVMVersion: >=byzantium
// revertStrings: debug
// ----

View File

@ -14,11 +14,12 @@ contract C {
}
}
// ====
// allowNonExistingFunctions: true
// compileViaYul: also
// EVMVersion: >homestead
// allowNonExistingFunctions: true
// ----
// _() -> FAILURE
// e() -> FAILURE, hex"08c379a0", 0x20, 19, "Transaction failed."
// f(bool): false -> FAILURE, hex"08c379a0", 0x20, 0
// g(bool): false -> FAILURE, hex"08c379a0", 0x20, 15, "Value is false."
// h() -> FAILURE
// h() -> FAILURE