foundation
foundation copied to clipboard
Storable Word128 and Word256 uses mixed endiannes on LE architectures
Basement.Types.Word{128,256} have Storable
instances, which do not take endianness into account and result in a rather peculiar mixed endian encoding for Word128 and Word256 on little endian architectures.
AFAIK all instances of WordN and even IntN use native endiannes for Storable instances, so it seems the larger Words should use the same.
At a minimum, it should not implement such an unusual Storable instance.
ghci test:
:set -XScopedTypeVariables
:m + Data.Word Foreign.Ptr Foreign.Marshal.Utils Foreign.Storable
:m + Basement.Types.Word128 Basement.Types.Word256
let p val = with val (\p -> (mapM (\o -> peek (castPtr p `plusPtr` o)) [0..pred (sizeOf val)] >>= (print :: [Word8] -> IO ())))
p (0x0f0e0d0c0b0a09080706050403020100 :: Word128)
p (0x1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100 :: Word256)
Result (on LE):
[8,9,10,11,12,13,14,15,0,1,2,3,4,5,6,7]
[24,25,26,27,28,29,30,31,16,17,18,19,20,21,22,23,8,9,10,11,12,13,14,15,0,1,2,3,4,5,6,7]
Expected result (on LE):
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]
Likely current and expected result on BE:
[15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0]
[31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0]
A solution would be to reverse the offset/order of Word64s in peek and poke, however it should only be done on little endian architectures.
I don't have a patch as I currently don't know what is a good way to choose offset/implementation based on endianness.