Commit efd70cfb authored by Reiner Pope's avatar Reiner Pope Committed by David Feuer

Add unaligned bytearray access primops. Fixes #4442.

Reviewers: bgamari, simonmar

Reviewed By: bgamari

Subscribers: dfeuer, rwbarton, thomie, carter

GHC Trac Issues: #4442

Differential Revision: https://phabricator.haskell.org/D4488
parent ecfb4d36
{-# LANGUAGE CPP #-}
-- emitPrimOp is quite large
{-# OPTIONS_GHC -fmax-pmcheck-iterations=4000000 #-}
----------------------------------------------------------------------------
--
......@@ -519,6 +521,40 @@ emitPrimOp dflags res ReadByteArrayOp_Word16 args = doIndexByteArrayOp
emitPrimOp dflags res ReadByteArrayOp_Word32 args = doIndexByteArrayOp (Just (mo_u_32ToWord dflags)) b32 res args
emitPrimOp _ res ReadByteArrayOp_Word64 args = doIndexByteArrayOp Nothing b64 res args
-- IndexWord8ArrayAsXXX
emitPrimOp dflags res IndexByteArrayOp_Word8AsChar args = doIndexByteArrayOpAs (Just (mo_u_8ToWord dflags)) b8 b8 res args
emitPrimOp dflags res IndexByteArrayOp_Word8AsWideChar args = doIndexByteArrayOpAs (Just (mo_u_32ToWord dflags)) b32 b8 res args
emitPrimOp dflags res IndexByteArrayOp_Word8AsInt args = doIndexByteArrayOpAs Nothing (bWord dflags) b8 res args
emitPrimOp dflags res IndexByteArrayOp_Word8AsWord args = doIndexByteArrayOpAs Nothing (bWord dflags) b8 res args
emitPrimOp dflags res IndexByteArrayOp_Word8AsAddr args = doIndexByteArrayOpAs Nothing (bWord dflags) b8 res args
emitPrimOp _ res IndexByteArrayOp_Word8AsFloat args = doIndexByteArrayOpAs Nothing f32 b8 res args
emitPrimOp _ res IndexByteArrayOp_Word8AsDouble args = doIndexByteArrayOpAs Nothing f64 b8 res args
emitPrimOp dflags res IndexByteArrayOp_Word8AsStablePtr args = doIndexByteArrayOpAs Nothing (bWord dflags) b8 res args
emitPrimOp dflags res IndexByteArrayOp_Word8AsInt16 args = doIndexByteArrayOpAs (Just (mo_s_16ToWord dflags)) b16 b8 res args
emitPrimOp dflags res IndexByteArrayOp_Word8AsInt32 args = doIndexByteArrayOpAs (Just (mo_s_32ToWord dflags)) b32 b8 res args
emitPrimOp _ res IndexByteArrayOp_Word8AsInt64 args = doIndexByteArrayOpAs Nothing b64 b8 res args
emitPrimOp dflags res IndexByteArrayOp_Word8AsWord16 args = doIndexByteArrayOpAs (Just (mo_u_16ToWord dflags)) b16 b8 res args
emitPrimOp dflags res IndexByteArrayOp_Word8AsWord32 args = doIndexByteArrayOpAs (Just (mo_u_32ToWord dflags)) b32 b8 res args
emitPrimOp _ res IndexByteArrayOp_Word8AsWord64 args = doIndexByteArrayOpAs Nothing b64 b8 res args
-- ReadInt8ArrayAsXXX, identical to IndexInt8ArrayAsXXX
emitPrimOp dflags res ReadByteArrayOp_Word8AsChar args = doIndexByteArrayOpAs (Just (mo_u_8ToWord dflags)) b8 b8 res args
emitPrimOp dflags res ReadByteArrayOp_Word8AsWideChar args = doIndexByteArrayOpAs (Just (mo_u_32ToWord dflags)) b32 b8 res args
emitPrimOp dflags res ReadByteArrayOp_Word8AsInt args = doIndexByteArrayOpAs Nothing (bWord dflags) b8 res args
emitPrimOp dflags res ReadByteArrayOp_Word8AsWord args = doIndexByteArrayOpAs Nothing (bWord dflags) b8 res args
emitPrimOp dflags res ReadByteArrayOp_Word8AsAddr args = doIndexByteArrayOpAs Nothing (bWord dflags) b8 res args
emitPrimOp _ res ReadByteArrayOp_Word8AsFloat args = doIndexByteArrayOpAs Nothing f32 b8 res args
emitPrimOp _ res ReadByteArrayOp_Word8AsDouble args = doIndexByteArrayOpAs Nothing f64 b8 res args
emitPrimOp dflags res ReadByteArrayOp_Word8AsStablePtr args = doIndexByteArrayOpAs Nothing (bWord dflags) b8 res args
emitPrimOp dflags res ReadByteArrayOp_Word8AsInt16 args = doIndexByteArrayOpAs (Just (mo_s_16ToWord dflags)) b16 b8 res args
emitPrimOp dflags res ReadByteArrayOp_Word8AsInt32 args = doIndexByteArrayOpAs (Just (mo_s_32ToWord dflags)) b32 b8 res args
emitPrimOp _ res ReadByteArrayOp_Word8AsInt64 args = doIndexByteArrayOpAs Nothing b64 b8 res args
emitPrimOp dflags res ReadByteArrayOp_Word8AsWord16 args = doIndexByteArrayOpAs (Just (mo_u_16ToWord dflags)) b16 b8 res args
emitPrimOp dflags res ReadByteArrayOp_Word8AsWord32 args = doIndexByteArrayOpAs (Just (mo_u_32ToWord dflags)) b32 b8 res args
emitPrimOp _ res ReadByteArrayOp_Word8AsWord64 args = doIndexByteArrayOpAs Nothing b64 b8 res args
-- WriteXXXoffAddr
emitPrimOp dflags res WriteOffAddrOp_Char args = doWriteOffAddrOp (Just (mo_WordTo8 dflags)) b8 res args
......@@ -557,6 +593,23 @@ emitPrimOp dflags res WriteByteArrayOp_Word16 args = doWriteByteArrayO
emitPrimOp dflags res WriteByteArrayOp_Word32 args = doWriteByteArrayOp (Just (mo_WordTo32 dflags)) b32 res args
emitPrimOp _ res WriteByteArrayOp_Word64 args = doWriteByteArrayOp Nothing b64 res args
-- WriteInt8ArrayAsXXX
emitPrimOp dflags res WriteByteArrayOp_Word8AsChar args = doWriteByteArrayOp (Just (mo_WordTo8 dflags)) b8 res args
emitPrimOp dflags res WriteByteArrayOp_Word8AsWideChar args = doWriteByteArrayOp (Just (mo_WordTo32 dflags)) b8 res args
emitPrimOp _ res WriteByteArrayOp_Word8AsInt args = doWriteByteArrayOp Nothing b8 res args
emitPrimOp _ res WriteByteArrayOp_Word8AsWord args = doWriteByteArrayOp Nothing b8 res args
emitPrimOp _ res WriteByteArrayOp_Word8AsAddr args = doWriteByteArrayOp Nothing b8 res args
emitPrimOp _ res WriteByteArrayOp_Word8AsFloat args = doWriteByteArrayOp Nothing b8 res args
emitPrimOp _ res WriteByteArrayOp_Word8AsDouble args = doWriteByteArrayOp Nothing b8 res args
emitPrimOp _ res WriteByteArrayOp_Word8AsStablePtr args = doWriteByteArrayOp Nothing b8 res args
emitPrimOp dflags res WriteByteArrayOp_Word8AsInt16 args = doWriteByteArrayOp (Just (mo_WordTo16 dflags)) b8 res args
emitPrimOp dflags res WriteByteArrayOp_Word8AsInt32 args = doWriteByteArrayOp (Just (mo_WordTo32 dflags)) b8 res args
emitPrimOp _ res WriteByteArrayOp_Word8AsInt64 args = doWriteByteArrayOp Nothing b8 res args
emitPrimOp dflags res WriteByteArrayOp_Word8AsWord16 args = doWriteByteArrayOp (Just (mo_WordTo16 dflags)) b8 res args
emitPrimOp dflags res WriteByteArrayOp_Word8AsWord32 args = doWriteByteArrayOp (Just (mo_WordTo32 dflags)) b8 res args
emitPrimOp _ res WriteByteArrayOp_Word8AsWord64 args = doWriteByteArrayOp Nothing b8 res args
-- Copying and setting byte arrays
emitPrimOp _ [] CopyByteArrayOp [src,src_off,dst,dst_off,n] =
doCopyByteArrayOp src src_off dst dst_off n
......
......@@ -1254,6 +1254,76 @@ primop IndexByteArrayOp_Word64 "indexWord64Array#" GenPrimOp
{Read 64-bit word; offset in 64-bit words.}
with can_fail = True
primop IndexByteArrayOp_Word8AsChar "indexWord8ArrayAsChar#" GenPrimOp
ByteArray# -> Int# -> Char#
{Read 8-bit character; offset in bytes.}
with can_fail = True
primop IndexByteArrayOp_Word8AsWideChar "indexWord8ArrayAsWideChar#" GenPrimOp
ByteArray# -> Int# -> Char#
{Read 31-bit character; offset in bytes.}
with can_fail = True
primop IndexByteArrayOp_Word8AsAddr "indexWord8ArrayAsAddr#" GenPrimOp
ByteArray# -> Int# -> Addr#
{Read address; offset in bytes.}
with can_fail = True
primop IndexByteArrayOp_Word8AsFloat "indexWord8ArrayAsFloat#" GenPrimOp
ByteArray# -> Int# -> Float#
{Read float; offset in bytes.}
with can_fail = True
primop IndexByteArrayOp_Word8AsDouble "indexWord8ArrayAsDouble#" GenPrimOp
ByteArray# -> Int# -> Double#
{Read double; offset in bytes.}
with can_fail = True
primop IndexByteArrayOp_Word8AsStablePtr "indexWord8ArrayAsStablePtr#" GenPrimOp
ByteArray# -> Int# -> StablePtr# a
{Read stable pointer; offset in bytes.}
with can_fail = True
primop IndexByteArrayOp_Word8AsInt16 "indexWord8ArrayAsInt16#" GenPrimOp
ByteArray# -> Int# -> Int#
{Read 16-bit int; offset in bytes.}
with can_fail = True
primop IndexByteArrayOp_Word8AsInt32 "indexWord8ArrayAsInt32#" GenPrimOp
ByteArray# -> Int# -> INT32
{Read 32-bit int; offset in bytes.}
with can_fail = True
primop IndexByteArrayOp_Word8AsInt64 "indexWord8ArrayAsInt64#" GenPrimOp
ByteArray# -> Int# -> INT64
{Read 64-bit int; offset in bytes.}
with can_fail = True
primop IndexByteArrayOp_Word8AsInt "indexWord8ArrayAsInt#" GenPrimOp
ByteArray# -> Int# -> Int#
{Read int; offset in bytes.}
with can_fail = True
primop IndexByteArrayOp_Word8AsWord16 "indexWord8ArrayAsWord16#" GenPrimOp
ByteArray# -> Int# -> Word#
{Read 16-bit word; offset in bytes.}
with can_fail = True
primop IndexByteArrayOp_Word8AsWord32 "indexWord8ArrayAsWord32#" GenPrimOp
ByteArray# -> Int# -> WORD32
{Read 32-bit word; offset in bytes.}
with can_fail = True
primop IndexByteArrayOp_Word8AsWord64 "indexWord8ArrayAsWord64#" GenPrimOp
ByteArray# -> Int# -> WORD64
{Read 64-bit word; offset in bytes.}
with can_fail = True
primop IndexByteArrayOp_Word8AsWord "indexWord8ArrayAsWord#" GenPrimOp
ByteArray# -> Int# -> Word#
{Read word; offset in bytes.}
with can_fail = True
primop ReadByteArrayOp_Char "readCharArray#" GenPrimOp
MutableByteArray# s -> Int# -> State# s -> (# State# s, Char# #)
{Read 8-bit character; offset in bytes.}
......@@ -1338,6 +1408,76 @@ primop ReadByteArrayOp_Word64 "readWord64Array#" GenPrimOp
with has_side_effects = True
can_fail = True
primop ReadByteArrayOp_Word8AsChar "readWord8ArrayAsChar#" GenPrimOp
MutableByteArray# s -> Int# -> State# s -> (# State# s, Char# #)
with has_side_effects = True
can_fail = True
primop ReadByteArrayOp_Word8AsWideChar "readWord8ArrayAsWideChar#" GenPrimOp
MutableByteArray# s -> Int# -> State# s -> (# State# s, Char# #)
with has_side_effects = True
can_fail = True
primop ReadByteArrayOp_Word8AsAddr "readWord8ArrayAsAddr#" GenPrimOp
MutableByteArray# s -> Int# -> State# s -> (# State# s, Addr# #)
with has_side_effects = True
can_fail = True
primop ReadByteArrayOp_Word8AsFloat "readWord8ArrayAsFloat#" GenPrimOp
MutableByteArray# s -> Int# -> State# s -> (# State# s, Float# #)
with has_side_effects = True
can_fail = True
primop ReadByteArrayOp_Word8AsDouble "readWord8ArrayAsDouble#" GenPrimOp
MutableByteArray# s -> Int# -> State# s -> (# State# s, Double# #)
with has_side_effects = True
can_fail = True
primop ReadByteArrayOp_Word8AsStablePtr "readWord8ArrayAsStablePtr#" GenPrimOp
MutableByteArray# s -> Int# -> State# s -> (# State# s, StablePtr# a #)
with has_side_effects = True
can_fail = True
primop ReadByteArrayOp_Word8AsInt16 "readWord8ArrayAsInt16#" GenPrimOp
MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
with has_side_effects = True
can_fail = True
primop ReadByteArrayOp_Word8AsInt32 "readWord8ArrayAsInt32#" GenPrimOp
MutableByteArray# s -> Int# -> State# s -> (# State# s, INT32 #)
with has_side_effects = True
can_fail = True
primop ReadByteArrayOp_Word8AsInt64 "readWord8ArrayAsInt64#" GenPrimOp
MutableByteArray# s -> Int# -> State# s -> (# State# s, INT64 #)
with has_side_effects = True
can_fail = True
primop ReadByteArrayOp_Word8AsInt "readWord8ArrayAsInt#" GenPrimOp
MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
with has_side_effects = True
can_fail = True
primop ReadByteArrayOp_Word8AsWord16 "readWord8ArrayAsWord16#" GenPrimOp
MutableByteArray# s -> Int# -> State# s -> (# State# s, Word# #)
with has_side_effects = True
can_fail = True
primop ReadByteArrayOp_Word8AsWord32 "readWord8ArrayAsWord32#" GenPrimOp
MutableByteArray# s -> Int# -> State# s -> (# State# s, WORD32 #)
with has_side_effects = True
can_fail = True
primop ReadByteArrayOp_Word8AsWord64 "readWord8ArrayAsWord64#" GenPrimOp
MutableByteArray# s -> Int# -> State# s -> (# State# s, WORD64 #)
with has_side_effects = True
can_fail = True
primop ReadByteArrayOp_Word8AsWord "readWord8ArrayAsWord#" GenPrimOp
MutableByteArray# s -> Int# -> State# s -> (# State# s, Word# #)
with has_side_effects = True
can_fail = True
primop WriteByteArrayOp_Char "writeCharArray#" GenPrimOp
MutableByteArray# s -> Int# -> Char# -> State# s -> State# s
{Write 8-bit character; offset in bytes.}
......@@ -1420,6 +1560,76 @@ primop WriteByteArrayOp_Word64 "writeWord64Array#" GenPrimOp
with has_side_effects = True
can_fail = True
primop WriteByteArrayOp_Word8AsChar "writeWord8ArrayAsChar#" GenPrimOp
MutableByteArray# s -> Int# -> Char# -> State# s -> State# s
with has_side_effects = True
can_fail = True
primop WriteByteArrayOp_Word8AsWideChar "writeWord8ArrayAsWideChar#" GenPrimOp
MutableByteArray# s -> Int# -> Char# -> State# s -> State# s
with has_side_effects = True
can_fail = True
primop WriteByteArrayOp_Word8AsAddr "writeWord8ArrayAsAddr#" GenPrimOp
MutableByteArray# s -> Int# -> Addr# -> State# s -> State# s
with has_side_effects = True
can_fail = True
primop WriteByteArrayOp_Word8AsFloat "writeWord8ArrayAsFloat#" GenPrimOp
MutableByteArray# s -> Int# -> Float# -> State# s -> State# s
with has_side_effects = True
can_fail = True
primop WriteByteArrayOp_Word8AsDouble "writeWord8ArrayAsDouble#" GenPrimOp
MutableByteArray# s -> Int# -> Double# -> State# s -> State# s
with has_side_effects = True
can_fail = True
primop WriteByteArrayOp_Word8AsStablePtr "writeWord8ArrayAsStablePtr#" GenPrimOp
MutableByteArray# s -> Int# -> StablePtr# a -> State# s -> State# s
with has_side_effects = True
can_fail = True
primop WriteByteArrayOp_Word8AsInt16 "writeWord8ArrayAsInt16#" GenPrimOp
MutableByteArray# s -> Int# -> Int# -> State# s -> State# s
with has_side_effects = True
can_fail = True
primop WriteByteArrayOp_Word8AsInt32 "writeWord8ArrayAsInt32#" GenPrimOp
MutableByteArray# s -> Int# -> INT32 -> State# s -> State# s
with has_side_effects = True
can_fail = True
primop WriteByteArrayOp_Word8AsInt64 "writeWord8ArrayAsInt64#" GenPrimOp
MutableByteArray# s -> Int# -> INT64 -> State# s -> State# s
with has_side_effects = True
can_fail = True
primop WriteByteArrayOp_Word8AsInt "writeWord8ArrayAsInt#" GenPrimOp
MutableByteArray# s -> Int# -> Int# -> State# s -> State# s
with has_side_effects = True
can_fail = True
primop WriteByteArrayOp_Word8AsWord16 "writeWord8ArrayAsWord16#" GenPrimOp
MutableByteArray# s -> Int# -> Word# -> State# s -> State# s
with has_side_effects = True
can_fail = True
primop WriteByteArrayOp_Word8AsWord32 "writeWord8ArrayAsWord32#" GenPrimOp
MutableByteArray# s -> Int# -> WORD32 -> State# s -> State# s
with has_side_effects = True
can_fail = True
primop WriteByteArrayOp_Word8AsWord64 "writeWord8ArrayAsWord64#" GenPrimOp
MutableByteArray# s -> Int# -> WORD64 -> State# s -> State# s
with has_side_effects = True
can_fail = True
primop WriteByteArrayOp_Word8AsWord "writeWord8ArrayAsWord#" GenPrimOp
MutableByteArray# s -> Int# -> Word# -> State# s -> State# s
with has_side_effects = True
can_fail = True
primop CompareByteArraysOp "compareByteArrays#" GenPrimOp
ByteArray# -> Int# -> ByteArray# -> Int# -> Int# -> Int#
{{\tt compareByteArrays# src1 src1_ofs src2 src2_ofs n} compares
......
{-# LANGUAGE MagicHash, UnboxedTuples, CPP #-}
module Main where
#include "MachDeps.h"
import GHC.Ptr(Ptr(..), nullPtr, plusPtr, minusPtr)
import GHC.Stable(
StablePtr(..), castStablePtrToPtr, castPtrToStablePtr, newStablePtr)
import GHC.Exts
import Data.Char(ord)
assertEqual :: (Show a, Eq a) => a -> a -> IO ()
assertEqual a b
| a /= b = putStrLn (show a ++ " /= " ++ show b)
| otherwise = return ()
readBytes :: MutableByteArray# s -> State# s -> Int# -> (# State# s, [Int] #)
readBytes marr s0 len = go s0 len []
where
go s 0# bs = (# s, bs #)
go s i bs = case readWord8Array# marr (i -# 1#) s of
(# s', b #) -> go s' (i -# 1#) (I# (word2Int# b):bs)
indexBytes :: ByteArray# -> Int# -> [Int]
indexBytes arr len =
[I# (word2Int# (indexWord8Array# arr i)) | I# i <- [0..I# len - 1]]
fillByteArray :: MutableByteArray# s -> Int# -> Int -> State# s -> State# s
fillByteArray arr len (I# a) = go len
where
go 0# s = s
go i s = go (i -# 1#) (writeInt8Array# arr (i -# 1#) a s)
test :: (Eq a, Show a)
=> String
-> (ByteArray# -> Int# -> a)
-> (MutableByteArray# RealWorld -> Int# -> State# RealWorld
-> (# State# RealWorld, a #))
-> (MutableByteArray# RealWorld -> Int# -> a -> State# RealWorld
-> State# RealWorld)
-> a
-> [Int]
-> Int
-> IO ()
test name index read write val valBytes len = do
putStrLn name
mapM_ testAtOffset [0..16]
where
arrLen :: Int#
arrLen = 24#
fillerByte :: Int
fillerByte = 0x34
expectedArrayBytes :: Int -> [Int]
expectedArrayBytes offset =
replicate offset fillerByte
++ valBytes
++ replicate (I# arrLen - len - offset) fillerByte
testAtOffset :: Int -> IO ()
testAtOffset offset@(I# offset#) = runRW# (\s0 -> let
(# s1, marr #) = newByteArray# arrLen s0
s2 = fillByteArray marr arrLen fillerByte s1
s3 = write marr offset# val s2
(# s4, actual0 #) = read marr offset# s3
(# s5, actualBytes0 #) = readBytes marr s4 arrLen
(# _, arr #) = unsafeFreezeByteArray# marr s5
actual1 = index arr offset#
actualBytes1 = indexBytes arr arrLen
in do
assertEqual actual0 val
assertEqual actual1 val
assertEqual actualBytes0 (expectedArrayBytes offset)
assertEqual actualBytes1 (expectedArrayBytes offset)
)
intToBytes :: Int -> Int -> [Int]
intToBytes (I# val0) (I# len0) = let
result = go val0 len0
go v 0# = []
go v len =
I# (v `andI#` 0xff#) : go (v `uncheckedIShiftRL#` 8#) (len -# 1#)
in
#if defined(WORDS_BIGENDIAN)
reverse result
#else
result
#endif
testIntArray ::
String
-> (ByteArray# -> Int# -> Int#)
-> (MutableByteArray# RealWorld -> Int# -> State# RealWorld
-> (# State# RealWorld, Int# #))
-> (MutableByteArray# RealWorld -> Int# -> Int# -> State# RealWorld
-> State# RealWorld)
-> Int
-> Int
-> IO ()
testIntArray name0 index read write val0 len = do
doOne (name0 ++ " positive") val0
doOne (name0 ++ " negative") (negate val0)
where
doOne name val = test
name
(\arr i -> I# (index arr i))
(\arr i s -> case read arr i s of (# s', a #) -> (# s', I# a #))
(\arr i (I# a) s -> write arr i a s)
val
(intToBytes val len)
len
testWordArray ::
String
-> (ByteArray# -> Int# -> Word#)
-> (MutableByteArray# RealWorld -> Int# -> State# RealWorld
-> (# State# RealWorld, Word# #))
-> (MutableByteArray# RealWorld -> Int# -> Word# -> State# RealWorld
-> State# RealWorld)
-> Word
-> Int
-> IO ()
testWordArray name index read write val len = test
name
(\arr i -> W# (index arr i))
(\arr i s -> case read arr i s of (# s', a #) -> (# s', W# a #))
(\arr i (W# a) s -> write arr i a s)
val
(intToBytes (fromIntegral val) len)
len
wordSizeInBytes :: Int
wordSizeInBytes = WORD_SIZE_IN_BITS `div` 8
int :: Int
int
| WORD_SIZE_IN_BITS == 32 = 12345678
| otherwise = 1234567890123
word :: Word
word = fromIntegral int
float :: Float
float = 123.456789
-- Test pattern generated by this python code:
-- >>> import struct
-- >>> import binascii
-- >>> binascii.hexlify(struct.pack('>f', 123.456789))
floatBytes :: Int
floatBytes = 0x42f6e9e0
double :: Double
double = 123.45678901234
-- Test pattern generated by this python code:
-- >>> import struct
-- >>> import binascii
-- >>> binascii.hexlify(struct.pack('>d', 123.45678901234))
doubleBytes :: Int
doubleBytes = 0x405edd3c07fb4b09
main :: IO ()
main = do
testIntArray "Int8#"
indexInt8Array# readInt8Array# writeInt8Array#
123 1
testIntArray "Int16#"
indexWord8ArrayAsInt16# readWord8ArrayAsInt16# writeWord8ArrayAsInt16#
12345 2
testIntArray "Int32#"
indexWord8ArrayAsInt32# readWord8ArrayAsInt32# writeWord8ArrayAsInt32#
12345678 4
testIntArray "Int64#"
indexWord8ArrayAsInt64# readWord8ArrayAsInt64# writeWord8ArrayAsInt64#
1234567890123 8
testIntArray "Int#"
indexWord8ArrayAsInt# readWord8ArrayAsInt# writeWord8ArrayAsInt#
int wordSizeInBytes
testWordArray "Word8#"
indexWord8Array# readWord8Array# writeWord8Array#
123 1
testWordArray "Word16#"
indexWord8ArrayAsWord16# readWord8ArrayAsWord16# writeWord8ArrayAsWord16#
12345 2
testWordArray "Word32#"
indexWord8ArrayAsWord32# readWord8ArrayAsWord32# writeWord8ArrayAsWord32#
12345678 4
testWordArray "Word64#"
indexWord8ArrayAsWord64# readWord8ArrayAsWord64# writeWord8ArrayAsWord64#
1234567890123 8
testWordArray "Word#"
indexWord8ArrayAsWord# readWord8ArrayAsWord# writeWord8ArrayAsWord#
word wordSizeInBytes
test
"Char#"
(\arr i -> C# (indexWord8ArrayAsChar# arr i))
(\arr i s ->
case readWord8ArrayAsChar# arr i s of (# s', a #) -> (# s', C# a #))
(\arr i (C# a) s -> writeWord8ArrayAsChar# arr i a s)
'z'
[ord 'z']
1
test
"WideChar#"
(\arr i -> C# (indexWord8ArrayAsWideChar# arr i))
(\arr i s ->
case readWord8ArrayAsWideChar# arr i s of (# s', a #) -> (# s', C# a #))
(\arr i (C# a) s -> writeWord8ArrayAsWideChar# arr i a s)
'𠜎' -- See http://www.i18nguy.com/unicode/supplementary-test.html
(intToBytes (ord '𠜎') 4)
4
test
"Addr#"
(\arr i -> Ptr (indexWord8ArrayAsAddr# arr i))
(\arr i s ->
case readWord8ArrayAsAddr# arr i s of (# s', a #) -> (# s', Ptr a #))
(\arr i (Ptr a) s -> writeWord8ArrayAsAddr# arr i a s)
(nullPtr `plusPtr` int)
(intToBytes int wordSizeInBytes)
wordSizeInBytes
stablePtr <- newStablePtr ()
test
"StablePtr#"
(\arr i ->
castStablePtrToPtr (StablePtr (indexWord8ArrayAsStablePtr# arr i)))
(\arr i s -> case readWord8ArrayAsStablePtr# arr i s of
(# s', a #) -> (# s', castStablePtrToPtr (StablePtr a) #))
(\arr i p s -> case castPtrToStablePtr p of
(StablePtr a) -> writeWord8ArrayAsStablePtr# arr i a s)
(castStablePtrToPtr stablePtr)
(intToBytes (castStablePtrToPtr stablePtr `minusPtr` nullPtr)
wordSizeInBytes)
wordSizeInBytes
test
"Float#"
(\arr i -> F# (indexWord8ArrayAsFloat# arr i))
(\arr i s ->
case readWord8ArrayAsFloat# arr i s of (# s', a #) -> (# s', F# a #))
(\arr i (F# a) s -> writeWord8ArrayAsFloat# arr i a s)
float
(intToBytes floatBytes 4)
4
test
"Double#"
(\arr i -> D# (indexWord8ArrayAsDouble# arr i))
(\arr i s ->
case readWord8ArrayAsDouble# arr i s of (# s', a #) -> (# s', D# a #))
(\arr i (D# a) s -> writeWord8ArrayAsDouble# arr i a s)
double
(intToBytes doubleBytes 8)
8
Int8# positive
Int8# negative
Int16# positive
Int16# negative
Int32# positive
Int32# negative
Int64# positive
Int64# negative
Int# positive
Int# negative
Word8#
Word16#
Word32#
Word64#
Word#
Char#
WideChar#
Addr#
StablePtr#
Float#
Double#
\ No newline at end of file
test('T6135', normal, compile_and_run, [''])
test('T7689', normal, compile_and_run, [''])
# The test is using unboxed tuples, so omit ghci
# These tests are using unboxed tuples, so omit ghci
test('T9430', omit_ways(['ghci']), compile_and_run, [''])
test('T4442', omit_ways(['ghci']), compile_and_run, [''])
test('T10481', exit_code(1), compile_and_run, [''])
test('T10678',
[stats_num_field('bytes allocated',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment