This commit is contained in:
Daniel Kirchner 2020-03-12 17:32:10 +01:00 committed by chriseth
parent 04d8ad2ae1
commit e255c15227
8 changed files with 229 additions and 38 deletions

View File

@ -61,6 +61,8 @@ BOOST_AUTO_TEST_CASE(all_assembly_items)
Assembly _subAsm;
auto sub_asm = make_shared<CharStream>("lorem ipsum", "sub.asm");
_subAsm.setSourceLocation({6, 8, sub_asm});
// PushImmutable
_subAsm.appendImmutable("someImmutable");
_subAsm.append(Instruction::INVALID);
shared_ptr<Assembly> _subAsmPtr = make_shared<Assembly>(_subAsm);
@ -86,6 +88,11 @@ BOOST_AUTO_TEST_CASE(all_assembly_items)
_assembly.pushSubroutineOffset(size_t(sub.data()));
// PushDeployTimeAddress
_assembly.append(PushDeployTimeAddress);
// AssignImmutable.
// Note that since there is no reference to "someOtherImmutable", this will compile to a simple POP in the hex output.
_assembly.appendImmutableAssignment("someOtherImmutable");
_assembly.append(u256(2));
_assembly.appendImmutableAssignment("someImmutable");
// Operation
_assembly.append(Instruction::STOP);
_assembly.appendAuxiliaryDataToEnd(bytes{0x42, 0x66});
@ -95,8 +102,11 @@ BOOST_AUTO_TEST_CASE(all_assembly_items)
BOOST_CHECK_EQUAL(
_assembly.assemble().toHex(),
"5b6001600220604673__$bf005014d9d0f534b8fcb268bd84c491a2$__"
"600056603e6001603d73000000000000000000000000000000000000000000fe"
"5b6001600220606f73__$bf005014d9d0f534b8fcb268bd84c491a2$__"
"60005660676022604573000000000000000000000000000000000000000050"
"60028060015250"
"00fe"
"7f0000000000000000000000000000000000000000000000000000000000000000"
"fe010203044266eeaa"
);
BOOST_CHECK_EQUAL(
@ -111,12 +121,16 @@ BOOST_AUTO_TEST_CASE(all_assembly_items)
" dataSize(sub_0)\n"
" dataOffset(sub_0)\n"
" deployTimeAddress()\n"
" assignImmutable(\"0xc3978657661c4d8e32e3d5f42597c009f0d3859e9f9d0d94325268f9799e2bfb\")\n"
" 0x02\n"
" assignImmutable(\"0x26f2c0195e9d408feff3abd77d83f2971f3c9a18d1e8a9437c7835ae4211fc9f\")\n"
" stop\n"
"stop\n"
"data_a6885b3731702da62e8e4a8f584ac46a7f6822f4e2ba50fba902f67b1588d23b 01020304\n"
"\n"
"sub_0: assembly {\n"
" /* \"sub.asm\":6:8 */\n"
" immutable(\"0x26f2c0195e9d408feff3abd77d83f2971f3c9a18d1e8a9437c7835ae4211fc9f\")\n"
" invalid\n"
"}\n"
"\n"
@ -138,9 +152,104 @@ BOOST_AUTO_TEST_CASE(all_assembly_items)
"{\"begin\":1,\"end\":3,\"name\":\"PUSH #[$]\",\"source\":0,\"value\":\"0000000000000000000000000000000000000000000000000000000000000000\"},"
"{\"begin\":1,\"end\":3,\"name\":\"PUSH [$]\",\"source\":0,\"value\":\"0000000000000000000000000000000000000000000000000000000000000000\"},"
"{\"begin\":1,\"end\":3,\"name\":\"PUSHDEPLOYADDRESS\",\"source\":0},"
"{\"begin\":1,\"end\":3,\"name\":\"ASSIGNIMMUTABLE\",\"source\":0,\"value\":\"someOtherImmutable\"},"
"{\"begin\":1,\"end\":3,\"name\":\"PUSH\",\"source\":0,\"value\":\"2\"},"
"{\"begin\":1,\"end\":3,\"name\":\"ASSIGNIMMUTABLE\",\"source\":0,\"value\":\"someImmutable\"},"
"{\"begin\":1,\"end\":3,\"name\":\"STOP\",\"source\":0}"
"],\".data\":{\"0\":{\".code\":[{\"begin\":6,\"end\":8,\"name\":\"INVALID\",\"source\":1}]},"
"\"A6885B3731702DA62E8E4A8F584AC46A7F6822F4E2BA50FBA902F67B1588D23B\":\"01020304\"}}"
"],\".data\":{\"0\":{\".code\":["
"{\"begin\":6,\"end\":8,\"name\":\"PUSHIMMUTABLE\",\"source\":1,\"value\":\"someImmutable\"},"
"{\"begin\":6,\"end\":8,\"name\":\"INVALID\",\"source\":1}"
"]},\"A6885B3731702DA62E8E4A8F584AC46A7F6822F4E2BA50FBA902F67B1588D23B\":\"01020304\"}}"
);
}
BOOST_AUTO_TEST_CASE(immutable)
{
map<string, unsigned> indices = {
{ "root.asm", 0 },
{ "sub.asm", 1 }
};
Assembly _assembly;
auto root_asm = make_shared<CharStream>("lorem ipsum", "root.asm");
_assembly.setSourceLocation({1, 3, root_asm});
Assembly _subAsm;
auto sub_asm = make_shared<CharStream>("lorem ipsum", "sub.asm");
_subAsm.setSourceLocation({6, 8, sub_asm});
_subAsm.appendImmutable("someImmutable");
_subAsm.appendImmutable("someOtherImmutable");
_subAsm.appendImmutable("someImmutable");
shared_ptr<Assembly> _subAsmPtr = make_shared<Assembly>(_subAsm);
_assembly.append(u256(42));
_assembly.appendImmutableAssignment("someImmutable");
_assembly.append(u256(23));
_assembly.appendImmutableAssignment("someOtherImmutable");
auto sub = _assembly.appendSubroutine(_subAsmPtr);
_assembly.pushSubroutineOffset(size_t(sub.data()));
checkCompilation(_assembly);
BOOST_CHECK_EQUAL(
_assembly.assemble().toHex(),
// root.asm
// assign "someImmutable"
"602a" // PUSH1 42 - value for someImmutable
"80" // DUP1
"6001" // PUSH1 1 - offset of first someImmutable in sub_0
"52" // MSTORE
"80" // DUP1
"6043" // PUSH1 67 - offset of second someImmutable in sub_0
"52" // MSTORE
"50" // POP
// assign "someOtherImmutable"
"6017" // PUSH1 23 - value for someOtherImmutable
"80" // DUP1
"6022" // PUSH1 34 - offset of someOtherImmutable in sub_0
"52" // MSTORE
"50" // POP
"6063" // PUSH1 0x63 - dataSize(sub_0)
"6017" // PUSH1 0x17 - dataOffset(sub_0)
"fe" // INVALID
// end of root.asm
// sub.asm
"7f0000000000000000000000000000000000000000000000000000000000000000" // PUSHIMMUTABLE someImmutable - data at offset 1
"7f0000000000000000000000000000000000000000000000000000000000000000" // PUSHIMMUTABLE someOtherImmutable - data at offset 34
"7f0000000000000000000000000000000000000000000000000000000000000000" // PUSHIMMUTABLE someImmutable - data at offset 67
);
BOOST_CHECK_EQUAL(
_assembly.assemblyString(),
" /* \"root.asm\":1:3 */\n"
" 0x2a\n"
" assignImmutable(\"0x26f2c0195e9d408feff3abd77d83f2971f3c9a18d1e8a9437c7835ae4211fc9f\")\n"
" 0x17\n"
" assignImmutable(\"0xc3978657661c4d8e32e3d5f42597c009f0d3859e9f9d0d94325268f9799e2bfb\")\n"
" dataSize(sub_0)\n"
" dataOffset(sub_0)\n"
"stop\n"
"\n"
"sub_0: assembly {\n"
" /* \"sub.asm\":6:8 */\n"
" immutable(\"0x26f2c0195e9d408feff3abd77d83f2971f3c9a18d1e8a9437c7835ae4211fc9f\")\n"
" immutable(\"0xc3978657661c4d8e32e3d5f42597c009f0d3859e9f9d0d94325268f9799e2bfb\")\n"
" immutable(\"0x26f2c0195e9d408feff3abd77d83f2971f3c9a18d1e8a9437c7835ae4211fc9f\")\n"
"}\n"
);
BOOST_CHECK_EQUAL(
util::jsonCompactPrint(_assembly.assemblyJSON(indices)),
"{\".code\":["
"{\"begin\":1,\"end\":3,\"name\":\"PUSH\",\"source\":0,\"value\":\"2A\"},"
"{\"begin\":1,\"end\":3,\"name\":\"ASSIGNIMMUTABLE\",\"source\":0,\"value\":\"someImmutable\"},"
"{\"begin\":1,\"end\":3,\"name\":\"PUSH\",\"source\":0,\"value\":\"17\"},"
"{\"begin\":1,\"end\":3,\"name\":\"ASSIGNIMMUTABLE\",\"source\":0,\"value\":\"someOtherImmutable\"},"
"{\"begin\":1,\"end\":3,\"name\":\"PUSH #[$]\",\"source\":0,\"value\":\"0000000000000000000000000000000000000000000000000000000000000000\"},"
"{\"begin\":1,\"end\":3,\"name\":\"PUSH [$]\",\"source\":0,\"value\":\"0000000000000000000000000000000000000000000000000000000000000000\"}"
"],\".data\":{\"0\":{\".code\":["
"{\"begin\":6,\"end\":8,\"name\":\"PUSHIMMUTABLE\",\"source\":1,\"value\":\"someImmutable\"},"
"{\"begin\":6,\"end\":8,\"name\":\"PUSHIMMUTABLE\",\"source\":1,\"value\":\"someOtherImmutable\"},"
"{\"begin\":6,\"end\":8,\"name\":\"PUSHIMMUTABLE\",\"source\":1,\"value\":\"someImmutable\"}"
"]}}}"
);
}

