foundation icon indicating copy to clipboard operation
foundation copied to clipboard

Storable Word128 and Word256 uses mixed endiannes on LE architectures

Open monoidk opened this issue 3 years ago • 0 comments

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.

monoidk avatar Jul 02 '21 13:07 monoidk