Allocate memory for deployed code.

This commit is contained in:
Daniel Kirchner 2021-03-15 17:57:42 +01:00
parent 86e1e4a2dd
commit e9180481e9
17 changed files with 35 additions and 46 deletions

View File

@ -804,31 +804,27 @@ void IRGenerator::generateImplicitConstructors(ContractDefinition const& _contra
string IRGenerator::deployCode(ContractDefinition const& _contract)
{
Whiskers t(R"X(
<#loadImmutables>
let <var> := mload(<memoryOffset>)
</loadImmutables>
let codeOffset := <allocate>(datasize("<object>"))
codecopy(codeOffset, dataoffset("<object>"), datasize("<object>"))
codecopy(0, dataoffset("<object>"), datasize("<object>"))
<#immutables>
setimmutable(codeOffset, "<name>", <value>)
</immutables>
<#storeImmutables>
setimmutable(0, "<immutableName>", <var>)
</storeImmutables>
return(0, datasize("<object>"))
return(codeOffset, datasize("<object>"))
)X");
t("object", IRNames::deployedObject(_contract));
t("allocate", m_utils.allocationFunction());
vector<map<string, string>> loadImmutables;
vector<map<string, string>> storeImmutables;
vector<map<string, string>> immutables;
if (_contract.isLibrary())
{
solAssert(ContractType(_contract).immutableVariables().empty(), "");
storeImmutables.emplace_back(map<string, string>{
{"var"s, "address()"},
{"immutableName"s, IRNames::libraryAddressImmutable()}
immutables.emplace_back(map<string, string>{
{"name"s, IRNames::libraryAddressImmutable()},
{"value"s, "address()"}
});
}
else
for (VariableDeclaration const* immutable: ContractType(_contract).immutableVariables())
@ -836,19 +832,12 @@ string IRGenerator::deployCode(ContractDefinition const& _contract)
solUnimplementedAssert(immutable->type()->isValueType(), "");
solUnimplementedAssert(immutable->type()->sizeOnStack() == 1, "");
string yulVar = m_context.newYulVariable();
loadImmutables.emplace_back(map<string, string>{
{"var"s, yulVar},
{"memoryOffset"s, to_string(m_context.immutableMemoryOffset(*immutable))}
});
storeImmutables.emplace_back(map<string, string>{
{"var"s, yulVar},
{"immutableName"s, to_string(immutable->id())}
immutables.emplace_back(map<string, string>{
{"name"s, to_string(immutable->id())},
{"value"s, "mload("s + to_string(m_context.immutableMemoryOffset(*immutable)) + ")"s}
});
}
t("loadImmutables", std::move(loadImmutables));
// reverse order to ease stack strain
reverse(storeImmutables.begin(), storeImmutables.end());
t("storeImmutables", std::move(storeImmutables));
t("immutables", std::move(immutables));
return t.render();
}

View File

@ -30,6 +30,6 @@ contract C is B {
// compileViaYul: also
// ----
// test() -> 77
// gas irOptimized: 139834
// gas irOptimized: 139931
// gas legacy: 156573
// gas legacyOptimized: 112983

View File

@ -21,6 +21,6 @@ contract B {
// compileViaYul: also
// ----
// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004
// gas irOptimized: 179491
// gas irOptimized: 179582
// gas legacy: 264410
// gas legacyOptimized: 134899

View File

@ -45,6 +45,6 @@ contract C {
// compileViaYul: also
// ----
// test() -> 5, 6, 7
// gas irOptimized: 360048
// gas irOptimized: 360145
// gas legacy: 500424
// gas legacyOptimized: 307615

View File

@ -26,6 +26,6 @@ contract Main {
// compileViaYul: also
// ----
// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1
// gas irOptimized: 117287
// gas irOptimized: 117459
// gas legacy: 127152
// gas legacyOptimized: 113679

View File

@ -26,6 +26,6 @@ contract Creator {
// compileViaYul: also
// ----
// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8
// gas irOptimized: 472538
// gas irOptimized: 472752
// gas legacy: 570900
// gas legacyOptimized: 436164

View File

@ -26,6 +26,6 @@ contract Creator {
// compileViaYul: also
// ----
// f(uint256,bytes): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> 7, "h"
// gas irOptimized: 335246
// gas irOptimized: 335413
// gas legacy: 414850
// gas legacyOptimized: 290276

View File

@ -19,6 +19,6 @@ contract C {
// compileViaYul: also
// ----
// f(), 2000 ether -> true
// gas irOptimized: 123853
// gas irOptimized: 124114
// gas legacy: 123226
// gas legacyOptimized: 123092

View File

@ -28,6 +28,6 @@ contract C {
// compileViaYul: also
// ----
// t() -> 9
// gas irOptimized: 124896
// gas irOptimized: 124993
// gas legacy: 161097
// gas legacyOptimized: 111516

View File

@ -29,7 +29,7 @@ contract C {
// compileViaYul: also
// ----
// f() -> 3, 7, 5
// gas irOptimized: 133517
// gas irOptimized: 133717
// gas legacy: 153990
// gas legacyOptimized: 127822
// x() -> 7

View File

@ -23,8 +23,8 @@ contract D {
// compileViaYul: also
// ----
// f() -> 1
// gas irOptimized: 111246
// gas irOptimized: 111343
// gas legacy: 114412
// g() -> 5
// gas irOptimized: 111379
// gas irOptimized: 111476
// gas legacy: 114872

View File

@ -25,5 +25,5 @@ contract B {
// compileViaYul: also
// ----
// g() -> 42
// gas irOptimized: 107179
// gas irOptimized: 107276
// gas legacy: 117797

View File

@ -25,6 +25,6 @@ contract B {
// compileViaYul: also
// ----
// g() -> 42
// gas irOptimized: 127021
// gas irOptimized: 127118
// gas legacy: 180597
// gas legacyOptimized: 116153

View File

@ -37,10 +37,10 @@ contract C {
// compileViaYul: also
// ----
// convertParent() -> 1
// gas irOptimized: 122356
// gas irOptimized: 122453
// convertSubA() -> 1, 2
// gas irOptimized: 124555
// gas irOptimized: 124652
// gas legacy: 101703
// convertSubB() -> 1, 3
// gas irOptimized: 124489
// gas irOptimized: 124586
// gas legacy: 101637

View File

@ -22,6 +22,6 @@ contract A {
// ----
// different_salt() -> true
// same_salt() -> true
// gas irOptimized: 98439083
// gas irOptimized: 98439085
// gas legacy: 98439116
// gas legacyOptimized: 98438982

View File

@ -22,6 +22,6 @@ contract A {
// compileViaYul: also
// ----
// f(), 10 ether -> 3007, 3008, 3009
// gas irOptimized: 338630
// gas irOptimized: 339266
// gas legacy: 422027
// gas legacyOptimized: 287256

View File

@ -38,10 +38,10 @@ contract D {
// f() -> 0x1 # This should work, next should throw #
// gas legacy: 102944
// fview() -> FAILURE
// gas irOptimized: 98438674
// gas irOptimized: 98438675
// gas legacy: 98438822
// gas legacyOptimized: 98438615
// fpure() -> FAILURE
// gas irOptimized: 98438674
// gas irOptimized: 98438675
// gas legacy: 98438822
// gas legacyOptimized: 98438616