diff options
author | Matthew Pickering <matthew.pickering@tweag.io> | 2018-06-04 02:05:46 +0000 |
---|---|---|
committer | Matthew Pickering <matthew.pickering@tweag.io> | 2018-06-04 02:06:03 +0000 |
commit | 554bc7fcca30b1b6ffb6a2daca684ea74eb83ad8 (patch) | |
tree | 622414d95ac9fe351718c471e98f2033038cee15 /compiler/iface/BinIface.hs | |
parent | 4dd1895bf8bbe5aac7a8e80f18ba76e78520be18 (diff) | |
download | haskell-554bc7fcca30b1b6ffb6a2daca684ea74eb83ad8.tar.gz |
Provide `getWithUserData` and `putWithUserData`
Summary:
This makes it possible to serialise Names and FastStrings in user
programs, for example, when writing a source plugin.
When writing my first source plugin, I wanted to serialise names but it
wasn't possible easily without exporting additional constructors. This
interface is sufficient and abstracts nicely over the symbol table and
dictionary.
Reviewers: alpmestan, bgamari
Reviewed By: alpmestan
Subscribers: rwbarton, thomie, carter
GHC Trac Issues: #15223
Differential Revision: https://phabricator.haskell.org/D4782
Diffstat (limited to 'compiler/iface/BinIface.hs')
-rw-r--r-- | compiler/iface/BinIface.hs | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/compiler/iface/BinIface.hs b/compiler/iface/BinIface.hs index 2a4696a541..b8b4bb0370 100644 --- a/compiler/iface/BinIface.hs +++ b/compiler/iface/BinIface.hs @@ -15,7 +15,10 @@ module BinIface ( getSymtabName, getDictFastString, CheckHiWay(..), - TraceBinIFaceReading(..) + TraceBinIFaceReading(..), + getWithUserData, + putWithUserData + ) where #include "HsVersions.h" @@ -134,7 +137,14 @@ readBinIface_ dflags checkHiWay traceBinIFaceReading hi_path ncu = do wantedGot "Way" way_descr check_way when (checkHiWay == CheckHiWay) $ errorOnMismatch "mismatched interface file ways" way_descr check_way + getWithUserData ncu bh + +-- | This performs a get action after reading the dictionary and symbol +-- table. It is necessary to run this before trying to deserialise any +-- Names or FastStrings. +getWithUserData :: Binary a => NameCacheUpdater -> BinHandle -> IO a +getWithUserData ncu bh = do -- Read the dictionary -- The next word in the file is a pointer to where the dictionary is -- (probably at the end of the file) @@ -179,6 +189,17 @@ writeBinIface dflags hi_path mod_iface = do let way_descr = getWayDescr dflags put_ bh way_descr + + putWithUserData (debugTraceMsg dflags 3) bh mod_iface + -- And send the result to the file + writeBinMem bh hi_path + +-- | Put a piece of data with an initialised `UserData` field. This +-- is necessary if you want to serialise Names or FastStrings. +-- It also writes a symbol table and the dictionary. +-- This segment should be read using `getWithUserData`. +putWithUserData :: Binary a => (SDoc -> IO ()) -> BinHandle -> a -> IO () +putWithUserData log_action bh payload = do -- Remember where the dictionary pointer will go dict_p_p <- tellBin bh -- Placeholder for ptr to dictionary @@ -187,7 +208,6 @@ writeBinIface dflags hi_path mod_iface = do -- Remember where the symbol table pointer will go symtab_p_p <- tellBin bh put_ bh symtab_p_p - -- Make some intial state symtab_next <- newFastMutInt writeFastMutInt symtab_next 0 @@ -206,7 +226,7 @@ writeBinIface dflags hi_path mod_iface = do bh <- return $ setUserData bh $ newWriteState (putName bin_dict bin_symtab) (putName bin_dict bin_symtab) (putFastString bin_dict) - put_ bh mod_iface + put_ bh payload -- Write the symtab pointer at the front of the file symtab_p <- tellBin bh -- This is where the symtab will start @@ -217,7 +237,7 @@ writeBinIface dflags hi_path mod_iface = do symtab_next <- readFastMutInt symtab_next symtab_map <- readIORef symtab_map putSymbolTable bh symtab_next symtab_map - debugTraceMsg dflags 3 (text "writeBinIface:" <+> int symtab_next + log_action (text "writeBinIface:" <+> int symtab_next <+> text "Names") -- NB. write the dictionary after the symbol table, because @@ -232,11 +252,10 @@ writeBinIface dflags hi_path mod_iface = do dict_next <- readFastMutInt dict_next_ref dict_map <- readIORef dict_map_ref putDictionary bh dict_next dict_map - debugTraceMsg dflags 3 (text "writeBinIface:" <+> int dict_next + log_action (text "writeBinIface:" <+> int dict_next <+> text "dict entries") - -- And send the result to the file - writeBinMem bh hi_path + -- | Initial ram buffer to allocate for writing interface files initBinMemSize :: Int |