Merge pull request #8867 from ethereum/solYulCreationCode

[Sol->Yul] Implement .creationCode.
This commit is contained in:
Daniel Kirchner 2020-05-11 23:04:08 +02:00 committed by GitHub
commit 34e4fce46b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 44 additions and 1 deletions

View File

@ -1304,7 +1304,20 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
solAssert(false, "Blockhash has been removed."); solAssert(false, "Blockhash has been removed.");
else if (member == "creationCode" || member == "runtimeCode") else if (member == "creationCode" || member == "runtimeCode")
{ {
solUnimplementedAssert(false, ""); solUnimplementedAssert(member != "runtimeCode", "");
TypePointer arg = dynamic_cast<MagicType const&>(*_memberAccess.expression().annotation().type).typeArgument();
ContractDefinition const& contract = dynamic_cast<ContractType const&>(*arg).contractDefinition();
m_context.subObjectsCreated().insert(&contract);
m_code << Whiskers(R"(
let <size> := datasize("<objectName>")
let <result> := <allocationFunction>(add(<size>, 32))
mstore(<result>, <size>)
datacopy(add(<result>, 32), dataoffset("<objectName>"), <size>)
)")
("allocationFunction", m_utils.allocationFunction())
("size", m_context.newYulVariable())
("objectName", m_context.creationObjectName(contract))
("result", IRVariable(_memberAccess).commaSeparatedList()).render();
} }
else if (member == "name") else if (member == "name")
{ {

View File

@ -29,6 +29,7 @@ contract C {
} }
// ==== // ====
// EVMVersion: >homestead // EVMVersion: >homestead
// compileViaYul: also
// ---- // ----
// f(uint256), 2000 ether: 0 -> true // f(uint256), 2000 ether: 0 -> true
// f(uint256), 2000 ether: 100 -> false // f(uint256), 2000 ether: 100 -> false

View File

@ -22,5 +22,7 @@ contract C {
} }
} }
// ====
// compileViaYul: also
// ---- // ----
// test() -> 7 // test() -> 7

View File

@ -0,0 +1,27 @@
contract D {
uint256 x;
constructor() public {
x = 7;
}
function f() public view returns (uint256) {
return x;
}
}
contract C {
function test() public returns (uint256) {
D d = new D();
bytes32 hash;
assembly { hash := extcodehash(d) }
assert(hash == keccak256(type(D).runtimeCode));
return 42;
}
}
// ====
// EVMVersion: >=constantinople
// ----
// test() -> 42