Closed mrsmkl closed 3 years ago
Hmm, the current memory layout for argVec
is like 4 layers of pointers. Not sure if this should be optimized... Maybe abi.encode could be used to make the code neater.
hmmm. I thought that the memory representation of a variable-size array of fixed-sized objects was a length-prefix with tightly packed objects. Maybe I was mistaken 🤔
Here's something you can test with remix IDE:
pragma solidity >=0.4.22;
contract A {
struct Fp {
uint256 a;
uint256 b;
}
struct Fp2 {
Fp a;
Fp b;
}
struct G1Point {
Fp X;
Fp Y;
}
struct G2Point {
Fp2 X;
Fp2 Y;
}
struct PairingArg {
G1Point g1;
G2Point g2;
}
function test() public pure returns (uint256, uint, uint, uint) {
Fp memory arg = Fp(1,2);
Fp memory arg2 = Fp(3,4);
Fp2 memory x = Fp2(arg, arg2);
Fp2 memory y = Fp2(arg2, arg);
G1Point memory p1 = G1Point(arg, arg2);
G2Point memory p2 = G2Point(x, y);
PairingArg memory q = PairingArg(p1, p2);
PairingArg[] memory arr = new PairingArg[](2);
arr[0] = q;
arr[1] = q;
arg.a = 123;
uint256 res1;
uint res2;
uint res3;
uint res4;
assembly {
res1 := mload(arr)
res2 := mload(add(arr,0x20))
res3 := mload(add(arr,0x40))
res4 := mload(add(arr,0x80))
}
return (res1, res2, res3, res4);
}
}
It will return
I believe that you are correct :) but I don't understand why the compiler is doing this. Maybe it's not as smart with fixed-size types as I thought it was 🤔
Probably there's a more efficient way to do all this, but it's working for now.