Implement address(...).code in the IR

This commit is contained in:
chriseth 2020-12-10 14:37:26 +01:00 committed by Alex Beregszaszi
parent 7b347b9ec2
commit baaf7c0db8
5 changed files with 30 additions and 3 deletions

View File

@ -4055,3 +4055,21 @@ string YulUtilFunctions::copyConstructorArgumentsToMemoryFunction(
.render(); .render();
}); });
} }
string YulUtilFunctions::externalCodeFunction()
{
string functionName = "external_code_at";
return m_functionCollector.createFunction(functionName, [&]() {
return util::Whiskers(R"(
function <functionName>(addr) -> mpos {
let length := extcodesize(addr)
mpos := <allocateArray>(length)
extcodecopy(addr, add(mpos, 0x20), 0, length)
}
)")
("functionName", functionName)
("allocateArray", allocateMemoryArrayFunction(*TypeProvider::bytesMemory()))
.render();
});
}

View File

@ -460,6 +460,11 @@ public:
std::string const& _creationObjectName std::string const& _creationObjectName
); );
/// @returns the name of a function that copies code from a given address to a newly
/// allocated byte array in memory.
/// Signature: (address) -> mpos
std::string externalCodeFunction();
private: private:
/// Special case of conversion functions - handles all array conversions. /// Special case of conversion functions - handles all array conversions.
std::string arrayConversionFunction(ArrayType const& _from, ArrayType const& _to); std::string arrayConversionFunction(ArrayType const& _from, ArrayType const& _to);

View File

@ -1622,6 +1622,12 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
"balance(" << "balance(" <<
expressionAsType(_memberAccess.expression(), *TypeProvider::address()) << expressionAsType(_memberAccess.expression(), *TypeProvider::address()) <<
")\n"; ")\n";
else if (member == "code")
define(_memberAccess) <<
m_utils.externalCodeFunction() <<
"(" <<
expressionAsType(_memberAccess.expression(), *TypeProvider::address()) <<
")\n";
else if (member == "codehash") else if (member == "codehash")
define(_memberAccess) << define(_memberAccess) <<
"extcodehash(" << "extcodehash(" <<

View File

@ -12,8 +12,6 @@ contract C {
function g() public view returns (uint) { return address(0).code.length; } function g() public view returns (uint) { return address(0).code.length; }
function h() public view returns (uint) { return address(1).code.length; } function h() public view returns (uint) { return address(1).code.length; }
} }
// ====
// compileViaYul: false
// ---- // ----
// constructor() -> // constructor() ->
// initCode() -> 0x20, 0 // initCode() -> 0x20, 0

View File

@ -13,7 +13,7 @@ contract C {
function g() public returns (uint) { return address(new A()).code.length; } function g() public returns (uint) { return address(new A()).code.length; }
} }
// ==== // ====
// compileViaYul: false // compileViaYul: also
// ---- // ----
// f() -> 0x20, 0x20, 0x48aa5566000000 // f() -> 0x20, 0x20, 0x48aa5566000000
// g() -> 0x20 // g() -> 0x20