on master help sign in
Use unsafeDupablePerformIO where possible
779189dJohan Tibell
Data/Text/Encoding.hs+3−3
@@ -72,11 +72,11 @@ import Foreign.Marshal.Utils (with)
72import Foreign.Ptr (Ptr, minusPtr, plusPtr)
72import Foreign.Ptr (Ptr, minusPtr, plusPtr)
73import Foreign.Storable (peek, poke)
73import Foreign.Storable (peek, poke)
74import GHC.Base (MutableByteArray#)
74import GHC.Base (MutableByteArray#)
75−import System.IO.Unsafe (unsafePerformIO)
76import qualified Data.Text.Array as A
75import qualified Data.Text.Array as A
77import qualified Data.Text.Encoding.Fusion as E
76import qualified Data.Text.Encoding.Fusion as E
78import qualified Data.Text.Encoding.Utf16 as U16
77import qualified Data.Text.Encoding.Utf16 as U16
79import qualified Data.Text.Fusion as F
78import qualified Data.Text.Fusion as F
79+import Data.Text.Unsafe (unsafeDupablePerformIO)
80
80
81-- $strict
81-- $strict
82--
82--
@@ -157,12 +157,12 @@ decodeUtf8 = decodeUtf8With strictDecode
157-- If the input contains any invalid UTF-8 data, the relevant
157-- If the input contains any invalid UTF-8 data, the relevant
158-- exception will be returned, otherwise the decoded text.
158-- exception will be returned, otherwise the decoded text.
159decodeUtf8' :: ByteString -> Either UnicodeException Text
159decodeUtf8' :: ByteString -> Either UnicodeException Text
160−decodeUtf8' = unsafePerformIO . try . evaluate . decodeUtf8With strictDecode
160+decodeUtf8' = unsafeDupablePerformIO . try . evaluate . decodeUtf8With strictDecode
161{-# INLINE decodeUtf8' #-}
161{-# INLINE decodeUtf8' #-}
162
162
163-- | Encode text using UTF-8 encoding.
163-- | Encode text using UTF-8 encoding.
164encodeUtf8 :: Text -> ByteString
164encodeUtf8 :: Text -> ByteString
165−encodeUtf8 (Text arr off len) = unsafePerformIO $ do
165+encodeUtf8 (Text arr off len) = unsafeDupablePerformIO $ do
166 let size0 = max len 4
166 let size0 = max len 4
167 mallocByteString size0 >>= start size0 off 0
167 mallocByteString size0 >>= start size0 off 0
168 where
168 where
Data/Text/Encoding/Fusion.hs+2−2
@@ -44,12 +44,12 @@ import Data.Text.UnsafeShift (shiftL, shiftR)
44import Data.Word (Word8, Word16, Word32)
44import Data.Word (Word8, Word16, Word32)
45import Foreign.ForeignPtr (withForeignPtr, ForeignPtr)
45import Foreign.ForeignPtr (withForeignPtr, ForeignPtr)
46import Foreign.Storable (pokeByteOff)
46import Foreign.Storable (pokeByteOff)
47−import System.IO.Unsafe (unsafePerformIO)
48import qualified Data.ByteString as B
47import qualified Data.ByteString as B
49import qualified Data.ByteString.Unsafe as B
48import qualified Data.ByteString.Unsafe as B
50import qualified Data.Text.Encoding.Utf8 as U8
49import qualified Data.Text.Encoding.Utf8 as U8
51import qualified Data.Text.Encoding.Utf16 as U16
50import qualified Data.Text.Encoding.Utf16 as U16
52import qualified Data.Text.Encoding.Utf32 as U32
51import qualified Data.Text.Encoding.Utf32 as U32
52+import Data.Text.Unsafe (unsafeDupablePerformIO)
53
53
54streamASCII :: ByteString -> Stream Char
54streamASCII :: ByteString -> Stream Char
55streamASCII bs = Stream next 0 (maxSize l)
55streamASCII bs = Stream next 0 (maxSize l)
@@ -163,7 +163,7 @@ streamUtf32LE onErr bs = Stream next 0 (maxSize (l `shiftR` 2))
163
163
164-- | /O(n)/ Convert a 'Stream' 'Word8' to a 'ByteString'.
164-- | /O(n)/ Convert a 'Stream' 'Word8' to a 'ByteString'.
165unstream :: Stream Word8 -> ByteString
165unstream :: Stream Word8 -> ByteString
166−unstream (Stream next s0 len) = unsafePerformIO $ do
166+unstream (Stream next s0 len) = unsafeDupablePerformIO $ do
167 let mlen = upperBound 4 len
167 let mlen = upperBound 4 len
168 mallocByteString mlen >>= loop mlen 0 s0
168 mallocByteString mlen >>= loop mlen 0 s0
169 where
169 where
Data/Text/Lazy/Encoding.hs+2−2
@@ -52,7 +52,6 @@ import Control.Exception (evaluate, try)
52import Data.Bits ((.&.))
52import Data.Bits ((.&.))
53import Data.Text.Encoding.Error (OnDecodeError, UnicodeException, strictDecode)
53import Data.Text.Encoding.Error (OnDecodeError, UnicodeException, strictDecode)
54import Data.Text.Lazy.Internal (Text(..), chunk, empty, foldrChunks)
54import Data.Text.Lazy.Internal (Text(..), chunk, empty, foldrChunks)
55−import System.IO.Unsafe (unsafePerformIO)
56import qualified Data.ByteString as S
55import qualified Data.ByteString as S
57import qualified Data.ByteString.Lazy as B
56import qualified Data.ByteString.Lazy as B
58import qualified Data.ByteString.Lazy.Internal as B
57import qualified Data.ByteString.Lazy.Internal as B
@@ -61,6 +60,7 @@ import qualified Data.Text as T
61import qualified Data.Text.Encoding as TE
60import qualified Data.Text.Encoding as TE
62import qualified Data.Text.Lazy.Encoding.Fusion as E
61import qualified Data.Text.Lazy.Encoding.Fusion as E
63import qualified Data.Text.Lazy.Fusion as F
62import qualified Data.Text.Lazy.Fusion as F
63+import Data.Text.Unsafe (unsafeDupablePerformIO)
64
64
65-- $strict
65-- $strict
66--
66--
@@ -149,7 +149,7 @@ decodeUtf8 = decodeUtf8With strictDecode
149-- input before it can return a result. If you need lazy (streaming)
149-- input before it can return a result. If you need lazy (streaming)
150-- decoding, use 'decodeUtf8With' in lenient mode.
150-- decoding, use 'decodeUtf8With' in lenient mode.
151decodeUtf8' :: B.ByteString -> Either UnicodeException Text
151decodeUtf8' :: B.ByteString -> Either UnicodeException Text
152−decodeUtf8' bs = unsafePerformIO $ do
152+decodeUtf8' bs = unsafeDupablePerformIO $ do
153 let t = decodeUtf8 bs
153 let t = decodeUtf8 bs
154 try (evaluate (rnf t `seq` t))
154 try (evaluate (rnf t `seq` t))
155 where
155 where
Data/Text/Lazy/Encoding/Fusion.hs+2−2
@@ -42,7 +42,7 @@ import Data.Word (Word8, Word16, Word32)
42import qualified Data.Text.Encoding.Utf8 as U8
42import qualified Data.Text.Encoding.Utf8 as U8
43import qualified Data.Text.Encoding.Utf16 as U16
43import qualified Data.Text.Encoding.Utf16 as U16
44import qualified Data.Text.Encoding.Utf32 as U32
44import qualified Data.Text.Encoding.Utf32 as U32
45−import System.IO.Unsafe (unsafePerformIO)
45+import Data.Text.Unsafe (unsafeDupablePerformIO)
46import Foreign.ForeignPtr (withForeignPtr, ForeignPtr)
46import Foreign.ForeignPtr (withForeignPtr, ForeignPtr)
47import Foreign.Storable (pokeByteOff)
47import Foreign.Storable (pokeByteOff)
48import Data.ByteString.Internal (mallocByteString, memcpy)
48import Data.ByteString.Internal (mallocByteString, memcpy)
@@ -272,7 +272,7 @@ streamUtf32LE onErr bs0 = Stream next (T bs0 S0 0) unknownSize
272-- | /O(n)/ Convert a 'Stream' 'Word8' to a lazy 'ByteString'.
272-- | /O(n)/ Convert a 'Stream' 'Word8' to a lazy 'ByteString'.
273unstreamChunks :: Int -> Stream Word8 -> ByteString
273unstreamChunks :: Int -> Stream Word8 -> ByteString
274unstreamChunks chunkSize (Stream next s0 len0) = chunk s0 (upperBound 4 len0)
274unstreamChunks chunkSize (Stream next s0 len0) = chunk s0 (upperBound 4 len0)
275− where chunk s1 len1 = unsafePerformIO $ do
275+ where chunk s1 len1 = unsafeDupablePerformIO $ do
276 let len = max 4 (min len1 chunkSize)
276 let len = max 4 (min len1 chunkSize)
277 mallocByteString len >>= loop len 0 s1
277 mallocByteString len >>= loop len 0 s1
278 where
278 where
Data/Text/Unsafe.hs+6
@@ -14,6 +14,7 @@ module Data.Text.Unsafe
14 (
14 (
15 inlineInterleaveST
15 inlineInterleaveST
16 , inlinePerformIO
16 , inlinePerformIO
17+ , unsafeDupablePerformIO
17 , Iter(..)
18 , Iter(..)
18 , iter
19 , iter
19 , iter_
20 , iter_
@@ -33,6 +34,11 @@ import Data.Text.Internal (Text(..))
33import Data.Text.Unsafe.Base (inlineInterleaveST, inlinePerformIO)
34import Data.Text.Unsafe.Base (inlineInterleaveST, inlinePerformIO)
34import Data.Text.UnsafeChar (unsafeChr)
35import Data.Text.UnsafeChar (unsafeChr)
35import qualified Data.Text.Array as A
36import qualified Data.Text.Array as A
37+#if __GLASGOW_HASKELL__ >= 611
38+import GHC.IO (unsafeDupablePerformIO)
39+#else
40+import GHC.IOBase (unsafeDupablePerformIO)
41+#endif
36
42
37-- | /O(1)/ A variant of 'head' for non-empty 'Text'. 'unsafeHead'
43-- | /O(1)/ A variant of 'head' for non-empty 'Text'. 'unsafeHead'
38-- omits the check for the empty case, so there is an obligation on
44-- omits the check for the empty case, so there is an obligation on