Use selfbalance for `address(this).balance`.

This commit is contained in:
chriseth
2019-10-16 14:25:56 +02:00
parent 9ec8bcda4f
commit ebfe7391ff
3 changed files with 42 additions and 0 deletions
@@ -1229,6 +1229,28 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
utils().leftShiftNumberOnStack(224);
return false;
}
// Another special case for `address(this).balance`. Post-Istanbul, we can use the selfbalance
// opcode.
if (
m_context.evmVersion().hasSelfBalance() &&
member == "balance" &&
_memberAccess.expression().annotation().type->category() == Type::Category::Address
)
if (FunctionCall const* funCall = dynamic_cast<FunctionCall const*>(&_memberAccess.expression()))
if (auto const* addr = dynamic_cast<ElementaryTypeNameExpression const*>(&funCall->expression()))
if (
addr->typeName().token() == Token::Address &&
funCall->arguments().size() == 1
)
if (auto arg = dynamic_cast<Identifier const*>( funCall->arguments().front().get()))
if (
arg->name() == "this" &&
dynamic_cast<MagicVariableDeclaration const*>(arg->annotation().referencedDeclaration)
)
{
m_context << Instruction::SELFBALANCE;
return false;
}
_memberAccess.expression().accept(*this);
switch (_memberAccess.expression().annotation().type->category())