PageRenderTime 75ms CodeModel.GetById 7ms RepoModel.GetById 1ms app.codeStats 0ms

/compiler/utils/Binary.hs

http://github.com/ghc/ghc
Haskell | 943 lines | 661 code | 131 blank | 151 comment | 15 complexity | dccbb5263c5e01c58f61a317e864df61 MD5 | raw file
Possible License(s): MIT, BSD-3-Clause, GPL-3.0
  1. {-# LANGUAGE CPP, MagicHash, UnboxedTuples #-}
  2. {-# LANGUAGE FlexibleInstances #-}
  3. {-# OPTIONS_GHC -O -funbox-strict-fields #-}
  4. -- We always optimise this, otherwise performance of a non-optimised
  5. -- compiler is severely affected
  6. --
  7. -- (c) The University of Glasgow 2002-2006
  8. --
  9. -- Binary I/O library, with special tweaks for GHC
  10. --
  11. -- Based on the nhc98 Binary library, which is copyright
  12. -- (c) Malcolm Wallace and Colin Runciman, University of York, 1998.
  13. -- Under the terms of the license for that software, we must tell you
  14. -- where you can obtain the original version of the Binary library, namely
  15. -- http://www.cs.york.ac.uk/fp/nhc98/
  16. module Binary
  17. ( {-type-} Bin,
  18. {-class-} Binary(..),
  19. {-type-} BinHandle,
  20. SymbolTable, Dictionary,
  21. openBinMem,
  22. -- closeBin,
  23. seekBin,
  24. seekBy,
  25. tellBin,
  26. castBin,
  27. writeBinMem,
  28. readBinMem,
  29. fingerprintBinMem,
  30. computeFingerprint,
  31. isEOFBin,
  32. putAt, getAt,
  33. -- for writing instances:
  34. putByte,
  35. getByte,
  36. -- lazy Bin I/O
  37. lazyGet,
  38. lazyPut,
  39. UserData(..), getUserData, setUserData,
  40. newReadState, newWriteState,
  41. putDictionary, getDictionary, putFS,
  42. ) where
  43. #include "HsVersions.h"
  44. -- The *host* architecture version:
  45. #include "../includes/MachDeps.h"
  46. import {-# SOURCE #-} Name (Name)
  47. import FastString
  48. import Panic
  49. import UniqFM
  50. import FastMutInt
  51. import Fingerprint
  52. import BasicTypes
  53. import SrcLoc
  54. import Foreign
  55. import Data.Array
  56. import Data.ByteString (ByteString)
  57. import qualified Data.ByteString as BS
  58. import qualified Data.ByteString.Unsafe as BS
  59. import Data.IORef
  60. import Data.Char ( ord, chr )
  61. import Data.Time
  62. import Data.Typeable
  63. import Control.Monad ( when )
  64. import System.IO as IO
  65. import System.IO.Unsafe ( unsafeInterleaveIO )
  66. import System.IO.Error ( mkIOError, eofErrorType )
  67. import GHC.Real ( Ratio(..) )
  68. import GHC.Serialized
  69. type BinArray = ForeignPtr Word8
  70. ---------------------------------------------------------------
  71. -- BinHandle
  72. ---------------------------------------------------------------
  73. data BinHandle
  74. = BinMem { -- binary data stored in an unboxed array
  75. bh_usr :: UserData, -- sigh, need parameterized modules :-)
  76. _off_r :: !FastMutInt, -- the current offset
  77. _sz_r :: !FastMutInt, -- size of the array (cached)
  78. _arr_r :: !(IORef BinArray) -- the array (bounds: (0,size-1))
  79. }
  80. -- XXX: should really store a "high water mark" for dumping out
  81. -- the binary data to a file.
  82. getUserData :: BinHandle -> UserData
  83. getUserData bh = bh_usr bh
  84. setUserData :: BinHandle -> UserData -> BinHandle
  85. setUserData bh us = bh { bh_usr = us }
  86. ---------------------------------------------------------------
  87. -- Bin
  88. ---------------------------------------------------------------
  89. newtype Bin a = BinPtr Int
  90. deriving (Eq, Ord, Show, Bounded)
  91. castBin :: Bin a -> Bin b
  92. castBin (BinPtr i) = BinPtr i
  93. ---------------------------------------------------------------
  94. -- class Binary
  95. ---------------------------------------------------------------
  96. class Binary a where
  97. put_ :: BinHandle -> a -> IO ()
  98. put :: BinHandle -> a -> IO (Bin a)
  99. get :: BinHandle -> IO a
  100. -- define one of put_, put. Use of put_ is recommended because it
  101. -- is more likely that tail-calls can kick in, and we rarely need the
  102. -- position return value.
  103. put_ bh a = do _ <- put bh a; return ()
  104. put bh a = do p <- tellBin bh; put_ bh a; return p
  105. putAt :: Binary a => BinHandle -> Bin a -> a -> IO ()
  106. putAt bh p x = do seekBin bh p; put_ bh x; return ()
  107. getAt :: Binary a => BinHandle -> Bin a -> IO a
  108. getAt bh p = do seekBin bh p; get bh
  109. openBinMem :: Int -> IO BinHandle
  110. openBinMem size
  111. | size <= 0 = error "Data.Binary.openBinMem: size must be >= 0"
  112. | otherwise = do
  113. arr <- mallocForeignPtrBytes size
  114. arr_r <- newIORef arr
  115. ix_r <- newFastMutInt
  116. writeFastMutInt ix_r 0
  117. sz_r <- newFastMutInt
  118. writeFastMutInt sz_r size
  119. return (BinMem noUserData ix_r sz_r arr_r)
  120. tellBin :: BinHandle -> IO (Bin a)
  121. tellBin (BinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix)
  122. seekBin :: BinHandle -> Bin a -> IO ()
  123. seekBin h@(BinMem _ ix_r sz_r _) (BinPtr p) = do
  124. sz <- readFastMutInt sz_r
  125. if (p >= sz)
  126. then do expandBin h p; writeFastMutInt ix_r p
  127. else writeFastMutInt ix_r p
  128. seekBy :: BinHandle -> Int -> IO ()
  129. seekBy h@(BinMem _ ix_r sz_r _) off = do
  130. sz <- readFastMutInt sz_r
  131. ix <- readFastMutInt ix_r
  132. let ix' = ix + off
  133. if (ix' >= sz)
  134. then do expandBin h ix'; writeFastMutInt ix_r ix'
  135. else writeFastMutInt ix_r ix'
  136. isEOFBin :: BinHandle -> IO Bool
  137. isEOFBin (BinMem _ ix_r sz_r _) = do
  138. ix <- readFastMutInt ix_r
  139. sz <- readFastMutInt sz_r
  140. return (ix >= sz)
  141. writeBinMem :: BinHandle -> FilePath -> IO ()
  142. writeBinMem (BinMem _ ix_r _ arr_r) fn = do
  143. h <- openBinaryFile fn WriteMode
  144. arr <- readIORef arr_r
  145. ix <- readFastMutInt ix_r
  146. withForeignPtr arr $ \p -> hPutBuf h p ix
  147. hClose h
  148. readBinMem :: FilePath -> IO BinHandle
  149. -- Return a BinHandle with a totally undefined State
  150. readBinMem filename = do
  151. h <- openBinaryFile filename ReadMode
  152. filesize' <- hFileSize h
  153. let filesize = fromIntegral filesize'
  154. arr <- mallocForeignPtrBytes (filesize*2)
  155. count <- withForeignPtr arr $ \p -> hGetBuf h p filesize
  156. when (count /= filesize) $
  157. error ("Binary.readBinMem: only read " ++ show count ++ " bytes")
  158. hClose h
  159. arr_r <- newIORef arr
  160. ix_r <- newFastMutInt
  161. writeFastMutInt ix_r 0
  162. sz_r <- newFastMutInt
  163. writeFastMutInt sz_r filesize
  164. return (BinMem noUserData ix_r sz_r arr_r)
  165. fingerprintBinMem :: BinHandle -> IO Fingerprint
  166. fingerprintBinMem (BinMem _ ix_r _ arr_r) = do
  167. arr <- readIORef arr_r
  168. ix <- readFastMutInt ix_r
  169. withForeignPtr arr $ \p -> fingerprintData p ix
  170. computeFingerprint :: Binary a
  171. => (BinHandle -> Name -> IO ())
  172. -> a
  173. -> IO Fingerprint
  174. computeFingerprint put_name a = do
  175. bh <- openBinMem (3*1024) -- just less than a block
  176. bh <- return $ setUserData bh $ newWriteState put_name putFS
  177. put_ bh a
  178. fingerprintBinMem bh
  179. -- expand the size of the array to include a specified offset
  180. expandBin :: BinHandle -> Int -> IO ()
  181. expandBin (BinMem _ _ sz_r arr_r) off = do
  182. sz <- readFastMutInt sz_r
  183. let sz' = head (dropWhile (<= off) (iterate (* 2) sz))
  184. arr <- readIORef arr_r
  185. arr' <- mallocForeignPtrBytes sz'
  186. withForeignPtr arr $ \old ->
  187. withForeignPtr arr' $ \new ->
  188. copyBytes new old sz
  189. writeFastMutInt sz_r sz'
  190. writeIORef arr_r arr'
  191. -- -----------------------------------------------------------------------------
  192. -- Low-level reading/writing of bytes
  193. putWord8 :: BinHandle -> Word8 -> IO ()
  194. putWord8 h@(BinMem _ ix_r sz_r arr_r) w = do
  195. ix <- readFastMutInt ix_r
  196. sz <- readFastMutInt sz_r
  197. -- double the size of the array if it overflows
  198. if (ix >= sz)
  199. then do expandBin h ix
  200. putWord8 h w
  201. else do arr <- readIORef arr_r
  202. withForeignPtr arr $ \p -> pokeByteOff p ix w
  203. writeFastMutInt ix_r (ix+1)
  204. return ()
  205. getWord8 :: BinHandle -> IO Word8
  206. getWord8 (BinMem _ ix_r sz_r arr_r) = do
  207. ix <- readFastMutInt ix_r
  208. sz <- readFastMutInt sz_r
  209. when (ix >= sz) $
  210. ioError (mkIOError eofErrorType "Data.Binary.getWord8" Nothing Nothing)
  211. arr <- readIORef arr_r
  212. w <- withForeignPtr arr $ \p -> peekByteOff p ix
  213. writeFastMutInt ix_r (ix+1)
  214. return w
  215. putByte :: BinHandle -> Word8 -> IO ()
  216. putByte bh w = put_ bh w
  217. getByte :: BinHandle -> IO Word8
  218. getByte = getWord8
  219. -- -----------------------------------------------------------------------------
  220. -- Primitve Word writes
  221. instance Binary Word8 where
  222. put_ = putWord8
  223. get = getWord8
  224. instance Binary Word16 where
  225. put_ h w = do -- XXX too slow.. inline putWord8?
  226. putByte h (fromIntegral (w `shiftR` 8))
  227. putByte h (fromIntegral (w .&. 0xff))
  228. get h = do
  229. w1 <- getWord8 h
  230. w2 <- getWord8 h
  231. return $! ((fromIntegral w1 `shiftL` 8) .|. fromIntegral w2)
  232. instance Binary Word32 where
  233. put_ h w = do
  234. putByte h (fromIntegral (w `shiftR` 24))
  235. putByte h (fromIntegral ((w `shiftR` 16) .&. 0xff))
  236. putByte h (fromIntegral ((w `shiftR` 8) .&. 0xff))
  237. putByte h (fromIntegral (w .&. 0xff))
  238. get h = do
  239. w1 <- getWord8 h
  240. w2 <- getWord8 h
  241. w3 <- getWord8 h
  242. w4 <- getWord8 h
  243. return $! ((fromIntegral w1 `shiftL` 24) .|.
  244. (fromIntegral w2 `shiftL` 16) .|.
  245. (fromIntegral w3 `shiftL` 8) .|.
  246. (fromIntegral w4))
  247. instance Binary Word64 where
  248. put_ h w = do
  249. putByte h (fromIntegral (w `shiftR` 56))
  250. putByte h (fromIntegral ((w `shiftR` 48) .&. 0xff))
  251. putByte h (fromIntegral ((w `shiftR` 40) .&. 0xff))
  252. putByte h (fromIntegral ((w `shiftR` 32) .&. 0xff))
  253. putByte h (fromIntegral ((w `shiftR` 24) .&. 0xff))
  254. putByte h (fromIntegral ((w `shiftR` 16) .&. 0xff))
  255. putByte h (fromIntegral ((w `shiftR` 8) .&. 0xff))
  256. putByte h (fromIntegral (w .&. 0xff))
  257. get h = do
  258. w1 <- getWord8 h
  259. w2 <- getWord8 h
  260. w3 <- getWord8 h
  261. w4 <- getWord8 h
  262. w5 <- getWord8 h
  263. w6 <- getWord8 h
  264. w7 <- getWord8 h
  265. w8 <- getWord8 h
  266. return $! ((fromIntegral w1 `shiftL` 56) .|.
  267. (fromIntegral w2 `shiftL` 48) .|.
  268. (fromIntegral w3 `shiftL` 40) .|.
  269. (fromIntegral w4 `shiftL` 32) .|.
  270. (fromIntegral w5 `shiftL` 24) .|.
  271. (fromIntegral w6 `shiftL` 16) .|.
  272. (fromIntegral w7 `shiftL` 8) .|.
  273. (fromIntegral w8))
  274. -- -----------------------------------------------------------------------------
  275. -- Primitve Int writes
  276. instance Binary Int8 where
  277. put_ h w = put_ h (fromIntegral w :: Word8)
  278. get h = do w <- get h; return $! (fromIntegral (w::Word8))
  279. instance Binary Int16 where
  280. put_ h w = put_ h (fromIntegral w :: Word16)
  281. get h = do w <- get h; return $! (fromIntegral (w::Word16))
  282. instance Binary Int32 where
  283. put_ h w = put_ h (fromIntegral w :: Word32)
  284. get h = do w <- get h; return $! (fromIntegral (w::Word32))
  285. instance Binary Int64 where
  286. put_ h w = put_ h (fromIntegral w :: Word64)
  287. get h = do w <- get h; return $! (fromIntegral (w::Word64))
  288. -- -----------------------------------------------------------------------------
  289. -- Instances for standard types
  290. instance Binary () where
  291. put_ _ () = return ()
  292. get _ = return ()
  293. instance Binary Bool where
  294. put_ bh b = putByte bh (fromIntegral (fromEnum b))
  295. get bh = do x <- getWord8 bh; return $! (toEnum (fromIntegral x))
  296. instance Binary Char where
  297. put_ bh c = put_ bh (fromIntegral (ord c) :: Word32)
  298. get bh = do x <- get bh; return $! (chr (fromIntegral (x :: Word32)))
  299. instance Binary Int where
  300. put_ bh i = put_ bh (fromIntegral i :: Int64)
  301. get bh = do
  302. x <- get bh
  303. return $! (fromIntegral (x :: Int64))
  304. instance Binary a => Binary [a] where
  305. put_ bh l = do
  306. let len = length l
  307. if (len < 0xff)
  308. then putByte bh (fromIntegral len :: Word8)
  309. else do putByte bh 0xff; put_ bh (fromIntegral len :: Word32)
  310. mapM_ (put_ bh) l
  311. get bh = do
  312. b <- getByte bh
  313. len <- if b == 0xff
  314. then get bh
  315. else return (fromIntegral b :: Word32)
  316. let loop 0 = return []
  317. loop n = do a <- get bh; as <- loop (n-1); return (a:as)
  318. loop len
  319. instance (Binary a, Binary b) => Binary (a,b) where
  320. put_ bh (a,b) = do put_ bh a; put_ bh b
  321. get bh = do a <- get bh
  322. b <- get bh
  323. return (a,b)
  324. instance (Binary a, Binary b, Binary c) => Binary (a,b,c) where
  325. put_ bh (a,b,c) = do put_ bh a; put_ bh b; put_ bh c
  326. get bh = do a <- get bh
  327. b <- get bh
  328. c <- get bh
  329. return (a,b,c)
  330. instance (Binary a, Binary b, Binary c, Binary d) => Binary (a,b,c,d) where
  331. put_ bh (a,b,c,d) = do put_ bh a; put_ bh b; put_ bh c; put_ bh d
  332. get bh = do a <- get bh
  333. b <- get bh
  334. c <- get bh
  335. d <- get bh
  336. return (a,b,c,d)
  337. instance (Binary a, Binary b, Binary c, Binary d, Binary e) => Binary (a,b,c,d, e) where
  338. put_ bh (a,b,c,d, e) = do put_ bh a; put_ bh b; put_ bh c; put_ bh d; put_ bh e;
  339. get bh = do a <- get bh
  340. b <- get bh
  341. c <- get bh
  342. d <- get bh
  343. e <- get bh
  344. return (a,b,c,d,e)
  345. instance (Binary a, Binary b, Binary c, Binary d, Binary e, Binary f) => Binary (a,b,c,d, e, f) where
  346. put_ bh (a,b,c,d, e, f) = do put_ bh a; put_ bh b; put_ bh c; put_ bh d; put_ bh e; put_ bh f;
  347. get bh = do a <- get bh
  348. b <- get bh
  349. c <- get bh
  350. d <- get bh
  351. e <- get bh
  352. f <- get bh
  353. return (a,b,c,d,e,f)
  354. instance Binary a => Binary (Maybe a) where
  355. put_ bh Nothing = putByte bh 0
  356. put_ bh (Just a) = do putByte bh 1; put_ bh a
  357. get bh = do h <- getWord8 bh
  358. case h of
  359. 0 -> return Nothing
  360. _ -> do x <- get bh; return (Just x)
  361. instance (Binary a, Binary b) => Binary (Either a b) where
  362. put_ bh (Left a) = do putByte bh 0; put_ bh a
  363. put_ bh (Right b) = do putByte bh 1; put_ bh b
  364. get bh = do h <- getWord8 bh
  365. case h of
  366. 0 -> do a <- get bh ; return (Left a)
  367. _ -> do b <- get bh ; return (Right b)
  368. instance Binary UTCTime where
  369. put_ bh u = do put_ bh (utctDay u)
  370. put_ bh (utctDayTime u)
  371. get bh = do day <- get bh
  372. dayTime <- get bh
  373. return $ UTCTime { utctDay = day, utctDayTime = dayTime }
  374. instance Binary Day where
  375. put_ bh d = put_ bh (toModifiedJulianDay d)
  376. get bh = do i <- get bh
  377. return $ ModifiedJulianDay { toModifiedJulianDay = i }
  378. instance Binary DiffTime where
  379. put_ bh dt = put_ bh (toRational dt)
  380. get bh = do r <- get bh
  381. return $ fromRational r
  382. --to quote binary-0.3 on this code idea,
  383. --
  384. -- TODO This instance is not architecture portable. GMP stores numbers as
  385. -- arrays of machine sized words, so the byte format is not portable across
  386. -- architectures with different endianess and word size.
  387. --
  388. -- This makes it hard (impossible) to make an equivalent instance
  389. -- with code that is compilable with non-GHC. Do we need any instance
  390. -- Binary Integer, and if so, does it have to be blazing fast? Or can
  391. -- we just change this instance to be portable like the rest of the
  392. -- instances? (binary package has code to steal for that)
  393. --
  394. -- yes, we need Binary Integer and Binary Rational in basicTypes/Literal.hs
  395. instance Binary Integer where
  396. -- XXX This is hideous
  397. put_ bh i = put_ bh (show i)
  398. get bh = do str <- get bh
  399. case reads str of
  400. [(i, "")] -> return i
  401. _ -> fail ("Binary Integer: got " ++ show str)
  402. {-
  403. -- This code is currently commented out.
  404. -- See https://ghc.haskell.org/trac/ghc/ticket/3379#comment:10 for
  405. -- discussion.
  406. put_ bh (S# i#) = do putByte bh 0; put_ bh (I# i#)
  407. put_ bh (J# s# a#) = do
  408. putByte bh 1
  409. put_ bh (I# s#)
  410. let sz# = sizeofByteArray# a# -- in *bytes*
  411. put_ bh (I# sz#) -- in *bytes*
  412. putByteArray bh a# sz#
  413. get bh = do
  414. b <- getByte bh
  415. case b of
  416. 0 -> do (I# i#) <- get bh
  417. return (S# i#)
  418. _ -> do (I# s#) <- get bh
  419. sz <- get bh
  420. (BA a#) <- getByteArray bh sz
  421. return (J# s# a#)
  422. putByteArray :: BinHandle -> ByteArray# -> Int# -> IO ()
  423. putByteArray bh a s# = loop 0#
  424. where loop n#
  425. | n# ==# s# = return ()
  426. | otherwise = do
  427. putByte bh (indexByteArray a n#)
  428. loop (n# +# 1#)
  429. getByteArray :: BinHandle -> Int -> IO ByteArray
  430. getByteArray bh (I# sz) = do
  431. (MBA arr) <- newByteArray sz
  432. let loop n
  433. | n ==# sz = return ()
  434. | otherwise = do
  435. w <- getByte bh
  436. writeByteArray arr n w
  437. loop (n +# 1#)
  438. loop 0#
  439. freezeByteArray arr
  440. -}
  441. {-
  442. data ByteArray = BA ByteArray#
  443. data MBA = MBA (MutableByteArray# RealWorld)
  444. newByteArray :: Int# -> IO MBA
  445. newByteArray sz = IO $ \s ->
  446. case newByteArray# sz s of { (# s, arr #) ->
  447. (# s, MBA arr #) }
  448. freezeByteArray :: MutableByteArray# RealWorld -> IO ByteArray
  449. freezeByteArray arr = IO $ \s ->
  450. case unsafeFreezeByteArray# arr s of { (# s, arr #) ->
  451. (# s, BA arr #) }
  452. writeByteArray :: MutableByteArray# RealWorld -> Int# -> Word8 -> IO ()
  453. writeByteArray arr i (W8# w) = IO $ \s ->
  454. case writeWord8Array# arr i w s of { s ->
  455. (# s, () #) }
  456. indexByteArray :: ByteArray# -> Int# -> Word8
  457. indexByteArray a# n# = W8# (indexWord8Array# a# n#)
  458. -}
  459. instance (Binary a) => Binary (Ratio a) where
  460. put_ bh (a :% b) = do put_ bh a; put_ bh b
  461. get bh = do a <- get bh; b <- get bh; return (a :% b)
  462. instance Binary (Bin a) where
  463. put_ bh (BinPtr i) = put_ bh (fromIntegral i :: Int32)
  464. get bh = do i <- get bh; return (BinPtr (fromIntegral (i :: Int32)))
  465. -- -----------------------------------------------------------------------------
  466. -- Instances for Data.Typeable stuff
  467. instance Binary TyCon where
  468. put_ bh tc = do
  469. put_ bh (tyConPackage tc)
  470. put_ bh (tyConModule tc)
  471. put_ bh (tyConName tc)
  472. get bh = do
  473. p <- get bh
  474. m <- get bh
  475. n <- get bh
  476. return (mkTyCon3 p m n)
  477. instance Binary TypeRep where
  478. put_ bh type_rep = do
  479. let (ty_con, child_type_reps) = splitTyConApp type_rep
  480. put_ bh ty_con
  481. put_ bh child_type_reps
  482. get bh = do
  483. ty_con <- get bh
  484. child_type_reps <- get bh
  485. return (mkTyConApp ty_con child_type_reps)
  486. -- -----------------------------------------------------------------------------
  487. -- Lazy reading/writing
  488. lazyPut :: Binary a => BinHandle -> a -> IO ()
  489. lazyPut bh a = do
  490. -- output the obj with a ptr to skip over it:
  491. pre_a <- tellBin bh
  492. put_ bh pre_a -- save a slot for the ptr
  493. put_ bh a -- dump the object
  494. q <- tellBin bh -- q = ptr to after object
  495. putAt bh pre_a q -- fill in slot before a with ptr to q
  496. seekBin bh q -- finally carry on writing at q
  497. lazyGet :: Binary a => BinHandle -> IO a
  498. lazyGet bh = do
  499. p <- get bh -- a BinPtr
  500. p_a <- tellBin bh
  501. a <- unsafeInterleaveIO $ do
  502. -- NB: Use a fresh off_r variable in the child thread, for thread
  503. -- safety.
  504. off_r <- newFastMutInt
  505. getAt bh { _off_r = off_r } p_a
  506. seekBin bh p -- skip over the object for now
  507. return a
  508. -- -----------------------------------------------------------------------------
  509. -- UserData
  510. -- -----------------------------------------------------------------------------
  511. data UserData =
  512. UserData {
  513. -- for *deserialising* only:
  514. ud_get_name :: BinHandle -> IO Name,
  515. ud_get_fs :: BinHandle -> IO FastString,
  516. -- for *serialising* only:
  517. ud_put_name :: BinHandle -> Name -> IO (),
  518. ud_put_fs :: BinHandle -> FastString -> IO ()
  519. }
  520. newReadState :: (BinHandle -> IO Name)
  521. -> (BinHandle -> IO FastString)
  522. -> UserData
  523. newReadState get_name get_fs
  524. = UserData { ud_get_name = get_name,
  525. ud_get_fs = get_fs,
  526. ud_put_name = undef "put_name",
  527. ud_put_fs = undef "put_fs"
  528. }
  529. newWriteState :: (BinHandle -> Name -> IO ())
  530. -> (BinHandle -> FastString -> IO ())
  531. -> UserData
  532. newWriteState put_name put_fs
  533. = UserData { ud_get_name = undef "get_name",
  534. ud_get_fs = undef "get_fs",
  535. ud_put_name = put_name,
  536. ud_put_fs = put_fs
  537. }
  538. noUserData :: a
  539. noUserData = undef "UserData"
  540. undef :: String -> a
  541. undef s = panic ("Binary.UserData: no " ++ s)
  542. ---------------------------------------------------------
  543. -- The Dictionary
  544. ---------------------------------------------------------
  545. type Dictionary = Array Int FastString -- The dictionary
  546. -- Should be 0-indexed
  547. putDictionary :: BinHandle -> Int -> UniqFM (Int,FastString) -> IO ()
  548. putDictionary bh sz dict = do
  549. put_ bh sz
  550. mapM_ (putFS bh) (elems (array (0,sz-1) (nonDetEltsUFM dict)))
  551. -- It's OK to use nonDetEltsUFM here because the elements have indices
  552. -- that array uses to create order
  553. getDictionary :: BinHandle -> IO Dictionary
  554. getDictionary bh = do
  555. sz <- get bh
  556. elems <- sequence (take sz (repeat (getFS bh)))
  557. return (listArray (0,sz-1) elems)
  558. ---------------------------------------------------------
  559. -- The Symbol Table
  560. ---------------------------------------------------------
  561. -- On disk, the symbol table is an array of IfExtName, when
  562. -- reading it in we turn it into a SymbolTable.
  563. type SymbolTable = Array Int Name
  564. ---------------------------------------------------------
  565. -- Reading and writing FastStrings
  566. ---------------------------------------------------------
  567. putFS :: BinHandle -> FastString -> IO ()
  568. putFS bh fs = putBS bh $ fastStringToByteString fs
  569. getFS :: BinHandle -> IO FastString
  570. getFS bh = do bs <- getBS bh
  571. return $! mkFastStringByteString bs
  572. putBS :: BinHandle -> ByteString -> IO ()
  573. putBS bh bs =
  574. BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do
  575. put_ bh l
  576. let
  577. go n | n == l = return ()
  578. | otherwise = do
  579. b <- peekElemOff (castPtr ptr) n
  580. putByte bh b
  581. go (n+1)
  582. go 0
  583. getBS :: BinHandle -> IO ByteString
  584. getBS bh = do
  585. l <- get bh :: IO Int
  586. arr <- readIORef (_arr_r bh)
  587. sz <- readFastMutInt (_sz_r bh)
  588. off <- readFastMutInt (_off_r bh)
  589. when (off + l > sz) $
  590. ioError (mkIOError eofErrorType "Data.Binary.getBS" Nothing Nothing)
  591. writeFastMutInt (_off_r bh) (off+l)
  592. withForeignPtr arr $ \ptr -> do
  593. bs <- BS.unsafePackCStringLen (castPtr $ ptr `plusPtr` off, fromIntegral l)
  594. return $! BS.copy bs
  595. instance Binary ByteString where
  596. put_ bh f = putBS bh f
  597. get bh = getBS bh
  598. instance Binary FastString where
  599. put_ bh f =
  600. case getUserData bh of
  601. UserData { ud_put_fs = put_fs } -> put_fs bh f
  602. get bh =
  603. case getUserData bh of
  604. UserData { ud_get_fs = get_fs } -> get_fs bh
  605. -- Here to avoid loop
  606. instance Binary Fingerprint where
  607. put_ h (Fingerprint w1 w2) = do put_ h w1; put_ h w2
  608. get h = do w1 <- get h; w2 <- get h; return (Fingerprint w1 w2)
  609. instance Binary FunctionOrData where
  610. put_ bh IsFunction = putByte bh 0
  611. put_ bh IsData = putByte bh 1
  612. get bh = do
  613. h <- getByte bh
  614. case h of
  615. 0 -> return IsFunction
  616. 1 -> return IsData
  617. _ -> panic "Binary FunctionOrData"
  618. instance Binary TupleSort where
  619. put_ bh BoxedTuple = putByte bh 0
  620. put_ bh UnboxedTuple = putByte bh 1
  621. put_ bh ConstraintTuple = putByte bh 2
  622. get bh = do
  623. h <- getByte bh
  624. case h of
  625. 0 -> do return BoxedTuple
  626. 1 -> do return UnboxedTuple
  627. _ -> do return ConstraintTuple
  628. instance Binary Activation where
  629. put_ bh NeverActive = do
  630. putByte bh 0
  631. put_ bh AlwaysActive = do
  632. putByte bh 1
  633. put_ bh (ActiveBefore src aa) = do
  634. putByte bh 2
  635. put_ bh src
  636. put_ bh aa
  637. put_ bh (ActiveAfter src ab) = do
  638. putByte bh 3
  639. put_ bh src
  640. put_ bh ab
  641. get bh = do
  642. h <- getByte bh
  643. case h of
  644. 0 -> do return NeverActive
  645. 1 -> do return AlwaysActive
  646. 2 -> do src <- get bh
  647. aa <- get bh
  648. return (ActiveBefore src aa)
  649. _ -> do src <- get bh
  650. ab <- get bh
  651. return (ActiveAfter src ab)
  652. instance Binary InlinePragma where
  653. put_ bh (InlinePragma s a b c d) = do
  654. put_ bh s
  655. put_ bh a
  656. put_ bh b
  657. put_ bh c
  658. put_ bh d
  659. get bh = do
  660. s <- get bh
  661. a <- get bh
  662. b <- get bh
  663. c <- get bh
  664. d <- get bh
  665. return (InlinePragma s a b c d)
  666. instance Binary RuleMatchInfo where
  667. put_ bh FunLike = putByte bh 0
  668. put_ bh ConLike = putByte bh 1
  669. get bh = do
  670. h <- getByte bh
  671. if h == 1 then return ConLike
  672. else return FunLike
  673. instance Binary InlineSpec where
  674. put_ bh EmptyInlineSpec = putByte bh 0
  675. put_ bh Inline = putByte bh 1
  676. put_ bh Inlinable = putByte bh 2
  677. put_ bh NoInline = putByte bh 3
  678. get bh = do h <- getByte bh
  679. case h of
  680. 0 -> return EmptyInlineSpec
  681. 1 -> return Inline
  682. 2 -> return Inlinable
  683. _ -> return NoInline
  684. instance Binary RecFlag where
  685. put_ bh Recursive = do
  686. putByte bh 0
  687. put_ bh NonRecursive = do
  688. putByte bh 1
  689. get bh = do
  690. h <- getByte bh
  691. case h of
  692. 0 -> do return Recursive
  693. _ -> do return NonRecursive
  694. instance Binary OverlapMode where
  695. put_ bh (NoOverlap s) = putByte bh 0 >> put_ bh s
  696. put_ bh (Overlaps s) = putByte bh 1 >> put_ bh s
  697. put_ bh (Incoherent s) = putByte bh 2 >> put_ bh s
  698. put_ bh (Overlapping s) = putByte bh 3 >> put_ bh s
  699. put_ bh (Overlappable s) = putByte bh 4 >> put_ bh s
  700. get bh = do
  701. h <- getByte bh
  702. case h of
  703. 0 -> (get bh) >>= \s -> return $ NoOverlap s
  704. 1 -> (get bh) >>= \s -> return $ Overlaps s
  705. 2 -> (get bh) >>= \s -> return $ Incoherent s
  706. 3 -> (get bh) >>= \s -> return $ Overlapping s
  707. 4 -> (get bh) >>= \s -> return $ Overlappable s
  708. _ -> panic ("get OverlapMode" ++ show h)
  709. instance Binary OverlapFlag where
  710. put_ bh flag = do put_ bh (overlapMode flag)
  711. put_ bh (isSafeOverlap flag)
  712. get bh = do
  713. h <- get bh
  714. b <- get bh
  715. return OverlapFlag { overlapMode = h, isSafeOverlap = b }
  716. instance Binary FixityDirection where
  717. put_ bh InfixL = do
  718. putByte bh 0
  719. put_ bh InfixR = do
  720. putByte bh 1
  721. put_ bh InfixN = do
  722. putByte bh 2
  723. get bh = do
  724. h <- getByte bh
  725. case h of
  726. 0 -> do return InfixL
  727. 1 -> do return InfixR
  728. _ -> do return InfixN
  729. instance Binary Fixity where
  730. put_ bh (Fixity src aa ab) = do
  731. put_ bh src
  732. put_ bh aa
  733. put_ bh ab
  734. get bh = do
  735. src <- get bh
  736. aa <- get bh
  737. ab <- get bh
  738. return (Fixity src aa ab)
  739. instance Binary WarningTxt where
  740. put_ bh (WarningTxt s w) = do
  741. putByte bh 0
  742. put_ bh s
  743. put_ bh w
  744. put_ bh (DeprecatedTxt s d) = do
  745. putByte bh 1
  746. put_ bh s
  747. put_ bh d
  748. get bh = do
  749. h <- getByte bh
  750. case h of
  751. 0 -> do s <- get bh
  752. w <- get bh
  753. return (WarningTxt s w)
  754. _ -> do s <- get bh
  755. d <- get bh
  756. return (DeprecatedTxt s d)
  757. instance Binary StringLiteral where
  758. put_ bh (StringLiteral st fs) = do
  759. put_ bh st
  760. put_ bh fs
  761. get bh = do
  762. st <- get bh
  763. fs <- get bh
  764. return (StringLiteral st fs)
  765. instance Binary a => Binary (GenLocated SrcSpan a) where
  766. put_ bh (L l x) = do
  767. put_ bh l
  768. put_ bh x
  769. get bh = do
  770. l <- get bh
  771. x <- get bh
  772. return (L l x)
  773. instance Binary SrcSpan where
  774. put_ bh (RealSrcSpan ss) = do
  775. putByte bh 0
  776. put_ bh (srcSpanFile ss)
  777. put_ bh (srcSpanStartLine ss)
  778. put_ bh (srcSpanStartCol ss)
  779. put_ bh (srcSpanEndLine ss)
  780. put_ bh (srcSpanEndCol ss)
  781. put_ bh (UnhelpfulSpan s) = do
  782. putByte bh 1
  783. put_ bh s
  784. get bh = do
  785. h <- getByte bh
  786. case h of
  787. 0 -> do f <- get bh
  788. sl <- get bh
  789. sc <- get bh
  790. el <- get bh
  791. ec <- get bh
  792. return (mkSrcSpan (mkSrcLoc f sl sc)
  793. (mkSrcLoc f el ec))
  794. _ -> do s <- get bh
  795. return (UnhelpfulSpan s)
  796. instance Binary Serialized where
  797. put_ bh (Serialized the_type bytes) = do
  798. put_ bh the_type
  799. put_ bh bytes
  800. get bh = do
  801. the_type <- get bh
  802. bytes <- get bh
  803. return (Serialized the_type bytes)