@@ -322,6 +322,7 @@ import Data.Maybe (fromJust, isJust, isNothing)
322import Data.Word (Word32)
322import Data.Word (Word32)
323import Foreign.Ptr (Ptr)
323import Foreign.Ptr (Ptr)
324import Foreign.Storable (Storable(..))
324import Foreign.Storable (Storable(..))
325+import GHC.Exts (SpecConstrAnnotation(..))
325import GHC.Types (SPEC(..))
326import GHC.Types (SPEC(..))
326import System.Mem (performMajorGC)
327import System.Mem (performMajorGC)
327import Fusion.Plugin.Types (Fuse(..))
328import Fusion.Plugin.Types (Fuse(..))
@@ -953,6 +954,11 @@ splitAt n ls
954 (xs', xs'') = splitAt' (m - 1) xs
955 (xs', xs'') = splitAt' (m - 1) xs
957+-- GHC parser does not accept {-# ANN type [] NoSpecConstr #-}, so we need
958+-- to make a newtype.
959+{-# ANN type List NoSpecConstr #-}
960+newtype List a = List {getList :: [a]}
956-- | Run a 'Parse' over a stream.
962-- | Run a 'Parse' over a stream.
957{-# INLINE_NORMAL parselMx' #-}
963{-# INLINE_NORMAL parselMx' #-}
@@ -963,7 +969,7 @@ parselMx'
963 -> Stream m a
969 -> Stream m a
965parselMx' pstep initial extract (Stream step state) = do
971parselMx' pstep initial extract (Stream step state) = do
966− initial >>= go SPEC state []
972+ initial >>= go SPEC state (List [])
@@ -977,40 +983,41 @@ parselMx' pstep initial extract (Stream step state) = do
977 Yield x s -> do
983 Yield x s -> do
978 pRes <- pstep pst x
984 pRes <- pstep pst x
979 case pRes of
985 case pRes of
980− PR.Partial 0 pst1 -> go SPEC s [] pst1
986+ PR.Partial 0 pst1 -> go SPEC s (List []) pst1
981 PR.Partial n pst1 -> do
987 PR.Partial n pst1 -> do
982− assert (n <= length (x:buf)) (return ())
988+ assert (n <= length (x:getList buf)) (return ())
983− let src0 = Prelude.take n (x:buf)
989+ let src0 = Prelude.take n (x:getList buf)
984 src = Prelude.reverse src0
990 src = Prelude.reverse src0
985− gobuf SPEC s [] src pst1
991+ gobuf SPEC s (List []) (List src) pst1
986− PR.Continue 0 pst1 -> go SPEC s (x:buf) pst1
992+ PR.Continue 0 pst1 -> go SPEC s (List (x:getList buf)) pst1
987 PR.Continue n pst1 -> do
993 PR.Continue n pst1 -> do
988− assert (n <= length (x:buf)) (return ())
994+ assert (n <= length (x:getList buf)) (return ())
989− let (src0, buf1) = splitAt n (x:buf)
995+ let (src0, buf1) = splitAt n (x:getList buf)
990 src = Prelude.reverse src0
996 src = Prelude.reverse src0
991− gobuf SPEC s buf1 src pst1
997+ gobuf SPEC s (List buf1) (List src) pst1
992 PR.Done _ b -> return b
998 PR.Done _ b -> return b
993 PR.Error err -> throwM $ ParseError err
999 PR.Error err -> throwM $ ParseError err
994 Skip s -> go SPEC s buf pst
1000 Skip s -> go SPEC s buf pst
995 Stop -> extract pst
1001 Stop -> extract pst
997− gobuf !_ s buf [] !pst = go SPEC s buf pst
1003+ gobuf !_ s buf (List []) !pst = go SPEC s buf pst
998− gobuf !_ s buf (x:xs) !pst = do
1004+ gobuf !_ s buf (List (x:xs)) !pst = do
999 pRes <- pstep pst x
1005 pRes <- pstep pst x
1000 case pRes of
1006 case pRes of
1001 PR.Partial 0 pst1 ->
1007 PR.Partial 0 pst1 ->
1002− gobuf SPEC s [] xs pst1
1008+ gobuf SPEC s (List []) (List xs) pst1
1003 PR.Partial n pst1 -> do
1009 PR.Partial n pst1 -> do
1004− assert (n <= length (x:buf)) (return ())
1010+ assert (n <= length (x:getList buf)) (return ())
1005− let src0 = Prelude.take n (x:buf)
1011+ let src0 = Prelude.take n (x:getList buf)
1006 src = Prelude.reverse src0 ++ xs
1012 src = Prelude.reverse src0 ++ xs
1007− gobuf SPEC s [] src pst1
1013+ gobuf SPEC s (List []) (List src) pst1
1008− PR.Continue 0 pst1 -> gobuf SPEC s (x:buf) xs pst1
1014+ PR.Continue 0 pst1 ->
1015+ gobuf SPEC s (List (x:getList buf)) (List xs) pst1
1009 PR.Continue n pst1 -> do
1016 PR.Continue n pst1 -> do
1010− assert (n <= length (x:buf)) (return ())
1017+ assert (n <= length (x:getList buf)) (return ())
1011− let (src0, buf1) = splitAt n (x:buf)
1018+ let (src0, buf1) = splitAt n (x:getList buf)
1012 src = Prelude.reverse src0 ++ xs
1019 src = Prelude.reverse src0 ++ xs
1013− gobuf SPEC s buf1 src pst1
1020+ gobuf SPEC s (List buf1) (List src) pst1
1014 PR.Done _ b -> return b
1021 PR.Done _ b -> return b
1015 PR.Error err -> throwM $ ParseError err
1022 PR.Error err -> throwM $ ParseError err