Introduce address(...).code

This commit is contained in:
Alex Beregszaszi
2020-12-11 03:00:30 +00:00
parent 4b410b8731
commit 7b347b9ec2
10 changed files with 90 additions and 2 deletions
+1 -1
View File
@@ -356,7 +356,7 @@ void ViewPureChecker::endVisit(MemberAccess const& _memberAccess)
switch (_memberAccess.expression().annotation().type->category())
{
case Type::Category::Address:
if (member == "balance" || member == "codehash")
if (member == "balance" || member == "code" || member == "codehash")
mutability = StateMutability::View;
break;
case Type::Category::Magic:
+1
View File
@@ -456,6 +456,7 @@ MemberList::MemberMap AddressType::nativeMembers(ASTNode const*) const
{
MemberList::MemberMap members = {
{"balance", TypeProvider::uint256()},
{"code", TypeProvider::array(DataLocation::Memory)},
{"codehash", TypeProvider::fixedBytes(32)},
{"call", TypeProvider::function(strings{"bytes memory"}, strings{"bool", "bytes memory"}, FunctionType::Kind::BareCall, false, StateMutability::Payable)},
{"callcode", TypeProvider::function(strings{"bytes memory"}, strings{"bool", "bytes memory"}, FunctionType::Kind::BareCallCode, false, StateMutability::Payable)},
@@ -1508,6 +1508,39 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
);
m_context << Instruction::BALANCE;
}
else if (member == "code")
{
// Stack: <address>
utils().convertType(
*_memberAccess.expression().annotation().type,
*TypeProvider::address(),
true
);
m_context << Instruction::DUP1 << Instruction::EXTCODESIZE;
// Stack post: <address> <size>
m_context << Instruction::DUP1;
// Account for the size field of `bytes memory`
m_context << u256(32) << Instruction::ADD;
utils().allocateMemory();
// Stack post: <address> <size> <mem_offset>
// Store size at mem_offset
m_context << Instruction::DUP2 << Instruction::DUP2 << Instruction::MSTORE;
m_context << u256(0) << Instruction::SWAP1 << Instruction::DUP1;
// Stack post: <address> <size> 0 <mem_offset> <mem_offset>
m_context << u256(32) << Instruction::ADD << Instruction::SWAP1;
// Stack post: <address> <size> 0 <mem_offset_adjusted> <mem_offset>
m_context << Instruction::SWAP4;
// Stack post: <mem_offset> <size> 0 <mem_offset_adjusted> <address>
m_context << Instruction::EXTCODECOPY;
// Stack post: <mem_offset>
}
else if (member == "codehash")
{
utils().convertType(