View File

@ -1,20 +1,20 @@
contract D {
function f() external view returns (uint256) {
return 42;
}
function f() external view returns (uint256) {
return 42;
}
}
contract C {
D d;
function() external view returns(uint256) immutable z;
constructor() public {
d = new D();
z = d.f;
}
function f() public view returns (uint256) {
D d;
function() external view returns(uint256) immutable z;
constructor() public {
d = new D();
z = d.f;
}
function f() public view returns (uint256) {
assert(z.address == address(d));
assert(z.selector == D.f.selector);
return z();
}
return z();
}
}
// ----
// f() -> 42

View File

@ -0,0 +1,30 @@
contract A {
uint8 immutable a;
constructor() public {
a = 4;
}
}
contract B is A {
uint8 immutable b;
constructor() public {
b = 3;
}
}
contract C is A {
uint8 immutable c;
constructor() public {
c = 2;
}
}
contract D is B, C {
uint8 immutable d;
constructor() public {
d = 1;
}
function f() public view returns (uint256, uint256, uint, uint) {
return (a, b, c, d);
}
}
// ----
// f() -> 4, 3, 2, 1

View File

@ -0,0 +1,15 @@
contract C {
function() internal view returns(uint256) immutable z;
constructor() public {
z = f;
}
function f() public view returns (uint256) {
return 7;
}
function callZ() public view returns (uint) {
return z();
}
}
// ----
// f() -> 7
// callZ() -> 7

