import IfaceSyn
import Module
import Name
-import OccName
import VarEnv
-import InstEnv
import Class
import DynFlags
import UniqFM
import Unique
import Outputable
import FastString
+import Constants
import Data.List
import Data.Word
readBinIface :: CheckHiWay -> TraceBinIFaceReading -> FilePath
-> TcRnIf a b ModIface
readBinIface checkHiWay traceBinIFaceReading hi_path = do
- nc <- getNameCache
- (new_nc, iface) <- liftIO $
- readBinIface_ checkHiWay traceBinIFaceReading hi_path nc
- setNameCache new_nc
- return iface
-
-readBinIface_ :: CheckHiWay -> TraceBinIFaceReading -> FilePath -> NameCache
- -> IO (NameCache, ModIface)
-readBinIface_ checkHiWay traceBinIFaceReading hi_path nc = do
+ update_nc <- mkNameCacheUpdater
+ dflags <- getDOpts
+ liftIO $ readBinIface_ dflags checkHiWay traceBinIFaceReading hi_path update_nc
+
+readBinIface_ :: DynFlags -> CheckHiWay -> TraceBinIFaceReading -> FilePath
+ -> NameCacheUpdater (Array Int Name)
+ -> IO ModIface
+readBinIface_ dflags checkHiWay traceBinIFaceReading hi_path update_nc = do
let printer :: SDoc -> IO ()
printer = case traceBinIFaceReading of
TraceBinIFaceReading -> \sd -> printSDoc sd defaultDumpStyle
errorOnMismatch "magic number mismatch: old/corrupt interface file?"
binaryInterfaceMagic magic
- -- Get the dictionary pointer. We won't attempt to actually
- -- read the dictionary until we've done the version checks below,
- -- just in case this isn't a valid interface. In retrospect the
- -- version should have come before the dictionary pointer, but this
- -- is the way it was done originally, and we can't change it now.
- dict_p <- Binary.get bh -- Get the dictionary ptr
+ -- Note [dummy iface field]
+ -- read a dummy 32/64 bit value. This field used to hold the
+ -- dictionary pointer in old interface file formats, but now
+ -- the dictionary pointer is after the version (where it
+ -- should be). Also, the serialisation of value of type "Bin
+ -- a" used to depend on the word size of the machine, now they
+ -- are always 32 bits.
+ --
+ if wORD_SIZE == 4
+ then do _ <- Binary.get bh :: IO Word32; return ()
+ else do _ <- Binary.get bh :: IO Word64; return ()
-- Check the interface file version and ways.
check_ver <- get bh
errorOnMismatch "mismatched interface file versions" our_ver check_ver
check_way <- get bh
- way_descr <- getWayDescr
+ let way_descr = getWayDescr dflags
wantedGot "Way" way_descr check_way
when (checkHiWay == CheckHiWay) $
errorOnMismatch "mismatched interface file ways" way_descr check_way
-- Read the dictionary
-- The next word in the file is a pointer to where the dictionary is
-- (probably at the end of the file)
+ dict_p <- Binary.get bh
data_p <- tellBin bh -- Remember where we are now
seekBin bh dict_p
dict <- getDictionary bh
symtab_p <- Binary.get bh -- Get the symtab ptr
data_p <- tellBin bh -- Remember where we are now
seekBin bh symtab_p
- (nc', symtab) <- getSymbolTable bh nc
+ symtab <- getSymbolTable bh update_nc
seekBin bh data_p -- Back to where we were before
let ud = getUserData bh
bh <- return $! setUserData bh ud{ud_symtab = symtab}
iface <- get bh
- return (nc', iface)
+ return iface
writeBinIface :: DynFlags -> FilePath -> ModIface -> IO ()
bh <- openBinMem initBinMemSize
put_ bh binaryInterfaceMagic
- -- Remember where the dictionary pointer will go
- dict_p_p <- tellBin bh
- put_ bh dict_p_p -- Placeholder for ptr to dictionary
+ -- dummy 32/64-bit field before the version/way for
+ -- compatibility with older interface file formats.
+ -- See Note [dummy iface field] above.
+ if wORD_SIZE == 4
+ then Binary.put_ bh (0 :: Word32)
+ else Binary.put_ bh (0 :: Word64)
-- The version and way descriptor go next
put_ bh (show opt_HiVersion)
- way_descr <- getWayDescr
- put bh way_descr
+ let way_descr = getWayDescr dflags
+ put_ bh way_descr
+
+ -- Remember where the dictionary pointer will go
+ dict_p_p <- tellBin bh
+ put_ bh dict_p_p -- Placeholder for ptr to dictionary
-- Remember where the symbol table pointer will go
symtab_p_p <- tellBin bh
initBinMemSize = 1024 * 1024
-- The *host* architecture version:
-#include "MachDeps.h"
+#include "../includes/MachDeps.h"
binaryInterfaceMagic :: Word32
#if WORD_SIZE_IN_BITS == 32
let names = elems (array (0,next_off-1) (eltsUFM symtab))
mapM_ (\n -> serialiseName bh n symtab) names
-getSymbolTable :: BinHandle -> NameCache -> IO (NameCache, Array Int Name)
-getSymbolTable bh namecache = do
+getSymbolTable :: BinHandle -> NameCacheUpdater (Array Int Name)
+ -> IO (Array Int Name)
+getSymbolTable bh update_namecache = do
sz <- get bh
od_names <- sequence (replicate sz (get bh))
- let
+ update_namecache $ \namecache ->
+ let
arr = listArray (0,sz-1) names
(namecache', names) =
mapAccumR (fromOnDiskName arr) namecache od_names
- --
- return (namecache', arr)
+ in (namecache', arr)
type OnDiskName = (PackageId, ModuleName, OccName)
= do
symtab_map <- readIORef symtab_map_ref
case lookupUFM symtab_map name of
- Just (off,_) -> put_ bh off
+ Just (off,_) -> put_ bh (fromIntegral off :: Word32)
Nothing -> do
off <- readFastMutInt symtab_next
writeFastMutInt symtab_next (off+1)
writeIORef symtab_map_ref
$! addToUFM symtab_map name (off,name)
- put_ bh off
+ put_ bh (fromIntegral off :: Word32)
data BinSymbolTable = BinSymbolTable {
out <- readIORef out_r
let uniq = getUnique f
case lookupUFM out uniq of
- Just (j, _) -> put_ bh j
+ Just (j, _) -> put_ bh (fromIntegral j :: Word32)
Nothing -> do
j <- readFastMutInt j_r
- put_ bh j
+ put_ bh (fromIntegral j :: Word32)
writeFastMutInt j_r (j + 1)
writeIORef out_r $! addToUFM out uniq (j, f)
mi_fix_fn = mkIfaceFixCache fixities,
mi_hash_fn = mkIfaceHashCache decls })
-getWayDescr :: IO String
-getWayDescr = do
- tag <- readIORef v_Build_tag
- if cGhcUnregisterised == "YES" then return ('u':tag) else return tag
+getWayDescr :: DynFlags -> String
+getWayDescr dflags
+ | cGhcUnregisterised == "YES" = 'u':tag
+ | otherwise = tag
+ where tag = buildTag dflags
-- if this is an unregisterised build, make sure our interfaces
-- can't be used by a registerised build.
_ -> do ab <- get bh
return (ActiveAfter ab)
+instance Binary RuleMatchInfo where
+ put_ bh FunLike = putByte bh 0
+ put_ bh ConLike = putByte bh 1
+ get bh = do
+ h <- getByte bh
+ if h == 1 then return ConLike
+ else return FunLike
+
+instance Binary InlinePragma where
+ put_ bh (InlinePragma activation match_info) = do
+ put_ bh activation
+ put_ bh match_info
+
+ get bh = do
+ act <- get bh
+ info <- get bh
+ return (InlinePragma act info)
+
instance Binary StrictnessMark where
- put_ bh MarkedStrict = do
- putByte bh 0
- put_ bh MarkedUnboxed = do
- putByte bh 1
- put_ bh NotMarkedStrict = do
- putByte bh 2
+ put_ bh MarkedStrict = putByte bh 0
+ put_ bh MarkedUnboxed = putByte bh 1
+ put_ bh NotMarkedStrict = putByte bh 2
get bh = do
h <- getByte bh
case h of
_ -> do return NotMarkedStrict
instance Binary Boxity where
- put_ bh Boxed = do
- putByte bh 0
- put_ bh Unboxed = do
- putByte bh 1
+ put_ bh Boxed = putByte bh 0
+ put_ bh Unboxed = putByte bh 1
get bh = do
h <- getByte bh
case h of
instance Binary DmdType where
-- Ignore DmdEnv when spitting out the DmdType
- put bh (DmdType _ ds dr) = do p <- put bh ds; put bh dr; return (castBin p)
+ put bh (DmdType _ ds dr) = do p <- put bh ds; put_ bh dr; return (castBin p)
get bh = do ds <- get bh; dr <- get bh; return (DmdType emptyVarEnv ds dr)
instance Binary Demand where
put_ bh (IfaceTyConApp IfaceUnliftedTypeKindTc []) = putByte bh 14
put_ bh (IfaceTyConApp IfaceUbxTupleKindTc []) = putByte bh 15
put_ bh (IfaceTyConApp IfaceArgTypeKindTc []) = putByte bh 16
+ put_ bh (IfaceTyConApp (IfaceAnyTc k) []) = do { putByte bh 17; put_ bh k }
-- Generic cases
14 -> return (IfaceTyConApp IfaceUnliftedTypeKindTc [])
15 -> return (IfaceTyConApp IfaceUbxTupleKindTc [])
16 -> return (IfaceTyConApp IfaceArgTypeKindTc [])
+ 17 -> do { k <- get bh; return (IfaceTyConApp (IfaceAnyTc k) []) }
18 -> do { tc <- get bh; tys <- get bh; return (IfaceTyConApp (IfaceTc tc) tys) }
_ -> do { tc <- get bh; tys <- get bh; return (IfaceTyConApp tc tys) }
put_ bh IfaceArgTypeKindTc = putByte bh 10
put_ bh (IfaceTupTc bx ar) = do { putByte bh 11; put_ bh bx; put_ bh ar }
put_ bh (IfaceTc ext) = do { putByte bh 12; put_ bh ext }
+ put_ bh (IfaceAnyTc k) = do { putByte bh 13; put_ bh k }
get bh = do
h <- getByte bh
9 -> return IfaceUbxTupleKindTc
10 -> return IfaceArgTypeKindTc
11 -> do { bx <- get bh; ar <- get bh; return (IfaceTupTc bx ar) }
- _ -> do { ext <- get bh; return (IfaceTc ext) }
+ 12 -> do { ext <- get bh; return (IfaceTc ext) }
+ _ -> do { k <- get bh; return (IfaceAnyTc k) }
instance Binary IfacePredType where
put_ bh (IfaceClassP aa ab) = do
_ -> do ac <- get bh
return (IfaceRec ac)
+instance Binary IfaceIdDetails where
+ put_ bh IfVanillaId = putByte bh 0
+ put_ bh (IfRecSelId a b) = do { putByte bh 1; put_ bh a; put_ bh b }
+ put_ bh IfDFunId = putByte bh 2
+ get bh = do
+ h <- getByte bh
+ case h of
+ 0 -> return IfVanillaId
+ 1 -> do a <- get bh
+ b <- get bh
+ return (IfRecSelId a b)
+ _ -> return IfDFunId
+
instance Binary IfaceIdInfo where
put_ bh NoInfo = putByte bh 0
put_ bh (HasInfo i) = do
-- when de-serialising.
instance Binary IfaceDecl where
- put_ bh (IfaceId name ty idinfo) = do
+ put_ bh (IfaceId name ty details idinfo) = do
putByte bh 0
put_ bh (occNameFS name)
put_ bh ty
+ put_ bh details
put_ bh idinfo
put_ _ (IfaceForeign _ _) =
error "Binary.put_(IfaceDecl): IfaceForeign"
get bh = do
h <- getByte bh
case h of
- 0 -> do name <- get bh
- ty <- get bh
- idinfo <- get bh
+ 0 -> do name <- get bh
+ ty <- get bh
+ details <- get bh
+ idinfo <- get bh
occ <- return $! mkOccNameFS varName name
- return (IfaceId occ ty idinfo)
+ return (IfaceId occ ty details idinfo)
1 -> error "Binary.get(TyClDecl): ForeignType"
2 -> do
a1 <- get bh
return (IfNewTyCon aa)
instance Binary IfaceConDecl where
- put_ bh (IfCon a1 a2 a3 a4 a5 a6 a7 a8 a9) = do
+ put_ bh (IfCon a1 a2 a3 a4 a5 a6 a7 a8 a9 a10) = do
put_ bh a1
put_ bh a2
put_ bh a3
put_ bh a7
put_ bh a8
put_ bh a9
+ put_ bh a10
get bh = do a1 <- get bh
a2 <- get bh
a3 <- get bh
a7 <- get bh
a8 <- get bh
a9 <- get bh
- return (IfCon a1 a2 a3 a4 a5 a6 a7 a8 a9)
+ a10 <- get bh
+ return (IfCon a1 a2 a3 a4 a5 a6 a7 a8 a9 a10)
instance Binary IfaceClassOp where
put_ bh (IfaceClassOp n def ty) = do