@@ -1,5 +1,5 @@
11{-# LANGUAGE BangPatterns, CPP, Rank2Types, OverloadedStrings,
2− RecordWildCards #-}
2+ RecordWildCards, MagicHash, UnboxedTuples #-}
33-- |
44-- Module : Data.Attoparsec.ByteString.Internal
55-- Copyright : Bryan O'Sullivan 2007-2011
@@ -76,7 +76,6 @@ import Foreign.ForeignPtr (withForeignPtr)
7676import Foreign.Ptr (castPtr, minusPtr, plusPtr)
7777import Foreign.Storable (Storable(peek, sizeOf))
7878import Prelude hiding (getChar, take, takeWhile)
79−import System.IO.Unsafe (unsafeDupablePerformIO)
8079import qualified Data.Attoparsec.Internal.Types as T
8180import qualified Data.ByteString as B8
8281import qualified Data.ByteString.Char8 as B
@@ -85,8 +84,12 @@ import qualified Data.ByteString.Lazy as L
8584import qualified Data.ByteString.Unsafe as B
8685
8786#if defined(__GLASGOW_HASKELL__)
87+import GHC.Base (realWorld#)
8888import GHC.Exts (inline)
89+import GHC.IO (IO(IO))
8990#else
91+import System.IO.Unsafe (unsafePerformIO)
92+
9093inline :: a -> a
9194inline x = x
9295#endif
@@ -362,7 +365,7 @@ scan s0 p = do
362365 done !i !s = return (T i s)
363366 inner start s1
364367 bs <- get
365− let T i s' = unsafeDupablePerformIO $ scanner bs
368+ let T i s' = inlinePerformIO $ scanner bs
366369 !h = B.unsafeTake i bs
367370 !t = B.unsafeDrop i bs
368371 put t
@@ -503,3 +506,15 @@ parseOnly m s = case T.runParser m (I s) (A B.empty) Complete failK successK of
503506 Done _ a -> Right a
504507 _ -> error "parseOnly: impossible error!"
505508{-# INLINE parseOnly #-}
509+
510+-- | Just like unsafePerformIO, but we inline it. Big performance gains as
511+-- it exposes lots of things to further inlining. /Very unsafe/. In
512+-- particular, you should do no memory allocation inside an
513+-- 'inlinePerformIO' block. On Hugs this is just @unsafePerformIO@.
514+inlinePerformIO :: IO a -> a
515+#if defined(__GLASGOW_HASKELL__)
516+inlinePerformIO (IO m) = case m realWorld# of (# _, r #) -> r
517+#else
518+inlinePerformIO = unsafePerformIO
519+#endif
520+{-# INLINE inlinePerformIO #-}