View File

@ -0,0 +1,31 @@
contract A {
uint immutable a;
constructor() public {
a = 7;
}
function f() public view returns (uint) { return a; }
}
contract B {
uint immutable a;
constructor() public {
a = 5;
}
function f() public view returns (uint) { return a; }
}
contract C {
uint immutable a;
uint public x;
uint public y;
constructor() public {
a = 3;
x = (new A()).f();
y = (new B()).f();
}
function f() public returns (uint256, uint, uint) {
return (a, (new A()).f(), (new B()).f());
}
}
// ----
// f() -> 3, 7, 5
// x() -> 7
// y() -> 5

View File

@ -1,13 +0,0 @@
contract C {
uint256 immutable x;
uint256 immutable y;
constructor() public {
x = 42;
y = x;
}
function f() public view returns (uint256, uint256) {
return (x+x,y);
}
}
// ----
// f() -> 84, 42

View File

@ -1,13 +1,13 @@
contract C {
uint256 immutable x;
uint256 immutable y;
constructor() public {
x = 42;
y = 23;
}
function f() public view returns (uint256, uint256) {
return (x+x,y);
}
uint256 immutable x;
uint256 immutable y;
constructor() public {
x = 42;
y = 23;
}
function f() public view returns (uint256, uint256) {
return (x+x,y);
}
}
// ----
// f() -> 84, 23

View File

@ -0,0 +1,19 @@
contract C {
uint256 immutable x;
uint256 immutable y;
mapping(uint => uint) public m;
constructor(uint _a) public {
x = 42;
y = 23;
m[_a] = 7;
new uint[](4);
}
function f() public view returns (uint256, uint256) {
return (x+x,y);
}
}
// ----
// constructor(): 3 ->
// f() -> 84, 23
// m(uint256): 3 -> 7