Skip to content

Commit 3b725c1

Browse files
committed
Since GHC 7.0 there is no need to store the length of ByteArray in a separate field
1 parent 9ceaa3f commit 3b725c1

File tree

4 files changed

+23
-95
lines changed

4 files changed

+23
-95
lines changed

src/Data/Text/Array.hs

Lines changed: 22 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,13 @@
2424
module Data.Text.Array
2525
(
2626
-- * Types
27-
Array(Array, aBA)
28-
, MArray(MArray, maBA)
29-
27+
Array(..)
28+
, MArray(..)
3029
-- * Functions
3130
, copyM
3231
, copyI
3332
, empty
3433
, equal
35-
#if defined(ASSERTS)
36-
, length
37-
#endif
3834
, run
3935
, run2
4036
, toList
@@ -44,17 +40,6 @@ module Data.Text.Array
4440
, unsafeWrite
4541
) where
4642

47-
#if defined(ASSERTS)
48-
-- This fugly hack is brought by GHC's apparent reluctance to deal
49-
-- with MagicHash and UnboxedTuples when inferring types. Eek!
50-
# define CHECK_BOUNDS(_func_,_len_,_k_) \
51-
if (_k_) < 0 || (_k_) >= (_len_) then error ("Data.Text.Array." ++ (_func_) ++ ": bounds error, offset " ++ show (_k_) ++ ", length " ++ show (_len_)) else
52-
#else
53-
# define CHECK_BOUNDS(_func_,_len_,_k_)
54-
#endif
55-
56-
#include "MachDeps.h"
57-
5843
#if defined(ASSERTS)
5944
import Control.Exception (assert)
6045
#endif
@@ -73,57 +58,28 @@ import Foreign.C.Types (CInt, CSize)
7358
#endif
7459
import GHC.Base (ByteArray#, MutableByteArray#, Int(..),
7560
indexWord16Array#, newByteArray#,
76-
unsafeFreezeByteArray#, writeWord16Array#)
61+
unsafeFreezeByteArray#, writeWord16Array#, sizeofByteArray#, sizeofMutableByteArray#)
7762
import GHC.ST (ST(..), runST)
7863
import GHC.Word (Word16(..))
7964
import Prelude hiding (length, read)
8065

8166
-- | Immutable array type.
8267
--
8368
-- The 'Array' constructor is exposed since @text-1.1.1.3@
84-
data Array = Array {
85-
aBA :: ByteArray#
86-
#if defined(ASSERTS)
87-
, aLen :: {-# UNPACK #-} !Int -- length (in units of Word16, not bytes)
88-
#endif
89-
}
69+
data Array = Array { aBA :: ByteArray# }
9070

9171
-- | Mutable array type, for use in the ST monad.
9272
--
9373
-- The 'MArray' constructor is exposed since @text-1.1.1.3@
94-
data MArray s = MArray {
95-
maBA :: MutableByteArray# s
96-
#if defined(ASSERTS)
97-
, maLen :: {-# UNPACK #-} !Int -- length (in units of Word16, not bytes)
98-
#endif
99-
}
100-
101-
#if defined(ASSERTS)
102-
-- | Operations supported by all arrays.
103-
class IArray a where
104-
-- | Return the length of an array.
105-
length :: a -> Int
106-
107-
instance IArray Array where
108-
length = aLen
109-
{-# INLINE length #-}
110-
111-
instance IArray (MArray s) where
112-
length = maLen
113-
{-# INLINE length #-}
114-
#endif
74+
data MArray s = MArray { maBA :: MutableByteArray# s }
11575

11676
-- | Create an uninitialized mutable array.
11777
new :: forall s. Int -> ST s (MArray s)
11878
new n
11979
| n < 0 || n .&. highBit /= 0 = array_size_error
12080
| otherwise = ST $ \s1# ->
12181
case newByteArray# len# s1# of
122-
(# s2#, marr# #) -> (# s2#, MArray marr#
123-
#if defined(ASSERTS)
124-
n
125-
#endif
126-
#)
82+
(# s2#, marr# #) -> (# s2#, MArray marr# #)
12783
where !(I# len#) = bytesInArray n
12884
highBit = maxBound `xor` (maxBound `shiftR` 1)
12985
{-# INLINE new #-}
@@ -135,11 +91,7 @@ array_size_error = error "Data.Text.Array.new: size overflow"
13591
unsafeFreeze :: MArray s -> ST s Array
13692
unsafeFreeze MArray{..} = ST $ \s1# ->
13793
case unsafeFreezeByteArray# maBA s1# of
138-
(# s2#, ba# #) -> (# s2#, Array ba#
139-
#if defined(ASSERTS)
140-
maLen
141-
#endif
142-
#)
94+
(# s2#, ba# #) -> (# s2#, Array ba# #)
14395
{-# INLINE unsafeFreeze #-}
14496

14597
-- | Indicate how many bytes would be used for an array of the given
@@ -151,16 +103,24 @@ bytesInArray n = n `shiftL` 1
151103
-- | Unchecked read of an immutable array. May return garbage or
152104
-- crash on an out-of-bounds access.
153105
unsafeIndex :: Array -> Int -> Word16
154-
unsafeIndex Array{..} i@(I# i#) =
155-
CHECK_BOUNDS("unsafeIndex",aLen,i)
156-
case indexWord16Array# aBA i# of r# -> (W16# r#)
106+
unsafeIndex a@Array{..} i@(I# i#) =
107+
#if defined(ASSERTS)
108+
let word16len = I# (sizeofByteArray# aBA) `quot` 2 in
109+
if i < 0 || i >= word16len
110+
then error ("Data.Text.Array.unsafeIndex: bounds error, offset " ++ show i ++ ", length " ++ show word16len)
111+
else
112+
#endif
113+
case indexWord16Array# aBA i# of r# -> (W16# r#)
157114
{-# INLINE unsafeIndex #-}
158115

159116
-- | Unchecked write of a mutable array. May return garbage or crash
160117
-- on an out-of-bounds access.
161118
unsafeWrite :: MArray s -> Int -> Word16 -> ST s ()
162-
unsafeWrite MArray{..} i@(I# i#) (W16# e#) = ST $ \s1# ->
163-
CHECK_BOUNDS("unsafeWrite",maLen,i)
119+
unsafeWrite ma@MArray{..} i@(I# i#) (W16# e#) = ST $ \s1# ->
120+
#if defined(ASSERTS)
121+
let word16len = I# (sizeofMutableByteArray# maBA) `quot` 2 in
122+
if i < 0 || i >= word16len then error ("Data.Text.Array.unsafeWrite: bounds error, offset " ++ show i ++ ", length " ++ show word16len) else
123+
#endif
164124
case writeWord16Array# maBA i# e# s1# of
165125
s2# -> (# s2#, () #)
166126
{-# INLINE unsafeWrite #-}
@@ -200,8 +160,8 @@ copyM dest didx src sidx count
200160
| count <= 0 = return ()
201161
| otherwise =
202162
#if defined(ASSERTS)
203-
assert (sidx + count <= length src) .
204-
assert (didx + count <= length dest) .
163+
assert (sidx + count <= I# (sizeofMutableByteArray# (maBA src)) `quot` 2) .
164+
assert (didx + count <= I# (sizeofMutableByteArray# (maBA dest)) `quot` 2) .
205165
#endif
206166
unsafeIOToST $ memcpyM (maBA dest) (fromIntegral didx)
207167
(maBA src) (fromIntegral sidx)

src/Data/Text/Internal.hs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,8 @@ text_ :: A.Array -> Int -> Int -> Text
6868
text_ arr off len =
6969
#if defined(ASSERTS)
7070
let c = A.unsafeIndex arr off
71-
alen = A.length arr
7271
in assert (len >= 0) .
7372
assert (off >= 0) .
74-
assert (alen == 0 || len == 0 || off < alen) .
7573
assert (len == 0 || c < 0xDC00 || c > 0xDFFF) $
7674
#endif
7775
Text arr off len

src/Data/Text/Internal/Unsafe/Char.hs

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,8 @@ module Data.Text.Internal.Unsafe.Char
2323
, unsafeChr8
2424
, unsafeChr32
2525
, unsafeWrite
26-
-- , unsafeWriteRev
2726
) where
2827

29-
#ifdef ASSERTS
30-
import Control.Exception (assert)
31-
#endif
3228
import Control.Monad.ST (ST)
3329
import Data.Bits ((.&.))
3430
import Data.Text.Internal.Unsafe.Shift (shiftR)
@@ -58,15 +54,9 @@ unsafeChr32 (W32# w#) = C# (chr# (word2Int# (word32ToWord# w#)))
5854
unsafeWrite :: A.MArray s -> Int -> Char -> ST s Int
5955
unsafeWrite marr i c
6056
| n < 0x10000 = do
61-
#if defined(ASSERTS)
62-
assert (i >= 0) . assert (i < A.length marr) $ return ()
63-
#endif
6457
A.unsafeWrite marr i (fromIntegral n)
6558
return 1
6659
| otherwise = do
67-
#if defined(ASSERTS)
68-
assert (i >= 0) . assert (i < A.length marr - 1) $ return ()
69-
#endif
7060
A.unsafeWrite marr i lo
7161
A.unsafeWrite marr (i+1) hi
7262
return 2
@@ -75,22 +65,3 @@ unsafeWrite marr i c
7565
lo = fromIntegral $ (m `shiftR` 10) + 0xD800
7666
hi = fromIntegral $ (m .&. 0x3FF) + 0xDC00
7767
{-# INLINE unsafeWrite #-}
78-
79-
{-
80-
unsafeWriteRev :: A.MArray s Word16 -> Int -> Char -> ST s Int
81-
unsafeWriteRev marr i c
82-
| n < 0x10000 = do
83-
assert (i >= 0) . assert (i < A.length marr) $
84-
A.unsafeWrite marr i (fromIntegral n)
85-
return (i-1)
86-
| otherwise = do
87-
assert (i >= 1) . assert (i < A.length marr) $
88-
A.unsafeWrite marr (i-1) lo
89-
A.unsafeWrite marr i hi
90-
return (i-2)
91-
where n = ord c
92-
m = n - 0x10000
93-
lo = fromIntegral $ (m `shiftR` 10) + 0xD800
94-
hi = fromIntegral $ (m .&. 0x3FF) + 0xDC00
95-
{-# INLINE unsafeWriteRev #-}
96-
-}

text.cabal

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,7 @@ library
160160

161161
ghc-options: -Wall -fwarn-tabs -funbox-strict-fields -O2
162162
if flag(developer)
163-
ghc-prof-options: -auto-all
164-
ghc-options: -Werror
163+
ghc-options: -fno-ignore-asserts
165164
cpp-options: -DASSERTS
166165

167166
if impl(ghc >= 8.11)

0 commit comments

Comments
 (0)