mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Implement IR shortcut for <address>.code.length
This commit is contained in:
parent
d6d880dc53
commit
526ceec152
@ -1554,6 +1554,28 @@ void IRGeneratorForStatements::endVisit(FunctionCallOptions const& _options)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IRGeneratorForStatements::visit(MemberAccess const& _memberAccess)
|
||||||
|
{
|
||||||
|
// A shortcut for <address>.code.length. We skip visiting <address>.code and directly visit
|
||||||
|
// <address>. The actual code is generated in endVisit.
|
||||||
|
if (
|
||||||
|
auto innerExpression = dynamic_cast<MemberAccess const*>(&_memberAccess.expression());
|
||||||
|
_memberAccess.memberName() == "length" &&
|
||||||
|
innerExpression &&
|
||||||
|
innerExpression->memberName() == "code" &&
|
||||||
|
innerExpression->expression().annotation().type->category() == Type::Category::Address
|
||||||
|
)
|
||||||
|
{
|
||||||
|
solAssert(innerExpression->annotation().type->category() == Type::Category::Array, "");
|
||||||
|
// Skip visiting <address>.code
|
||||||
|
innerExpression->expression().accept(*this);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
|
void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
|
||||||
{
|
{
|
||||||
setLocation(_memberAccess);
|
setLocation(_memberAccess);
|
||||||
@ -1846,13 +1868,26 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
|
|||||||
case Type::Category::Array:
|
case Type::Category::Array:
|
||||||
{
|
{
|
||||||
auto const& type = dynamic_cast<ArrayType const&>(*_memberAccess.expression().annotation().type);
|
auto const& type = dynamic_cast<ArrayType const&>(*_memberAccess.expression().annotation().type);
|
||||||
|
|
||||||
if (member == "length")
|
if (member == "length")
|
||||||
|
{
|
||||||
|
// shortcut for <address>.code.length
|
||||||
|
if (
|
||||||
|
auto innerExpression = dynamic_cast<MemberAccess const*>(&_memberAccess.expression());
|
||||||
|
innerExpression &&
|
||||||
|
innerExpression->memberName() == "code" &&
|
||||||
|
innerExpression->expression().annotation().type->category() == Type::Category::Address
|
||||||
|
)
|
||||||
|
define(_memberAccess) <<
|
||||||
|
"extcodesize(" <<
|
||||||
|
expressionAsType(innerExpression->expression(), *TypeProvider::address()) <<
|
||||||
|
")\n";
|
||||||
|
else
|
||||||
define(_memberAccess) <<
|
define(_memberAccess) <<
|
||||||
m_utils.arrayLengthFunction(type) <<
|
m_utils.arrayLengthFunction(type) <<
|
||||||
"(" <<
|
"(" <<
|
||||||
IRVariable(_memberAccess.expression()).commaSeparatedList() <<
|
IRVariable(_memberAccess.expression()).commaSeparatedList() <<
|
||||||
")\n";
|
")\n";
|
||||||
|
}
|
||||||
else if (member == "pop" || member == "push")
|
else if (member == "pop" || member == "push")
|
||||||
{
|
{
|
||||||
solAssert(type.location() == DataLocation::Storage, "");
|
solAssert(type.location() == DataLocation::Storage, "");
|
||||||
|
@ -87,6 +87,7 @@ public:
|
|||||||
bool visit(BinaryOperation const& _binOp) override;
|
bool visit(BinaryOperation const& _binOp) override;
|
||||||
void endVisit(FunctionCall const& _funCall) override;
|
void endVisit(FunctionCall const& _funCall) override;
|
||||||
void endVisit(FunctionCallOptions const& _funCallOptions) override;
|
void endVisit(FunctionCallOptions const& _funCallOptions) override;
|
||||||
|
bool visit(MemberAccess const& _memberAccess) override;
|
||||||
void endVisit(MemberAccess const& _memberAccess) override;
|
void endVisit(MemberAccess const& _memberAccess) override;
|
||||||
bool visit(InlineAssembly const& _inlineAsm) override;
|
bool visit(InlineAssembly const& _inlineAsm) override;
|
||||||
void endVisit(IndexAccess const& _indexAccess) override;
|
void endVisit(IndexAccess const& _indexAccess) override;
|
||||||
|
Loading…
Reference in New Issue
Block a user