2 % (c) The AQUA Project, Glasgow University, 1994-1996
4 \section[PrelByteArr]{Module @PrelByteArr@}
6 Byte-arrays are flat arrays of non-pointers only.
9 {-# OPTIONS -fno-implicit-prelude #-}
11 module PrelByteArr where
13 import {-# SOURCE #-} PrelErr ( error )
17 import PrelList (foldl)
25 %*********************************************************
27 \subsection{The @Array@ types}
29 %*********************************************************
32 data Ix ix => ByteArray ix = ByteArray ix ix ByteArray#
33 data Ix ix => MutableByteArray s ix = MutableByteArray ix ix (MutableByteArray# s)
35 instance CCallable (ByteArray ix)
36 instance CCallable (MutableByteArray RealWorld ix)
37 -- Note the RealWorld! You can only ccall with MutableByteArray args
38 -- which are in the real world. When this was missed out, the result
39 -- was that a CCallOpId had a free tyvar, and since the compiler doesn't
40 -- expect that it didn't get zonked or substituted. Bad news.
42 instance Eq (MutableByteArray s ix) where
43 MutableByteArray _ _ arr1# == MutableByteArray _ _ arr2#
44 = sameMutableByteArray# arr1# arr2#
47 %*********************************************************
49 \subsection{Operations on mutable arrays}
51 %*********************************************************
53 Idle ADR question: What's the tradeoff here between flattening these
54 datatypes into @MutableArray ix ix (MutableArray# s elt)@ and using
55 it as is? As I see it, the former uses slightly less heap and
56 provides faster access to the individual parts of the bounds while the
57 code used has the benefit of providing a ready-made @(lo, hi)@ pair as
58 required by many array-related functions. Which wins? Is the
59 difference significant (probably not).
61 Idle AJG answer: When I looked at the outputted code (though it was 2
62 years ago) it seems like you often needed the tuple, and we build
63 it frequently. Now we've got the overloading specialiser things
64 might be different, though.
67 newCharArray, newIntArray, newWordArray, newAddrArray, newFloatArray, newDoubleArray
68 :: Ix ix => (ix,ix) -> ST s (MutableByteArray s ix)
70 {-# SPECIALIZE newCharArray :: IPr -> ST s (MutableByteArray s Int) #-}
71 {-# SPECIALIZE newIntArray :: IPr -> ST s (MutableByteArray s Int) #-}
72 {-# SPECIALIZE newWordArray :: IPr -> ST s (MutableByteArray s Int) #-}
73 {-# SPECIALIZE newAddrArray :: IPr -> ST s (MutableByteArray s Int) #-}
74 {-# SPECIALIZE newFloatArray :: IPr -> ST s (MutableByteArray s Int) #-}
75 {-# SPECIALIZE newDoubleArray :: IPr -> ST s (MutableByteArray s Int) #-}
77 newCharArray (l,u) = ST $ \ s# ->
78 case rangeSize (l,u) of { I# n# ->
79 case (newCharArray# n# s#) of { (# s2#, barr# #) ->
80 (# s2#, MutableByteArray l u barr# #) }}
82 newIntArray (l,u) = ST $ \ s# ->
83 case rangeSize (l,u) of { I# n# ->
84 case (newIntArray# n# s#) of { (# s2#, barr# #) ->
85 (# s2#, MutableByteArray l u barr# #) }}
87 newWordArray (l,u) = ST $ \ s# ->
88 case rangeSize (l,u) of { I# n# ->
89 case (newWordArray# n# s#) of { (# s2#, barr# #) ->
90 (# s2#, MutableByteArray l u barr# #) }}
92 newAddrArray (l,u) = ST $ \ s# ->
93 case rangeSize (l,u) of { I# n# ->
94 case (newAddrArray# n# s#) of { (# s2#, barr# #) ->
95 (# s2#, MutableByteArray l u barr# #) }}
97 newFloatArray (l,u) = ST $ \ s# ->
98 case rangeSize (l,u) of { I# n# ->
99 case (newFloatArray# n# s#) of { (# s2#, barr# #) ->
100 (# s2#, MutableByteArray l u barr# #) }}
102 newDoubleArray (l,u) = ST $ \ s# ->
103 case rangeSize (l,u) of { I# n# ->
104 case (newDoubleArray# n# s#) of { (# s2#, barr# #) ->
105 (# s2#, MutableByteArray l u barr# #) }}
108 readCharArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Char
109 readIntArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Int
110 readWordArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Word
111 readAddrArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Addr
112 readFloatArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Float
113 readDoubleArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Double
115 {-# SPECIALIZE readCharArray :: MutableByteArray s Int -> Int -> ST s Char #-}
116 {-# SPECIALIZE readIntArray :: MutableByteArray s Int -> Int -> ST s Int #-}
117 {-# SPECIALIZE readAddrArray :: MutableByteArray s Int -> Int -> ST s Addr #-}
118 --NO:{-# SPECIALIZE readFloatArray :: MutableByteArray s Int -> Int -> ST s Float #-}
119 {-# SPECIALIZE readDoubleArray :: MutableByteArray s Int -> Int -> ST s Double #-}
121 readCharArray (MutableByteArray l u barr#) n = ST $ \ s# ->
122 case (index (l,u) n) of { I# n# ->
123 case readCharArray# barr# n# s# of { (# s2#, r# #) ->
126 readIntArray (MutableByteArray l u barr#) n = ST $ \ s# ->
127 case (index (l,u) n) of { I# n# ->
128 case readIntArray# barr# n# s# of { (# s2#, r# #) ->
131 readWordArray (MutableByteArray l u barr#) n = ST $ \ s# ->
132 case (index (l,u) n) of { I# n# ->
133 case readWordArray# barr# n# s# of { (# s2#, r# #) ->
136 readAddrArray (MutableByteArray l u barr#) n = ST $ \ s# ->
137 case (index (l,u) n) of { I# n# ->
138 case readAddrArray# barr# n# s# of { (# s2#, r# #) ->
141 readFloatArray (MutableByteArray l u barr#) n = ST $ \ s# ->
142 case (index (l,u) n) of { I# n# ->
143 case readFloatArray# barr# n# s# of { (# s2#, r# #) ->
146 readDoubleArray (MutableByteArray l u barr#) n = ST $ \ s# ->
147 case (index (l,u) n) of { I# n# ->
148 case readDoubleArray# barr# n# s# of { (# s2#, r# #) ->
151 --Indexing of ordinary @Arrays@ is standard Haskell and isn't defined here.
152 indexCharArray :: Ix ix => ByteArray ix -> ix -> Char
153 indexIntArray :: Ix ix => ByteArray ix -> ix -> Int
154 indexWordArray :: Ix ix => ByteArray ix -> ix -> Word
155 indexAddrArray :: Ix ix => ByteArray ix -> ix -> Addr
156 indexFloatArray :: Ix ix => ByteArray ix -> ix -> Float
157 indexDoubleArray :: Ix ix => ByteArray ix -> ix -> Double
159 {-# SPECIALIZE indexCharArray :: ByteArray Int -> Int -> Char #-}
160 {-# SPECIALIZE indexIntArray :: ByteArray Int -> Int -> Int #-}
161 {-# SPECIALIZE indexAddrArray :: ByteArray Int -> Int -> Addr #-}
162 --NO:{-# SPECIALIZE indexFloatArray :: ByteArray Int -> Int -> Float #-}
163 {-# SPECIALIZE indexDoubleArray :: ByteArray Int -> Int -> Double #-}
165 indexCharArray (ByteArray l u barr#) n
166 = case (index (l,u) n) of { I# n# ->
167 case indexCharArray# barr# n# of { r# ->
170 indexIntArray (ByteArray l u barr#) n
171 = case (index (l,u) n) of { I# n# ->
172 case indexIntArray# barr# n# of { r# ->
175 indexWordArray (ByteArray l u barr#) n
176 = case (index (l,u) n) of { I# n# ->
177 case indexWordArray# barr# n# of { r# ->
180 indexAddrArray (ByteArray l u barr#) n
181 = case (index (l,u) n) of { I# n# ->
182 case indexAddrArray# barr# n# of { r# ->
185 indexFloatArray (ByteArray l u barr#) n
186 = case (index (l,u) n) of { I# n# ->
187 case indexFloatArray# barr# n# of { r# ->
190 indexDoubleArray (ByteArray l u barr#) n
191 = case (index (l,u) n) of { I# n# ->
192 case indexDoubleArray# barr# n# of { r# ->
195 writeCharArray :: Ix ix => MutableByteArray s ix -> ix -> Char -> ST s ()
196 writeIntArray :: Ix ix => MutableByteArray s ix -> ix -> Int -> ST s ()
197 writeWordArray :: Ix ix => MutableByteArray s ix -> ix -> Word -> ST s ()
198 writeAddrArray :: Ix ix => MutableByteArray s ix -> ix -> Addr -> ST s ()
199 writeFloatArray :: Ix ix => MutableByteArray s ix -> ix -> Float -> ST s ()
200 writeDoubleArray :: Ix ix => MutableByteArray s ix -> ix -> Double -> ST s ()
202 {-# SPECIALIZE writeCharArray :: MutableByteArray s Int -> Int -> Char -> ST s () #-}
203 {-# SPECIALIZE writeIntArray :: MutableByteArray s Int -> Int -> Int -> ST s () #-}
204 {-# SPECIALIZE writeAddrArray :: MutableByteArray s Int -> Int -> Addr -> ST s () #-}
205 --NO:{-# SPECIALIZE writeFloatArray :: MutableByteArray s Int -> Int -> Float -> ST s () #-}
206 {-# SPECIALIZE writeDoubleArray :: MutableByteArray s Int -> Int -> Double -> ST s () #-}
208 writeCharArray (MutableByteArray l u barr#) n (C# ele) = ST $ \ s# ->
209 case index (l,u) n of { I# n# ->
210 case writeCharArray# barr# n# ele s# of { s2# ->
213 writeIntArray (MutableByteArray l u barr#) n (I# ele) = ST $ \ s# ->
214 case index (l,u) n of { I# n# ->
215 case writeIntArray# barr# n# ele s# of { s2# ->
218 writeWordArray (MutableByteArray l u barr#) n (W# ele) = ST $ \ s# ->
219 case index (l,u) n of { I# n# ->
220 case writeWordArray# barr# n# ele s# of { s2# ->
223 writeAddrArray (MutableByteArray l u barr#) n (A# ele) = ST $ \ s# ->
224 case index (l,u) n of { I# n# ->
225 case writeAddrArray# barr# n# ele s# of { s2# ->
228 writeFloatArray (MutableByteArray l u barr#) n (F# ele) = ST $ \ s# ->
229 case index (l,u) n of { I# n# ->
230 case writeFloatArray# barr# n# ele s# of { s2# ->
233 writeDoubleArray (MutableByteArray l u barr#) n (D# ele) = ST $ \ s# ->
234 case index (l,u) n of { I# n# ->
235 case writeDoubleArray# barr# n# ele s# of { s2# ->
240 %*********************************************************
242 \subsection{Moving between mutable and immutable}
244 %*********************************************************
247 freezeCharArray :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
248 freezeIntArray :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
249 freezeWordArray :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
250 freezeAddrArray :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
252 {-# SPECIALISE freezeCharArray :: MutableByteArray s Int -> ST s (ByteArray Int) #-}
254 freezeCharArray (MutableByteArray l u arr#) = ST $ \ s# ->
255 case rangeSize (l,u) of { I# n# ->
256 case freeze arr# n# s# of { (# s2#, frozen# #) ->
257 (# s2#, ByteArray l u frozen# #) }}
259 freeze :: MutableByteArray# s -- the thing
260 -> Int# -- size of thing to be frozen
261 -> State# s -- the Universe and everything
262 -> (# State# s, ByteArray# #)
265 = case (newCharArray# n# s1#) of { (# s2#, newarr1# #) ->
266 case copy 0# n# arr1# newarr1# s2# of { (# s3#, newarr2# #) ->
267 unsafeFreezeByteArray# newarr2# s3#
271 -> MutableByteArray# s -> MutableByteArray# s
273 -> (# State# s, MutableByteArray# s #)
275 copy cur# end# from# to# st#
279 = case (readCharArray# from# cur# st#) of { (# s2#, ele #) ->
280 case (writeCharArray# to# cur# ele s2#) of { s3# ->
281 copy (cur# +# 1#) end# from# to# s3#
284 freezeIntArray (MutableByteArray l u arr#) = ST $ \ s# ->
285 case rangeSize (l,u) of { I# n# ->
286 case freeze arr# n# s# of { (# s2#, frozen# #) ->
287 (# s2#, ByteArray l u frozen# #) }}
289 freeze :: MutableByteArray# s -- the thing
290 -> Int# -- size of thing to be frozen
291 -> State# s -- the Universe and everything
292 -> (# State# s, ByteArray# #)
295 = case (newIntArray# n# s#) of { (# s2#, newarr1# #) ->
296 case copy 0# n# m_arr# newarr1# s2# of { (# s3#, newarr2# #) ->
297 unsafeFreezeByteArray# newarr2# s3#
301 -> MutableByteArray# s -> MutableByteArray# s
303 -> (# State# s, MutableByteArray# s #)
305 copy cur# end# from# to# s1#
309 = case (readIntArray# from# cur# s1#) of { (# s2#, ele #) ->
310 case (writeIntArray# to# cur# ele s2#) of { s3# ->
311 copy (cur# +# 1#) end# from# to# s3#
314 freezeWordArray (MutableByteArray l u arr#) = ST $ \ s# ->
315 case rangeSize (l,u) of { I# n# ->
316 case freeze arr# n# s# of { (# s2#, frozen# #) ->
317 (# s2#, ByteArray l u frozen# #) }}
319 freeze :: MutableByteArray# s -- the thing
320 -> Int# -- size of thing to be frozen
321 -> State# s -- the Universe and everything
322 -> (# State# s, ByteArray# #)
325 = case (newWordArray# n# s1#) of { (# s2#, newarr1# #) ->
326 case copy 0# n# m_arr# newarr1# s2# of { (# s3#, newarr2# #) ->
327 unsafeFreezeByteArray# newarr2# s3#
331 -> MutableByteArray# s -> MutableByteArray# s
333 -> (# State# s, MutableByteArray# s #)
335 copy cur# end# from# to# st#
336 | cur# ==# end# = (# st#, to# #)
338 case (readWordArray# from# cur# st#) of { (# s2#, ele #) ->
339 case (writeWordArray# to# cur# ele s2#) of { s3# ->
340 copy (cur# +# 1#) end# from# to# s3#
343 freezeAddrArray (MutableByteArray l u arr#) = ST $ \ s# ->
344 case rangeSize (l,u) of { I# n# ->
345 case freeze arr# n# s# of { (# s2#, frozen# #) ->
346 (# s2#, ByteArray l u frozen# #) }}
348 freeze :: MutableByteArray# s -- the thing
349 -> Int# -- size of thing to be frozen
350 -> State# s -- the Universe and everything
351 -> (# State# s, ByteArray# #)
354 = case (newAddrArray# n# s1#) of { (# s2#, newarr1# #) ->
355 case copy 0# n# m_arr# newarr1# s2# of { (# s3#, newarr2# #) ->
356 unsafeFreezeByteArray# newarr2# s3#
360 -> MutableByteArray# s -> MutableByteArray# s
362 -> (# State# s, MutableByteArray# s #)
364 copy cur# end# from# to# st#
368 = case (readAddrArray# from# cur# st#) of { (# st1#, ele #) ->
369 case (writeAddrArray# to# cur# ele st1#) of { st2# ->
370 copy (cur# +# 1#) end# from# to# st2#
373 unsafeFreezeByteArray :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
375 {-# SPECIALIZE unsafeFreezeByteArray :: MutableByteArray s Int -> ST s (ByteArray Int)
378 unsafeFreezeByteArray (MutableByteArray l u arr#) = ST $ \ s# ->
379 case unsafeFreezeByteArray# arr# s# of { (# s2#, frozen# #) ->
380 (# s2#, ByteArray l u frozen# #) }