@@ -47,9 +47,6 @@ import Data.Functor.Const (Const(..))
47import Data.Functor.Identity (Identity(..))
47import Data.Functor.Identity (Identity(..))
48import Data.Kind (Type)
48import Data.Kind (Type)
49import Data.Proxy (Proxy (..))
49import Data.Proxy (Proxy (..))
51−import Debug.Trace (trace)
53import Foreign.Ptr (IntPtr(..), WordPtr(..))
50import Foreign.Ptr (IntPtr(..), WordPtr(..))
54import GHC.Base (IO(..))
51import GHC.Base (IO(..))
55import GHC.Fingerprint.Type (Fingerprint(..))
52import GHC.Fingerprint.Type (Fingerprint(..))
@@ -68,6 +65,9 @@ import GHC.TypeLits
68import Prelude hiding (read)
65import Prelude hiding (read)
70import Streamly.Internal.Data.MutByteArray.Type (MutByteArray(..))
67import Streamly.Internal.Data.MutByteArray.Type (MutByteArray(..))
69+import Streamly.Internal.Data.MutByteArray.Type (sizeOfMutableByteArray)
72--------------------------------------------------------------------------------
72--------------------------------------------------------------------------------
73-- The Unbox type class
73-- The Unbox type class
@@ -266,43 +266,66 @@ class Unbox a where
266{-# DEPRECATED peekByteIndex "Use peekAt." #-}
266{-# DEPRECATED peekByteIndex "Use peekAt." #-}
267{-# DEPRECATED pokeByteIndex "Use pokeAt." #-}
267{-# DEPRECATED pokeByteIndex "Use pokeAt." #-}
269−-- XXX Add asserts to check bounds
269+-- _size is the length from array start to the last accessed byte.
270+{-# INLINE checkBounds #-}
271+checkBounds :: String -> Int -> MutByteArray -> IO ()
272+checkBounds _label _size _arr = do
274+ sz <- sizeOfMutableByteArray _arr
278+ ++ ": accessing array at offset = "
280+ ++ " max valid offset = " ++ show (sz - 1)
271#define DERIVE_UNBOXED(_type, _constructor, _readArray, _writeArray, _sizeOf) \
286#define DERIVE_UNBOXED(_type, _constructor, _readArray, _writeArray, _sizeOf) \
272−instance Unbox _type where { \
287+instance Unbox _type where { \
273−; {-# INLINE peekAt #-} \
288+; {-# INLINE peekAt #-} \
274−; peekAt (I# n) (MutByteArray mbarr) = IO $ \s -> \
289+; peekAt off@(I# n) arr@(MutByteArray mbarr) = \
290+ checkBounds "peek" (off + sizeOf (Proxy :: Proxy _type)) arr \
275− case _readArray mbarr n s of \
292+ case _readArray mbarr n s of \
276− { (# s1, i #) -> (# s1, _constructor i #) } \
293+ { (# s1, i #) -> (# s1, _constructor i #) }) \
277−; {-# INLINE pokeAt #-} \
294+; {-# INLINE pokeAt #-} \
278−; pokeAt (I# n) (MutByteArray mbarr) (_constructor val) = \
295+; pokeAt off@(I# n) arr@(MutByteArray mbarr) (_constructor val) = \
296+ checkBounds "poke" (off + sizeOf (Proxy :: Proxy _type)) arr \
279− IO $ \s -> (# _writeArray mbarr n val s, () #) \
297+ >> (IO $ \s -> (# _writeArray mbarr n val s, () #)) \
280−; {-# INLINE sizeOf #-} \
298+; {-# INLINE sizeOf #-} \
281−; sizeOf _ = _sizeOf \
299+; sizeOf _ = _sizeOf \
284#define DERIVE_WRAPPED_UNBOX(_constraint, _type, _constructor, _innerType) \
302#define DERIVE_WRAPPED_UNBOX(_constraint, _type, _constructor, _innerType) \
285instance _constraint Unbox _type where \
303instance _constraint Unbox _type where \
286−; {-# INLINE peekAt #-} \
304+; {-# INLINE peekAt #-} \
306+ checkBounds "peek" (i + sizeOf (Proxy :: Proxy _type)) arr \
287−; peekAt i arr = _constructor <$> peekAt i arr \
307+ >> _constructor <$> peekAt i arr \
288−; {-# INLINE pokeAt #-} \
308+; {-# INLINE pokeAt #-} \
289−; pokeAt i arr (_constructor a) = pokeAt i arr a \
309+; pokeAt i arr (_constructor a) = \
310+ checkBounds "poke" (i + sizeOf (Proxy :: Proxy _type)) arr \
290; {-# INLINE sizeOf #-} \
312; {-# INLINE sizeOf #-} \
291; sizeOf _ = SIZE_OF(_innerType)
313; sizeOf _ = SIZE_OF(_innerType)
293−#define DERIVE_BINARY_UNBOX(_constraint, _type, _constructor, _innerType) \
315+#define DERIVE_BINARY_UNBOX(_constraint, _type, _constructor, _innerType) \
294−instance _constraint Unbox _type where { \
316+instance _constraint Unbox _type where { \
295−; {-# INLINE peekAt #-} \
317+; {-# INLINE peekAt #-} \
296−; peekAt i arr = \
318+; peekAt i arr = \
319+ checkBounds "peek" (i + sizeOf (Proxy :: Proxy _type)) arr >> \
297− peekAt i arr >>= \
320+ peekAt i arr >>= \
298− (\p1 -> peekAt (i + SIZE_OF(_innerType)) arr \
321+ (\p1 -> peekAt (i + SIZE_OF(_innerType)) arr <&> _constructor p1) \
299− <&> _constructor p1) \
300−; {-# INLINE pokeAt #-} \
322+; {-# INLINE pokeAt #-} \
301−; pokeAt i arr (_constructor p1 p2) = \
323+; pokeAt i arr (_constructor p1 p2) = \
324+ checkBounds "poke" (i + sizeOf (Proxy :: Proxy _type)) arr >> \
302− pokeAt i arr p1 >> \
325+ pokeAt i arr p1 >> \
303− pokeAt (i + SIZE_OF(_innerType)) arr p2 \
326+ pokeAt (i + SIZE_OF(_innerType)) arr p2 \
304−; {-# INLINE sizeOf #-} \
327+; {-# INLINE sizeOf #-} \
305−; sizeOf _ = 2 * SIZE_OF(_innerType) \
328+; sizeOf _ = 2 * SIZE_OF(_innerType) \
308-------------------------------------------------------------------------------
331-------------------------------------------------------------------------------
@@ -423,10 +446,12 @@ DERIVE_BINARY_UNBOX(,Fingerprint,Fingerprint,Word64)
423instance Unbox () where
446instance Unbox () where
425 {-# INLINE peekAt #-}
448 {-# INLINE peekAt #-}
426− peekAt _ _ = return ()
449+ peekAt i arr =
450+ checkBounds "peek ()" (i + sizeOf (Proxy :: Proxy ())) arr >> return ()
428 {-# INLINE pokeAt #-}
452 {-# INLINE pokeAt #-}
429− pokeAt _ _ _ = return ()
453+ pokeAt i arr _ =
454+ checkBounds "poke ()" (i + sizeOf (Proxy :: Proxy ())) arr >> return ()
431 {-# INLINE sizeOf #-}
456 {-# INLINE sizeOf #-}
432 sizeOf _ = 1
457 sizeOf _ = 1
@@ -435,10 +460,16 @@ instance Unbox () where
435instance Unbox IoSubSystem where
460instance Unbox IoSubSystem where
437 {-# INLINE peekAt #-}
462 {-# INLINE peekAt #-}
465+ "peek IoSubSystem" (i + sizeOf (Proxy :: Proxy IoSubSystem)) arr
438− peekAt i arr = toEnum <$> peekAt i arr
466+ >> toEnum <$> peekAt i arr
440 {-# INLINE pokeAt #-}
468 {-# INLINE pokeAt #-}
471+ "poke IoSubSystem" (i + sizeOf (Proxy :: Proxy IoSubSystem)) arr
441− pokeAt i arr a = pokeAt i arr (fromEnum a)
472+ >> pokeAt i arr (fromEnum a)
443 {-# INLINE sizeOf #-}
474 {-# INLINE sizeOf #-}
444 sizeOf _ = sizeOf (Proxy :: Proxy Int)
475 sizeOf _ = sizeOf (Proxy :: Proxy Int)
@@ -448,14 +479,16 @@ instance Unbox Bool where
449 {-# INLINE peekAt #-}
480 {-# INLINE peekAt #-}
450 peekAt i arr = do
481 peekAt i arr = do
482+ checkBounds "peek Bool" (i + sizeOf (Proxy :: Proxy Bool)) arr
451 res <- peekAt i arr
483 res <- peekAt i arr
452 return $ res /= (0 :: Int8)
484 return $ res /= (0 :: Int8)
454 {-# INLINE pokeAt #-}
486 {-# INLINE pokeAt #-}
455 pokeAt i arr a =
487 pokeAt i arr a =
488+ checkBounds "poke Bool" (i + sizeOf (Proxy :: Proxy Bool)) arr
457− then pokeAt i arr (1 :: Int8)
490+ then pokeAt i arr (1 :: Int8)
458− else pokeAt i arr (0 :: Int8)
491+ else pokeAt i arr (0 :: Int8)
460 {-# INLINE sizeOf #-}
493 {-# INLINE sizeOf #-}
461 sizeOf _ = 1
494 sizeOf _ = 1