Add `.address and .selector` in inside assembly for external function pointers

This commit is contained in:
Marenz
2021-10-04 18:05:57 +02:00
committed by Mathias Baumann
parent 529087be6c
commit 98dd78362e
16 changed files with 211 additions and 5 deletions
@@ -0,0 +1,19 @@
contract C {
function testFunction() external {}
function testYul() public returns (address adr) {
function() external fp = this.testFunction;
assembly {
adr := fp.address
}
}
function testSol() public returns (address) {
return this.testFunction.address;
}
}
// ====
// compileViaYul: also
// ----
// testYul() -> 0x0fdd67305928fcac8d213d1e47bfa6165cd0b87b
// testSol() -> 0x0fdd67305928fcac8d213d1e47bfa6165cd0b87b
@@ -0,0 +1,18 @@
contract C {
function testFunction() external {}
function testYul(address newAddress) view public returns (address adr) {
function() external fp = this.testFunction;
assembly {
fp.address := newAddress
}
return fp.address;
}
}
// ====
// compileViaYul: also
// ----
// testYul(address): 0x1234567890 -> 0x1234567890
// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7
@@ -0,0 +1,23 @@
contract C {
function testFunction() external {}
function testYul() public returns (uint32) {
function() external fp = this.testFunction;
uint selectorValue = 0;
assembly {
selectorValue := fp.selector
}
// Value is right-aligned, we shift it so it can be compared
return uint32(bytes4(bytes32(selectorValue << (256 - 32))));
}
function testSol() public returns (uint32) {
return uint32(this.testFunction.selector);
}
}
// ====
// compileViaYul: also
// ----
// testYul() -> 0xe16b4a9b
// testSol() -> 0xe16b4a9b
@@ -0,0 +1,18 @@
contract C {
function testFunction() external {}
function testYul(uint32 newSelector) view public returns (uint32) {
function() external fp = this.testFunction;
assembly {
fp.selector := newSelector
}
return uint32(fp.selector);
}
}
// ====
// compileViaYul: also
// ----
// testYul(uint32): 0x12345678 -> 0x12345678
// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00
@@ -0,0 +1,15 @@
contract C {
function testFunction() external {}
function testYul() public {
function() external fp = this.testFunction;
uint myOffset;
assembly {
myOffset := fp.offset
}
}
}
// ----
// TypeError 9272: (173-182): Variables of type function pointer only support ".selector" and ".address".
@@ -0,0 +1,18 @@
contract C {
function testFunction() internal {}
function testYul() public returns (address adr) {
function() internal fp = testFunction;
uint selectorValue = 0;
assembly {
adr := fp.address
}
}
function testSol() public returns (address) {
return testFunction.address;
}
}
// ----
// TypeError 8533: (193-203): Only Variables of type external function pointer support ".selector" and ".address".
// TypeError 9582: (267-287): Member "address" not found or not visible after argument-dependent lookup in function ().
@@ -0,0 +1,20 @@
contract C {
function testFunction() internal {}
function testYul() public returns (uint32) {
function() internal fp = testFunction;
uint selectorValue = 0;
assembly {
selectorValue := fp.selector
}
return uint32(bytes4(bytes32(selectorValue)));
}
function testSol() public returns (uint32) {
return uint32(testFunction.selector);
}
}
// ----
// TypeError 8533: (198-209): Only Variables of type external function pointer support ".selector" and ".address".
// TypeError 9582: (329-350): Member "selector" not found or not visible after argument-dependent lookup in function ().