Merge pull request #7539 from ethereum/selfbalance

Use selfbalance for ``address(this).balance``.
This commit is contained in:
chriseth 2019-10-16 14:45:23 +02:00 committed by GitHub
commit 61d6c12b71
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 0 deletions

View File

@ -4,6 +4,7 @@ Language Features:
Compiler Features:
* Code Generator: Use SELFBALANCE for ``address(this).balance`` if using Istanbul EVM
Bugfixes:

View File

@ -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())

View File

@ -617,6 +617,25 @@ BOOST_AUTO_TEST_CASE(gas_left)
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
BOOST_AUTO_TEST_CASE(selfbalance)
{
char const* sourceCode = R"(
contract test {
function f() returns (uint) {
return address(this).balance;
}
}
)";
bytes code = compileFirstExpression(sourceCode, {}, {});
if (dev::test::Options::get().evmVersion() == EVMVersion::istanbul())
{
bytes expectation({uint8_t(Instruction::SELFBALANCE)});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
}
BOOST_AUTO_TEST_SUITE_END()
}