    {-# LANGUAGE FlexibleInstances          #-}
    {-# LANGUAGE LambdaCase                 #-}
    {-# LANGUAGE OverloadedStrings          #-}
    {-# LANGUAGE Rank2Types                 #-}
    {-# LANGUAGE ScopedTypeVariables        #-}

    -- only for DB.Binary instances on Module
    {-# OPTIONS_GHC -fno-warn-orphans #-}

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  GHC.StgToJS.Object
    -- Copyright   :  (c) The University of Glasgow 2001
    -- License     :  BSD-style (see the file LICENSE)
    --
    -- Maintainer  :  Sylvain Henry  <sylvain.henry@iohk.io>
    --                Jeffrey Young  <jeffrey.young@iohk.io>
    --                Luite Stegeman <luite.stegeman@iohk.io>
    --                Josh Meredith  <josh.meredith@iohk.io>
    -- Stability   :  experimental
    --
    --  Serialization/deserialization of binary .o files for the JavaScript backend
    --  The .o files contain dependency information and generated code.
    --  All strings are mapped to a central string table, which helps reduce
    --  file size and gives us efficient hash consing on read
    --
    --  Binary intermediate JavaScript object files:
    --   serialized [Text] -> ([ClosureInfo], JStat) blocks
    --
    --  file layout:
    --   - magic "GHCJSOBJ"
    --   - compiler version tag
    --   - module name
    --   - offsets of string table
    --   - dependencies
    --   - offset of the index
    --   - unit infos
    --   - index
    --   - string table
    --
    -----------------------------------------------------------------------------

    module GHC.StgToJS.Object
      ( putObject
      , getObjectHeader
      , getObjectBody
      , getObject
      , readObject
      , getObjectUnits
      , readObjectUnits
      , readObjectDeps
      , isGlobalUnit
      , isJsObjectFile
      , Object(..)
      , IndexEntry(..)
      , Deps (..), BlockDeps (..), DepsLocation (..)
      , ExportedFun (..)
      )
    where

    import GHC.Prelude

    import           Control.Monad

    import           Data.Array
    import           Data.Int
    import           Data.IntSet (IntSet)
    import qualified Data.IntSet as IS
    import           Data.List (sortOn)
    import           Data.Map (Map)
    import qualified Data.Map as M
    import           Data.Word
    import           Data.Char
    import Foreign.Storable
    import Foreign.Marshal.Array
    import System.IO

    import GHC.Settings.Constants (hiVersion)

    import GHC.JS.Syntax
    import GHC.StgToJS.Types

    import GHC.Unit.Module

    import GHC.Data.FastString

    import GHC.Types.Unique.Map
    import GHC.Float (castDoubleToWord64, castWord64ToDouble)

    import GHC.Utils.Binary hiding (SymbolTable)
    import GHC.Utils.Outputable (ppr, Outputable, hcat, vcat, text, hsep)
    import GHC.Utils.Monad (mapMaybeM)

    -- | An object file
    data Object = Object
      { Object -> ModuleName
    objModuleName    :: !ModuleName
        -- ^ name of the module
      , Object -> BinHandle
    objHandle        :: !BinHandle
        -- ^ BinHandle that can be used to read the ObjUnits
      , Object -> Bin ObjUnit
    objPayloadOffset :: !(Bin ObjUnit)
        -- ^ Offset of the payload (units)
      , Object -> Deps
    objDeps          :: !Deps
        -- ^ Dependencies
      , Object -> Index
    objIndex         :: !Index
        -- ^ The Index, serialed unit indices and their linkable units
      }

    type BlockId  = Int
    type BlockIds = IntSet

    -- | dependencies for a single module
    data Deps = Deps
      { Deps -> Module
    depsModule          :: !Module
          -- ^ module
      , Deps -> BlockIds
    depsRequired        :: !BlockIds
          -- ^ blocks that always need to be linked when this object is loaded (e.g.
          -- everything that contains initializer code or foreign exports)
      , Deps -> Map ExportedFun Int
    depsHaskellExported :: !(Map ExportedFun BlockId)
          -- ^ exported Haskell functions -> block
      , Deps -> Array Int BlockDeps
    depsBlocks          :: !(Array BlockId BlockDeps)
          -- ^ info about each block
      }

    instance Outputable Deps where
      ppr :: Deps -> SDoc
    ppr Deps
    d = [SDoc] -> SDoc
    forall doc. IsDoc doc => [doc] -> doc
    vcat
        [ [SDoc] -> SDoc
    forall doc. IsLine doc => [doc] -> doc
    hcat [ String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "module: ", Module -> SDoc
    forall doc. IsLine doc => Module -> doc
    pprModule (Deps -> Module
    depsModule Deps
    d) ]
        , [SDoc] -> SDoc
    forall doc. IsLine doc => [doc] -> doc
    hcat [ String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "exports: ", [ExportedFun] -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr (Map ExportedFun Int -> [ExportedFun]
    forall k a. Map k a -> [k]
    M.keys (Deps -> Map ExportedFun Int
    depsHaskellExported Deps
    d)) ]
        ]

    -- | Where are the dependencies
    data DepsLocation
      = ObjectFile  FilePath       -- ^ In an object file at path
      | ArchiveFile FilePath       -- ^ In a Ar file at path
      | InMemory    String Object  -- ^ In memory

    instance Outputable DepsLocation where
      ppr :: DepsLocation -> SDoc
    ppr = \case
        ObjectFile String
    fp  -> [SDoc] -> SDoc
    forall doc. IsLine doc => [doc] -> doc
    hsep [String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "ObjectFile", String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    fp]
        ArchiveFile String
    fp -> [SDoc] -> SDoc
    forall doc. IsLine doc => [doc] -> doc
    hsep [String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "ArchiveFile", String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    fp]
        InMemory String
    s Object
    o   -> [SDoc] -> SDoc
    forall doc. IsLine doc => [doc] -> doc
    hsep [String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "InMemory", String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    s, ModuleName -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr (Object -> ModuleName
    objModuleName Object
    o)]

    data BlockDeps = BlockDeps
      { BlockDeps -> [Int]
    blockBlockDeps       :: [Int]         -- ^ dependencies on blocks in this object
      , BlockDeps -> [ExportedFun]
    blockFunDeps         :: [ExportedFun] -- ^ dependencies on exported symbols in other objects
      -- , blockForeignExported :: [ExpFun]
      -- , blockForeignImported :: [ForeignRef]
      }

    {- | we use the convention that the first unit (0) is a module-global
         unit that's always included when something from the module
         is loaded. everything in a module implicitly depends on the
         global block. the global unit itself can't have dependencies
     -}
    isGlobalUnit :: Int -> Bool
    isGlobalUnit :: Int -> Bool
    isGlobalUnit Int
    n = Int
    n Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    0

    -- | Exported Functions
    data ExportedFun = ExportedFun
      { ExportedFun -> Module
    funModule  :: !Module              -- ^ The module containing the function
      , ExportedFun -> LexicalFastString
    funSymbol  :: !LexicalFastString   -- ^ The function
      } deriving (ExportedFun -> ExportedFun -> Bool
    (ExportedFun -> ExportedFun -> Bool)
    -> (ExportedFun -> ExportedFun -> Bool) -> Eq ExportedFun
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ExportedFun -> ExportedFun -> Bool
    == :: ExportedFun -> ExportedFun -> Bool
    $c/= :: ExportedFun -> ExportedFun -> Bool
    /= :: ExportedFun -> ExportedFun -> Bool
    Eq, Eq ExportedFun
    Eq ExportedFun =>
    (ExportedFun -> ExportedFun -> Ordering)
    -> (ExportedFun -> ExportedFun -> Bool)
    -> (ExportedFun -> ExportedFun -> Bool)
    -> (ExportedFun -> ExportedFun -> Bool)
    -> (ExportedFun -> ExportedFun -> Bool)
    -> (ExportedFun -> ExportedFun -> ExportedFun)
    -> (ExportedFun -> ExportedFun -> ExportedFun)
    -> Ord ExportedFun
    ExportedFun -> ExportedFun -> Bool
    ExportedFun -> ExportedFun -> Ordering
    ExportedFun -> ExportedFun -> ExportedFun
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: ExportedFun -> ExportedFun -> Ordering
    compare :: ExportedFun -> ExportedFun -> Ordering
    $c< :: ExportedFun -> ExportedFun -> Bool
    < :: ExportedFun -> ExportedFun -> Bool
    $c<= :: ExportedFun -> ExportedFun -> Bool
    <= :: ExportedFun -> ExportedFun -> Bool
    $c> :: ExportedFun -> ExportedFun -> Bool
    > :: ExportedFun -> ExportedFun -> Bool
    $c>= :: ExportedFun -> ExportedFun -> Bool
    >= :: ExportedFun -> ExportedFun -> Bool
    $cmax :: ExportedFun -> ExportedFun -> ExportedFun
    max :: ExportedFun -> ExportedFun -> ExportedFun
    $cmin :: ExportedFun -> ExportedFun -> ExportedFun
    min :: ExportedFun -> ExportedFun -> ExportedFun
    Ord)

    instance Outputable ExportedFun where
      ppr :: ExportedFun -> SDoc
    ppr (ExportedFun Module
    m LexicalFastString
    f) = [SDoc] -> SDoc
    forall doc. IsDoc doc => [doc] -> doc
    vcat
        [ [SDoc] -> SDoc
    forall doc. IsLine doc => [doc] -> doc
    hcat [ String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "module: ", Module -> SDoc
    forall doc. IsLine doc => Module -> doc
    pprModule Module
    m ]
        , [SDoc] -> SDoc
    forall doc. IsLine doc => [doc] -> doc
    hcat [ String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "symbol: ", LexicalFastString -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr LexicalFastString
    f ]
        ]

    -- | Write an ObjUnit, except for the top level symbols which are stored in the
    -- index
    putObjUnit :: BinHandle -> ObjUnit -> IO ()
    putObjUnit :: BinHandle -> ObjUnit -> IO ()
    putObjUnit BinHandle
    bh (ObjUnit [FastString]
    _syms [ClosureInfo]
    b [StaticInfo]
    c JStat
    d ByteString
    e [ExpFun]
    f [ForeignJSRef]
    g) = do
        BinHandle -> [ClosureInfo] -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh [ClosureInfo]
    b
        BinHandle -> [StaticInfo] -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh [StaticInfo]
    c
        BinHandle -> JStat -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    lazyPut BinHandle
    bh JStat
    d
        BinHandle -> ByteString -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh ByteString
    e
        BinHandle -> [ExpFun] -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh [ExpFun]
    f
        BinHandle -> [ForeignJSRef] -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh [ForeignJSRef]
    g

    -- | Read an ObjUnit and associate it to the given symbols (that must have been
    -- read from the index)
    getObjUnit :: [FastString] -> BinHandle -> IO ObjUnit
    getObjUnit :: [FastString] -> BinHandle -> IO ObjUnit
    getObjUnit [FastString]
    syms BinHandle
    bh = do
        [ClosureInfo]
    b <- BinHandle -> IO [ClosureInfo]
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        [StaticInfo]
    c <- BinHandle -> IO [StaticInfo]
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        JStat
    d <- BinHandle -> IO JStat
    forall a. Binary a => BinHandle -> IO a
    lazyGet BinHandle
    bh
        ByteString
    e <- BinHandle -> IO ByteString
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        [ExpFun]
    f <- BinHandle -> IO [ExpFun]
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        [ForeignJSRef]
    g <- BinHandle -> IO [ForeignJSRef]
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        ObjUnit -> IO ObjUnit
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (ObjUnit -> IO ObjUnit) -> ObjUnit -> IO ObjUnit
    forall a b. (a -> b) -> a -> b
    $ ObjUnit
          { oiSymbols :: [FastString]
    oiSymbols  = [FastString]
    syms
          , oiClInfo :: [ClosureInfo]
    oiClInfo   = [ClosureInfo]
    b
          , oiStatic :: [StaticInfo]
    oiStatic   = [StaticInfo]
    c
          , oiStat :: JStat
    oiStat     = JStat
    d
          , oiRaw :: ByteString
    oiRaw      = ByteString
    e
          , oiFExports :: [ExpFun]
    oiFExports = [ExpFun]
    f
          , oiFImports :: [ForeignJSRef]
    oiFImports = [ForeignJSRef]
    g
          }

    -- | A tag that determines the kind of payload in the .o file. See
    -- @StgToJS.Linker.Arhive.magic@ for another kind of magic
    magic :: String
    magic :: String
    magic = String
    "GHCJSOBJ"

    -- | Serialized unit indexes and their exported symbols
    -- (the first unit is module-global)
    type Index = [IndexEntry]
    data IndexEntry = IndexEntry
      { IndexEntry -> [FastString]
    idxSymbols :: ![FastString]  -- ^ Symbols exported by a unit
      , IndexEntry -> Bin ObjUnit
    idxOffset  :: !(Bin ObjUnit) -- ^ Offset of the unit in the object file
      }

    --------------------------------------------------------------------------------
    -- Essential oeprations on Objects
    --------------------------------------------------------------------------------

    -- | Given a handle to a Binary payload, add the module, 'mod_name', its
    -- dependencies, 'deps', and its linkable units to the payload.
    putObject
      :: BinHandle
      -> ModuleName -- ^ module
      -> Deps       -- ^ dependencies
      -> [ObjUnit]  -- ^ linkable units and their symbols
      -> IO ()
    putObject :: BinHandle -> ModuleName -> Deps -> [ObjUnit] -> IO ()
    putObject BinHandle
    bh ModuleName
    mod_name Deps
    deps [ObjUnit]
    os = do
      String -> (Char -> IO ()) -> IO ()
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    t a -> (a -> m b) -> m ()
    forM_ String
    magic (BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh (Word8 -> IO ()) -> (Char -> Word8) -> Char -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> Word8
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Int -> Word8) -> (Char -> Int) -> Char -> Word8
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Char -> Int
    ord)
      BinHandle -> String -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh (Integer -> String
    forall a. Show a => a -> String
    show Integer
    hiVersion)

      -- we store the module name as a String because we don't want to have to
      -- decode the FastString table just to decode it when we're looking for an
      -- object in an archive.
      BinHandle -> String -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh (ModuleName -> String
    moduleNameString ModuleName
    mod_name)

      (BinHandle
    bh_fs, FSTable
    _bin_dict, IO Int
    put_dict) <- BinHandle -> IO (BinHandle, FSTable, IO Int)
    initFSTable BinHandle
    bh

      BinHandle -> (() -> IO Int) -> IO () -> IO ()
    forall b a. BinHandle -> (b -> IO a) -> IO b -> IO ()
    forwardPut_ BinHandle
    bh (IO Int -> () -> IO Int
    forall a b. a -> b -> a
    const IO Int
    put_dict) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $ do
        BinHandle -> Deps -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh_fs Deps
    deps

        -- forward put the index
        BinHandle
    -> ([([FastString], Bin Any)] -> IO ())
    -> IO [([FastString], Bin Any)]
    -> IO ()
    forall b a. BinHandle -> (b -> IO a) -> IO b -> IO ()
    forwardPut_ BinHandle
    bh_fs (BinHandle -> [([FastString], Bin Any)] -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh_fs) (IO [([FastString], Bin Any)] -> IO ())
    -> IO [([FastString], Bin Any)] -> IO ()
    forall a b. (a -> b) -> a -> b
    $ do
          [([FastString], Bin Any)]
    idx <- [ObjUnit]
    -> (ObjUnit -> IO ([FastString], Bin Any))
    -> IO [([FastString], Bin Any)]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    t a -> (a -> m b) -> m (t b)
    forM [ObjUnit]
    os ((ObjUnit -> IO ([FastString], Bin Any))
     -> IO [([FastString], Bin Any)])
    -> (ObjUnit -> IO ([FastString], Bin Any))
    -> IO [([FastString], Bin Any)]
    forall a b. (a -> b) -> a -> b
    $ \ObjUnit
    o -> do
            Bin Any
    p <- BinHandle -> IO (Bin Any)
    forall {k} (a :: k). BinHandle -> IO (Bin a)
    tellBin BinHandle
    bh_fs
            -- write units without their symbols
            BinHandle -> ObjUnit -> IO ()
    putObjUnit BinHandle
    bh_fs ObjUnit
    o
            -- return symbols and offset to store in the index
            ([FastString], Bin Any) -> IO ([FastString], Bin Any)
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (ObjUnit -> [FastString]
    oiSymbols ObjUnit
    o,Bin Any
    p)
          [([FastString], Bin Any)] -> IO [([FastString], Bin Any)]
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure [([FastString], Bin Any)]
    idx

    -- | Test if the object file is a JS object
    isJsObjectFile :: FilePath -> IO Bool
    isJsObjectFile :: String -> IO Bool
    isJsObjectFile String
    fp = do
      let !n :: Int
    n = String -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length String
    magic
      String -> IOMode -> (Handle -> IO Bool) -> IO Bool
    forall r. String -> IOMode -> (Handle -> IO r) -> IO r
    withBinaryFile String
    fp IOMode
    ReadMode ((Handle -> IO Bool) -> IO Bool) -> (Handle -> IO Bool) -> IO Bool
    forall a b. (a -> b) -> a -> b
    $ \Handle
    hdl -> do
        Int -> (Ptr Word8 -> IO Bool) -> IO Bool
    forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
    allocaArray Int
    n ((Ptr Word8 -> IO Bool) -> IO Bool)
    -> (Ptr Word8 -> IO Bool) -> IO Bool
    forall a b. (a -> b) -> a -> b
    $ \Ptr Word8
    ptr -> do
          Int
    n' <- Handle -> Ptr Word8 -> Int -> IO Int
    forall a. Handle -> Ptr a -> Int -> IO Int
    hGetBuf Handle
    hdl Ptr Word8
    ptr Int
    n
          if (Int
    n' Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Int
    n)
            then Bool -> IO Bool
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Bool
    False
            else (Int -> IO Word8) -> IO Bool
    checkMagic (Ptr Word8 -> Int -> IO Word8
    forall a. Storable a => Ptr a -> Int -> IO a
    peekElemOff Ptr Word8
    ptr)

    -- | Check magic
    checkMagic :: (Int -> IO Word8) -> IO Bool
    checkMagic :: (Int -> IO Word8) -> IO Bool
    checkMagic Int -> IO Word8
    get_byte = do
      let go_magic :: Int -> String -> IO Bool
    go_magic !Int
    i = \case
            []     -> Bool -> IO Bool
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Bool
    True
            (Char
    e:String
    es) -> Int -> IO Word8
    get_byte Int
    i IO Word8 -> (Word8 -> IO Bool) -> IO Bool
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \case
              Word8
    c | Int -> Word8
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Char -> Int
    ord Char
    e) Word8 -> Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word8
    c -> Int -> String -> IO Bool
    go_magic (Int
    iInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    1) String
    es
                | Bool
    otherwise                 -> Bool -> IO Bool
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Bool
    False
      Int -> String -> IO Bool
    go_magic Int
    0 String
    magic

    -- | Parse object magic
    getCheckMagic :: BinHandle -> IO Bool
    getCheckMagic :: BinHandle -> IO Bool
    getCheckMagic BinHandle
    bh = (Int -> IO Word8) -> IO Bool
    checkMagic (IO Word8 -> Int -> IO Word8
    forall a b. a -> b -> a
    const (BinHandle -> IO Word8
    getByte BinHandle
    bh))

    -- | Parse object header
    getObjectHeader :: BinHandle -> IO (Either String ModuleName)
    getObjectHeader :: BinHandle -> IO (Either String ModuleName)
    getObjectHeader BinHandle
    bh = do
      Bool
    is_magic <- BinHandle -> IO Bool
    getCheckMagic BinHandle
    bh
      case Bool
    is_magic of
        Bool
    False -> Either String ModuleName -> IO (Either String ModuleName)
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (String -> Either String ModuleName
    forall a b. a -> Either a b
    Left String
    "invalid magic header")
        Bool
    True  -> do
          Bool
    is_correct_version <- ((Integer -> Integer -> Bool
    forall a. Eq a => a -> a -> Bool
    == Integer
    hiVersion) (Integer -> Bool) -> (String -> Integer) -> String -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> Integer
    forall a. Read a => String -> a
    read) (String -> Bool) -> IO String -> IO Bool
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO String
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
          case Bool
    is_correct_version of
            Bool
    False -> Either String ModuleName -> IO (Either String ModuleName)
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (String -> Either String ModuleName
    forall a b. a -> Either a b
    Left String
    "invalid header version")
            Bool
    True  -> do
              String
    mod_name <- BinHandle -> IO String
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
              Either String ModuleName -> IO (Either String ModuleName)
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (ModuleName -> Either String ModuleName
    forall a b. b -> Either a b
    Right (String -> ModuleName
    mkModuleName (String
    mod_name)))

    -- | Parse object body. Must be called after a sucessful getObjectHeader
    getObjectBody :: BinHandle -> ModuleName -> IO Object
    getObjectBody :: BinHandle -> ModuleName -> IO Object
    getObjectBody BinHandle
    bh0 ModuleName
    mod_name = do
      -- Read the string table
      Dictionary
    dict <- BinHandle -> IO Dictionary -> IO Dictionary
    forall a. BinHandle -> IO a -> IO a
    forwardGet BinHandle
    bh0 (BinHandle -> IO Dictionary
    getDictionary BinHandle
    bh0)
      let bh :: BinHandle
    bh = BinHandle -> UserData -> BinHandle
    setUserData BinHandle
    bh0 (UserData -> BinHandle) -> UserData -> BinHandle
    forall a b. (a -> b) -> a -> b
    $ UserData
    noUserData { ud_get_fs = getDictFastString dict }

      Deps
    deps     <- BinHandle -> IO Deps
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
      Index
    idx      <- BinHandle -> IO Index -> IO Index
    forall a. BinHandle -> IO a -> IO a
    forwardGet BinHandle
    bh (BinHandle -> IO Index
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh)
      Bin ObjUnit
    payload_pos <- BinHandle -> IO (Bin ObjUnit)
    forall {k} (a :: k). BinHandle -> IO (Bin a)
    tellBin BinHandle
    bh

      Object -> IO Object
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Object -> IO Object) -> Object -> IO Object
    forall a b. (a -> b) -> a -> b
    $ Object
        { objModuleName :: ModuleName
    objModuleName    = ModuleName
    mod_name
        , objHandle :: BinHandle
    objHandle        = BinHandle
    bh
        , objPayloadOffset :: Bin ObjUnit
    objPayloadOffset = Bin ObjUnit
    payload_pos
        , objDeps :: Deps
    objDeps          = Deps
    deps
        , objIndex :: Index
    objIndex         = Index
    idx
        }

    -- | Parse object
    getObject :: BinHandle -> IO (Maybe Object)
    getObject :: BinHandle -> IO (Maybe Object)
    getObject BinHandle
    bh = do
      BinHandle -> IO (Either String ModuleName)
    getObjectHeader BinHandle
    bh IO (Either String ModuleName)
    -> (Either String ModuleName -> IO (Maybe Object))
    -> IO (Maybe Object)
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \case
        Left String
    _err      -> Maybe Object -> IO (Maybe Object)
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Maybe Object
    forall a. Maybe a
    Nothing
        Right ModuleName
    mod_name -> Object -> Maybe Object
    forall a. a -> Maybe a
    Just (Object -> Maybe Object) -> IO Object -> IO (Maybe Object)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> ModuleName -> IO Object
    getObjectBody BinHandle
    bh ModuleName
    mod_name

    -- | Read object from file
    --
    -- The object is still in memory after this (see objHandle).
    readObject :: FilePath -> IO (Maybe Object)
    readObject :: String -> IO (Maybe Object)
    readObject String
    file = do
      BinHandle
    bh <- String -> IO BinHandle
    readBinMem String
    file
      BinHandle -> IO (Maybe Object)
    getObject BinHandle
    bh

    -- | Reads only the part necessary to get the dependencies
    readObjectDeps :: FilePath -> IO (Maybe Deps)
    readObjectDeps :: String -> IO (Maybe Deps)
    readObjectDeps String
    file = do
      BinHandle
    bh <- String -> IO BinHandle
    readBinMem String
    file
      BinHandle -> IO (Maybe Object)
    getObject BinHandle
    bh IO (Maybe Object)
    -> (Maybe Object -> IO (Maybe Deps)) -> IO (Maybe Deps)
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \case
        Just Object
    obj -> Maybe Deps -> IO (Maybe Deps)
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Maybe Deps -> IO (Maybe Deps)) -> Maybe Deps -> IO (Maybe Deps)
    forall a b. (a -> b) -> a -> b
    $! Deps -> Maybe Deps
    forall a. a -> Maybe a
    Just (Deps -> Maybe Deps) -> Deps -> Maybe Deps
    forall a b. (a -> b) -> a -> b
    $! Object -> Deps
    objDeps Object
    obj
        Maybe Object
    Nothing  -> Maybe Deps -> IO (Maybe Deps)
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Maybe Deps
    forall a. Maybe a
    Nothing

    -- | Get units in the object file, using the given filtering function
    getObjectUnits :: Object -> (Word -> IndexEntry -> Bool) -> IO [ObjUnit]
    getObjectUnits :: Object -> (Word -> IndexEntry -> Bool) -> IO [ObjUnit]
    getObjectUnits Object
    obj Word -> IndexEntry -> Bool
    pred = ((IndexEntry, Word) -> IO (Maybe ObjUnit))
    -> [(IndexEntry, Word)] -> IO [ObjUnit]
    forall (m :: * -> *) a b.
    Applicative m =>
    (a -> m (Maybe b)) -> [a] -> m [b]
    mapMaybeM (IndexEntry, Word) -> IO (Maybe ObjUnit)
    read_entry (Index -> [Word] -> [(IndexEntry, Word)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip (Object -> Index
    objIndex Object
    obj) [Word
    0..])
      where
        bh :: BinHandle
    bh = Object -> BinHandle
    objHandle Object
    obj
        read_entry :: (IndexEntry, Word) -> IO (Maybe ObjUnit)
    read_entry (e :: IndexEntry
    e@(IndexEntry [FastString]
    syms Bin ObjUnit
    offset),Word
    i)
          | Word -> IndexEntry -> Bool
    pred Word
    i IndexEntry
    e  = do
              BinHandle -> Bin ObjUnit -> IO ()
    forall {k} (a :: k). BinHandle -> Bin a -> IO ()
    seekBin BinHandle
    bh Bin ObjUnit
    offset
              ObjUnit -> Maybe ObjUnit
    forall a. a -> Maybe a
    Just (ObjUnit -> Maybe ObjUnit) -> IO ObjUnit -> IO (Maybe ObjUnit)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [FastString] -> BinHandle -> IO ObjUnit
    getObjUnit [FastString]
    syms BinHandle
    bh
          | Bool
    otherwise = Maybe ObjUnit -> IO (Maybe ObjUnit)
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Maybe ObjUnit
    forall a. Maybe a
    Nothing

    -- | Read units in the object file, using the given filtering function
    readObjectUnits :: FilePath -> (Word -> IndexEntry -> Bool) -> IO [ObjUnit]
    readObjectUnits :: String -> (Word -> IndexEntry -> Bool) -> IO [ObjUnit]
    readObjectUnits String
    file Word -> IndexEntry -> Bool
    pred = do
      String -> IO (Maybe Object)
    readObject String
    file IO (Maybe Object) -> (Maybe Object -> IO [ObjUnit]) -> IO [ObjUnit]
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \case
        Maybe Object
    Nothing  -> [ObjUnit] -> IO [ObjUnit]
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure []
        Just Object
    obj -> Object -> (Word -> IndexEntry -> Bool) -> IO [ObjUnit]
    getObjectUnits Object
    obj Word -> IndexEntry -> Bool
    pred

    --------------------------------------------------------------------------------
    -- Helper functions
    --------------------------------------------------------------------------------

    putEnum :: Enum a => BinHandle -> a -> IO ()
    putEnum :: forall a. Enum a => BinHandle -> a -> IO ()
    putEnum BinHandle
    bh a
    x | Word16
    n Word16 -> Word16 -> Bool
    forall a. Ord a => a -> a -> Bool
    > Word16
    65535 = String -> IO ()
    forall a. HasCallStack => String -> a
    error (String
    "putEnum: out of range: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Word16 -> String
    forall a. Show a => a -> String
    show Word16
    n)
                 | Bool
    otherwise = BinHandle -> Word16 -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Word16
    n
      where n :: Word16
    n = Int -> Word16
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Int -> Word16) -> Int -> Word16
    forall a b. (a -> b) -> a -> b
    $ a -> Int
    forall a. Enum a => a -> Int
    fromEnum a
    x :: Word16

    getEnum :: Enum a => BinHandle -> IO a
    getEnum :: forall a. Enum a => BinHandle -> IO a
    getEnum BinHandle
    bh = Int -> a
    forall a. Enum a => Int -> a
    toEnum (Int -> a) -> (Word16 -> Int) -> Word16 -> a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Word16 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Word16 -> a) -> IO Word16 -> IO a
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (BinHandle -> IO Word16
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh :: IO Word16)

    -- | Helper to convert Int to Int32
    toI32 :: Int -> Int32
    toI32 :: Int -> Int32
    toI32 = Int -> Int32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral

    -- | Helper to convert Int32 to Int
    fromI32 :: Int32 -> Int
    fromI32 :: Int32 -> Int
    fromI32 = Int32 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral

    --------------------------------------------------------------------------------
    -- Binary Instances
    --------------------------------------------------------------------------------

    instance Binary IndexEntry where
      put_ :: BinHandle -> IndexEntry -> IO ()
    put_ BinHandle
    bh (IndexEntry [FastString]
    a Bin ObjUnit
    b) = BinHandle -> [FastString] -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh [FastString]
    a IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> Bin ObjUnit -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Bin ObjUnit
    b
      get :: BinHandle -> IO IndexEntry
    get BinHandle
    bh = [FastString] -> Bin ObjUnit -> IndexEntry
    IndexEntry ([FastString] -> Bin ObjUnit -> IndexEntry)
    -> IO [FastString] -> IO (Bin ObjUnit -> IndexEntry)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO [FastString]
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (Bin ObjUnit -> IndexEntry) -> IO (Bin ObjUnit) -> IO IndexEntry
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO (Bin ObjUnit)
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh

    instance Binary Deps where
      put_ :: BinHandle -> Deps -> IO ()
    put_ BinHandle
    bh (Deps Module
    m BlockIds
    r Map ExportedFun Int
    e Array Int BlockDeps
    b) = do
          BinHandle -> Module -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Module
    m
          BinHandle -> [Int32] -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh ((Int -> Int32) -> [Int] -> [Int32]
    forall a b. (a -> b) -> [a] -> [b]
    map Int -> Int32
    toI32 ([Int] -> [Int32]) -> [Int] -> [Int32]
    forall a b. (a -> b) -> a -> b
    $ BlockIds -> [Int]
    IS.toList BlockIds
    r)
          BinHandle -> [(ExportedFun, Int32)] -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh (((ExportedFun, Int) -> (ExportedFun, Int32))
    -> [(ExportedFun, Int)] -> [(ExportedFun, Int32)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\(ExportedFun
    x,Int
    y) -> (ExportedFun
    x, Int -> Int32
    toI32 Int
    y)) ([(ExportedFun, Int)] -> [(ExportedFun, Int32)])
    -> [(ExportedFun, Int)] -> [(ExportedFun, Int32)]
    forall a b. (a -> b) -> a -> b
    $ Map ExportedFun Int -> [(ExportedFun, Int)]
    forall k a. Map k a -> [(k, a)]
    M.toList Map ExportedFun Int
    e)
          BinHandle -> [BlockDeps] -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh (Array Int BlockDeps -> [BlockDeps]
    forall i e. Array i e -> [e]
    elems Array Int BlockDeps
    b)
      get :: BinHandle -> IO Deps
    get BinHandle
    bh = Module
    -> BlockIds -> Map ExportedFun Int -> Array Int BlockDeps -> Deps
    Deps (Module
     -> BlockIds -> Map ExportedFun Int -> Array Int BlockDeps -> Deps)
    -> IO Module
    -> IO
         (BlockIds -> Map ExportedFun Int -> Array Int BlockDeps -> Deps)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO Module
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
                 IO (BlockIds -> Map ExportedFun Int -> Array Int BlockDeps -> Deps)
    -> IO BlockIds
    -> IO (Map ExportedFun Int -> Array Int BlockDeps -> Deps)
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> ([Int] -> BlockIds
    IS.fromList ([Int] -> BlockIds) -> ([Int32] -> [Int]) -> [Int32] -> BlockIds
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Int32 -> Int) -> [Int32] -> [Int]
    forall a b. (a -> b) -> [a] -> [b]
    map Int32 -> Int
    fromI32 ([Int32] -> BlockIds) -> IO [Int32] -> IO BlockIds
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO [Int32]
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh)
                 IO (Map ExportedFun Int -> Array Int BlockDeps -> Deps)
    -> IO (Map ExportedFun Int) -> IO (Array Int BlockDeps -> Deps)
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> ([(ExportedFun, Int)] -> Map ExportedFun Int
    forall k a. Ord k => [(k, a)] -> Map k a
    M.fromList ([(ExportedFun, Int)] -> Map ExportedFun Int)
    -> ([(ExportedFun, Int32)] -> [(ExportedFun, Int)])
    -> [(ExportedFun, Int32)]
    -> Map ExportedFun Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ((ExportedFun, Int32) -> (ExportedFun, Int))
    -> [(ExportedFun, Int32)] -> [(ExportedFun, Int)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\(ExportedFun
    x,Int32
    y) -> (ExportedFun
    x, Int32 -> Int
    fromI32 Int32
    y)) ([(ExportedFun, Int32)] -> Map ExportedFun Int)
    -> IO [(ExportedFun, Int32)] -> IO (Map ExportedFun Int)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO [(ExportedFun, Int32)]
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh)
                 IO (Array Int BlockDeps -> Deps)
    -> IO (Array Int BlockDeps) -> IO Deps
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> ((\[BlockDeps]
    xs -> (Int, Int) -> [BlockDeps] -> Array Int BlockDeps
    forall i e. Ix i => (i, i) -> [e] -> Array i e
    listArray (Int
    0, [BlockDeps] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [BlockDeps]
    xs Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    1) [BlockDeps]
    xs) ([BlockDeps] -> Array Int BlockDeps)
    -> IO [BlockDeps] -> IO (Array Int BlockDeps)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO [BlockDeps]
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh)

    instance Binary BlockDeps where
      put_ :: BinHandle -> BlockDeps -> IO ()
    put_ BinHandle
    bh (BlockDeps [Int]
    bbd [ExportedFun]
    bfd) = BinHandle -> [Int] -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh [Int]
    bbd IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> [ExportedFun] -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh [ExportedFun]
    bfd
      get :: BinHandle -> IO BlockDeps
    get BinHandle
    bh = [Int] -> [ExportedFun] -> BlockDeps
    BlockDeps ([Int] -> [ExportedFun] -> BlockDeps)
    -> IO [Int] -> IO ([ExportedFun] -> BlockDeps)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO [Int]
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO ([ExportedFun] -> BlockDeps) -> IO [ExportedFun] -> IO BlockDeps
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO [ExportedFun]
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh

    instance Binary ForeignJSRef where
      put_ :: BinHandle -> ForeignJSRef -> IO ()
    put_ BinHandle
    bh (ForeignJSRef FastString
    span FastString
    pat Safety
    safety CCallConv
    cconv [FastString]
    arg_tys FastString
    res_ty) =
        BinHandle -> FastString -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh FastString
    span IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> FastString -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh FastString
    pat IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> Safety -> IO ()
    forall a. Enum a => BinHandle -> a -> IO ()
    putEnum BinHandle
    bh Safety
    safety IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> CCallConv -> IO ()
    forall a. Enum a => BinHandle -> a -> IO ()
    putEnum BinHandle
    bh CCallConv
    cconv IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> [FastString] -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh [FastString]
    arg_tys IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> FastString -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh FastString
    res_ty
      get :: BinHandle -> IO ForeignJSRef
    get BinHandle
    bh = FastString
    -> FastString
    -> Safety
    -> CCallConv
    -> [FastString]
    -> FastString
    -> ForeignJSRef
    ForeignJSRef (FastString
     -> FastString
     -> Safety
     -> CCallConv
     -> [FastString]
     -> FastString
     -> ForeignJSRef)
    -> IO FastString
    -> IO
         (FastString
          -> Safety
          -> CCallConv
          -> [FastString]
          -> FastString
          -> ForeignJSRef)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO FastString
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO
      (FastString
       -> Safety
       -> CCallConv
       -> [FastString]
       -> FastString
       -> ForeignJSRef)
    -> IO FastString
    -> IO
         (Safety -> CCallConv -> [FastString] -> FastString -> ForeignJSRef)
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO FastString
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO
      (Safety -> CCallConv -> [FastString] -> FastString -> ForeignJSRef)
    -> IO Safety
    -> IO (CCallConv -> [FastString] -> FastString -> ForeignJSRef)
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO Safety
    forall a. Enum a => BinHandle -> IO a
    getEnum BinHandle
    bh IO (CCallConv -> [FastString] -> FastString -> ForeignJSRef)
    -> IO CCallConv -> IO ([FastString] -> FastString -> ForeignJSRef)
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO CCallConv
    forall a. Enum a => BinHandle -> IO a
    getEnum BinHandle
    bh IO ([FastString] -> FastString -> ForeignJSRef)
    -> IO [FastString] -> IO (FastString -> ForeignJSRef)
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO [FastString]
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (FastString -> ForeignJSRef) -> IO FastString -> IO ForeignJSRef
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO FastString
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh

    instance Binary ExpFun where
      put_ :: BinHandle -> ExpFun -> IO ()
    put_ BinHandle
    bh (ExpFun Bool
    isIO [JSFFIType]
    args JSFFIType
    res) = BinHandle -> Bool -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Bool
    isIO IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> [JSFFIType] -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh [JSFFIType]
    args IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JSFFIType -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JSFFIType
    res
      get :: BinHandle -> IO ExpFun
    get BinHandle
    bh                        = Bool -> [JSFFIType] -> JSFFIType -> ExpFun
    ExpFun (Bool -> [JSFFIType] -> JSFFIType -> ExpFun)
    -> IO Bool -> IO ([JSFFIType] -> JSFFIType -> ExpFun)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO Bool
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO ([JSFFIType] -> JSFFIType -> ExpFun)
    -> IO [JSFFIType] -> IO (JSFFIType -> ExpFun)
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO [JSFFIType]
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (JSFFIType -> ExpFun) -> IO JSFFIType -> IO ExpFun
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO JSFFIType
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh

    instance Binary JStat where
      put_ :: BinHandle -> JStat -> IO ()
    put_ BinHandle
    bh (DeclStat Ident
    i Maybe JExpr
    e)       = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    1  IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> Ident -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Ident
    i IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> Maybe JExpr -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Maybe JExpr
    e
      put_ BinHandle
    bh (ReturnStat JExpr
    e)       = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    2  IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JExpr -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JExpr
    e
      put_ BinHandle
    bh (IfStat JExpr
    e JStat
    s1 JStat
    s2)     = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    3  IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JExpr -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JExpr
    e  IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JStat -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JStat
    s1 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JStat -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JStat
    s2
      put_ BinHandle
    bh (WhileStat Bool
    b JExpr
    e JStat
    s)    = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    4  IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> Bool -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Bool
    b  IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JExpr -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JExpr
    e  IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JStat -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JStat
    s
      put_ BinHandle
    bh (ForInStat Bool
    b Ident
    i JExpr
    e JStat
    s)  = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    5  IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> Bool -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Bool
    b  IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> Ident -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Ident
    i  IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JExpr -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JExpr
    e  IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JStat -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JStat
    s
      put_ BinHandle
    bh (SwitchStat JExpr
    e [(JExpr, JStat)]
    ss JStat
    s)  = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    6  IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JExpr -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JExpr
    e  IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> [(JExpr, JStat)] -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh [(JExpr, JStat)]
    ss IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JStat -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JStat
    s
      put_ BinHandle
    bh (TryStat JStat
    s1 Ident
    i JStat
    s2 JStat
    s3) = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    7  IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JStat -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JStat
    s1 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> Ident -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Ident
    i  IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JStat -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JStat
    s2 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JStat -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JStat
    s3
      put_ BinHandle
    bh (BlockStat [JStat]
    xs)       = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    8  IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> [JStat] -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh [JStat]
    xs
      put_ BinHandle
    bh (ApplStat JExpr
    e [JExpr]
    es)      = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    9  IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JExpr -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JExpr
    e  IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> [JExpr] -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh [JExpr]
    es
      put_ BinHandle
    bh (UOpStat JUOp
    o JExpr
    e)        = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    10 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JUOp -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JUOp
    o  IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JExpr -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JExpr
    e
      put_ BinHandle
    bh (AssignStat JExpr
    e1 JExpr
    e2)   = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    11 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JExpr -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JExpr
    e1 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JExpr -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JExpr
    e2
      put_ BinHandle
    _  (UnsatBlock {})      = String -> IO ()
    forall a. HasCallStack => String -> a
    error String
    "put_ bh JStat: UnsatBlock"
      put_ BinHandle
    bh (LabelStat LexicalFastString
    l JStat
    s)      = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    12 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> LexicalFastString -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh LexicalFastString
    l  IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JStat -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JStat
    s
      put_ BinHandle
    bh (BreakStat Maybe LexicalFastString
    ml)       = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    13 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> Maybe LexicalFastString -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Maybe LexicalFastString
    ml
      put_ BinHandle
    bh (ContinueStat Maybe LexicalFastString
    ml)    = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    14 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> Maybe LexicalFastString -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Maybe LexicalFastString
    ml
      get :: BinHandle -> IO JStat
    get BinHandle
    bh = BinHandle -> IO Word8
    getByte BinHandle
    bh IO Word8 -> (Word8 -> IO JStat) -> IO JStat
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \case
        Word8
    1  -> Ident -> Maybe JExpr -> JStat
    DeclStat     (Ident -> Maybe JExpr -> JStat)
    -> IO Ident -> IO (Maybe JExpr -> JStat)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO Ident
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (Maybe JExpr -> JStat) -> IO (Maybe JExpr) -> IO JStat
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO (Maybe JExpr)
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    2  -> JExpr -> JStat
    ReturnStat   (JExpr -> JStat) -> IO JExpr -> IO JStat
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO JExpr
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    3  -> JExpr -> JStat -> JStat -> JStat
    IfStat       (JExpr -> JStat -> JStat -> JStat)
    -> IO JExpr -> IO (JStat -> JStat -> JStat)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO JExpr
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (JStat -> JStat -> JStat) -> IO JStat -> IO (JStat -> JStat)
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO JStat
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (JStat -> JStat) -> IO JStat -> IO JStat
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO JStat
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    4  -> Bool -> JExpr -> JStat -> JStat
    WhileStat    (Bool -> JExpr -> JStat -> JStat)
    -> IO Bool -> IO (JExpr -> JStat -> JStat)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO Bool
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (JExpr -> JStat -> JStat) -> IO JExpr -> IO (JStat -> JStat)
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO JExpr
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (JStat -> JStat) -> IO JStat -> IO JStat
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO JStat
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    5  -> Bool -> Ident -> JExpr -> JStat -> JStat
    ForInStat    (Bool -> Ident -> JExpr -> JStat -> JStat)
    -> IO Bool -> IO (Ident -> JExpr -> JStat -> JStat)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO Bool
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (Ident -> JExpr -> JStat -> JStat)
    -> IO Ident -> IO (JExpr -> JStat -> JStat)
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO Ident
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (JExpr -> JStat -> JStat) -> IO JExpr -> IO (JStat -> JStat)
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO JExpr
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (JStat -> JStat) -> IO JStat -> IO JStat
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO JStat
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    6  -> JExpr -> [(JExpr, JStat)] -> JStat -> JStat
    SwitchStat   (JExpr -> [(JExpr, JStat)] -> JStat -> JStat)
    -> IO JExpr -> IO ([(JExpr, JStat)] -> JStat -> JStat)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO JExpr
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO ([(JExpr, JStat)] -> JStat -> JStat)
    -> IO [(JExpr, JStat)] -> IO (JStat -> JStat)
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO [(JExpr, JStat)]
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (JStat -> JStat) -> IO JStat -> IO JStat
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO JStat
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    7  -> JStat -> Ident -> JStat -> JStat -> JStat
    TryStat      (JStat -> Ident -> JStat -> JStat -> JStat)
    -> IO JStat -> IO (Ident -> JStat -> JStat -> JStat)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO JStat
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (Ident -> JStat -> JStat -> JStat)
    -> IO Ident -> IO (JStat -> JStat -> JStat)
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO Ident
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (JStat -> JStat -> JStat) -> IO JStat -> IO (JStat -> JStat)
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO JStat
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (JStat -> JStat) -> IO JStat -> IO JStat
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO JStat
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    8  -> [JStat] -> JStat
    BlockStat    ([JStat] -> JStat) -> IO [JStat] -> IO JStat
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO [JStat]
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    9  -> JExpr -> [JExpr] -> JStat
    ApplStat     (JExpr -> [JExpr] -> JStat) -> IO JExpr -> IO ([JExpr] -> JStat)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO JExpr
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO ([JExpr] -> JStat) -> IO [JExpr] -> IO JStat
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO [JExpr]
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    10 -> JUOp -> JExpr -> JStat
    UOpStat      (JUOp -> JExpr -> JStat) -> IO JUOp -> IO (JExpr -> JStat)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO JUOp
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (JExpr -> JStat) -> IO JExpr -> IO JStat
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO JExpr
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    11 -> JExpr -> JExpr -> JStat
    AssignStat   (JExpr -> JExpr -> JStat) -> IO JExpr -> IO (JExpr -> JStat)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO JExpr
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (JExpr -> JStat) -> IO JExpr -> IO JStat
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO JExpr
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    12 -> LexicalFastString -> JStat -> JStat
    LabelStat    (LexicalFastString -> JStat -> JStat)
    -> IO LexicalFastString -> IO (JStat -> JStat)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO LexicalFastString
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (JStat -> JStat) -> IO JStat -> IO JStat
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO JStat
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    13 -> Maybe LexicalFastString -> JStat
    BreakStat    (Maybe LexicalFastString -> JStat)
    -> IO (Maybe LexicalFastString) -> IO JStat
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO (Maybe LexicalFastString)
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    14 -> Maybe LexicalFastString -> JStat
    ContinueStat (Maybe LexicalFastString -> JStat)
    -> IO (Maybe LexicalFastString) -> IO JStat
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO (Maybe LexicalFastString)
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    n -> String -> IO JStat
    forall a. HasCallStack => String -> a
    error (String
    "Binary get bh JStat: invalid tag: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Word8 -> String
    forall a. Show a => a -> String
    show Word8
    n)

    instance Binary JExpr where
      put_ :: BinHandle -> JExpr -> IO ()
    put_ BinHandle
    bh (ValExpr JVal
    v)          = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    1 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JVal -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JVal
    v
      put_ BinHandle
    bh (SelExpr JExpr
    e Ident
    i)        = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    2 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JExpr -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JExpr
    e  IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> Ident -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Ident
    i
      put_ BinHandle
    bh (IdxExpr JExpr
    e1 JExpr
    e2)      = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    3 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JExpr -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JExpr
    e1 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JExpr -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JExpr
    e2
      put_ BinHandle
    bh (InfixExpr JOp
    o JExpr
    e1 JExpr
    e2)  = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    4 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JOp -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JOp
    o  IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JExpr -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JExpr
    e1 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JExpr -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JExpr
    e2
      put_ BinHandle
    bh (UOpExpr JUOp
    o JExpr
    e)        = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    5 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JUOp -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JUOp
    o  IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JExpr -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JExpr
    e
      put_ BinHandle
    bh (IfExpr JExpr
    e1 JExpr
    e2 JExpr
    e3)    = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    6 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JExpr -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JExpr
    e1 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JExpr -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JExpr
    e2 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JExpr -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JExpr
    e3
      put_ BinHandle
    bh (ApplExpr JExpr
    e [JExpr]
    es)      = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    7 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JExpr -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JExpr
    e  IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> [JExpr] -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh [JExpr]
    es
      put_ BinHandle
    _  (UnsatExpr {})       = String -> IO ()
    forall a. HasCallStack => String -> a
    error String
    "put_ bh JExpr: UnsatExpr"
      get :: BinHandle -> IO JExpr
    get BinHandle
    bh = BinHandle -> IO Word8
    getByte BinHandle
    bh IO Word8 -> (Word8 -> IO JExpr) -> IO JExpr
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \case
        Word8
    1 -> JVal -> JExpr
    ValExpr   (JVal -> JExpr) -> IO JVal -> IO JExpr
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO JVal
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    2 -> JExpr -> Ident -> JExpr
    SelExpr   (JExpr -> Ident -> JExpr) -> IO JExpr -> IO (Ident -> JExpr)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO JExpr
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (Ident -> JExpr) -> IO Ident -> IO JExpr
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO Ident
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    3 -> JExpr -> JExpr -> JExpr
    IdxExpr   (JExpr -> JExpr -> JExpr) -> IO JExpr -> IO (JExpr -> JExpr)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO JExpr
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (JExpr -> JExpr) -> IO JExpr -> IO JExpr
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO JExpr
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    4 -> JOp -> JExpr -> JExpr -> JExpr
    InfixExpr (JOp -> JExpr -> JExpr -> JExpr)
    -> IO JOp -> IO (JExpr -> JExpr -> JExpr)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO JOp
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (JExpr -> JExpr -> JExpr) -> IO JExpr -> IO (JExpr -> JExpr)
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO JExpr
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (JExpr -> JExpr) -> IO JExpr -> IO JExpr
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO JExpr
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    5 -> JUOp -> JExpr -> JExpr
    UOpExpr   (JUOp -> JExpr -> JExpr) -> IO JUOp -> IO (JExpr -> JExpr)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO JUOp
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (JExpr -> JExpr) -> IO JExpr -> IO JExpr
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO JExpr
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    6 -> JExpr -> JExpr -> JExpr -> JExpr
    IfExpr    (JExpr -> JExpr -> JExpr -> JExpr)
    -> IO JExpr -> IO (JExpr -> JExpr -> JExpr)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO JExpr
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (JExpr -> JExpr -> JExpr) -> IO JExpr -> IO (JExpr -> JExpr)
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO JExpr
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (JExpr -> JExpr) -> IO JExpr -> IO JExpr
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO JExpr
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    7 -> JExpr -> [JExpr] -> JExpr
    ApplExpr  (JExpr -> [JExpr] -> JExpr) -> IO JExpr -> IO ([JExpr] -> JExpr)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO JExpr
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO ([JExpr] -> JExpr) -> IO [JExpr] -> IO JExpr
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO [JExpr]
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    n -> String -> IO JExpr
    forall a. HasCallStack => String -> a
    error (String
    "Binary get bh JExpr: invalid tag: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Word8 -> String
    forall a. Show a => a -> String
    show Word8
    n)

    instance Binary JVal where
      put_ :: BinHandle -> JVal -> IO ()
    put_ BinHandle
    bh (JVar Ident
    i)      = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    1 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> Ident -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Ident
    i
      put_ BinHandle
    bh (JList [JExpr]
    es)    = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    2 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> [JExpr] -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh [JExpr]
    es
      put_ BinHandle
    bh (JDouble SaneDouble
    d)   = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    3 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> SaneDouble -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh SaneDouble
    d
      put_ BinHandle
    bh (JInt Integer
    i)      = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    4 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> Integer -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Integer
    i
      put_ BinHandle
    bh (JStr FastString
    xs)     = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    5 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> FastString -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh FastString
    xs
      put_ BinHandle
    bh (JRegEx FastString
    xs)   = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    6 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> FastString -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh FastString
    xs
      put_ BinHandle
    bh (JHash UniqMap FastString JExpr
    m)     = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    7 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> [(FastString, JExpr)] -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh (((FastString, JExpr) -> LexicalFastString)
    -> [(FastString, JExpr)] -> [(FastString, JExpr)]
    forall b a. Ord b => (a -> b) -> [a] -> [a]
    sortOn (FastString -> LexicalFastString
    LexicalFastString (FastString -> LexicalFastString)
    -> ((FastString, JExpr) -> FastString)
    -> (FastString, JExpr)
    -> LexicalFastString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (FastString, JExpr) -> FastString
    forall a b. (a, b) -> a
    fst) ([(FastString, JExpr)] -> [(FastString, JExpr)])
    -> [(FastString, JExpr)] -> [(FastString, JExpr)]
    forall a b. (a -> b) -> a -> b
    $ UniqMap FastString JExpr -> [(FastString, JExpr)]
    forall k a. UniqMap k a -> [(k, a)]
    nonDetEltsUniqMap UniqMap FastString JExpr
    m)
      put_ BinHandle
    bh (JFunc [Ident]
    is JStat
    s)  = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    8 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> [Ident] -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh [Ident]
    is IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> JStat -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh JStat
    s
      put_ BinHandle
    _  (UnsatVal {}) = String -> IO ()
    forall a. HasCallStack => String -> a
    error String
    "put_ bh JVal: UnsatVal"
      get :: BinHandle -> IO JVal
    get BinHandle
    bh = BinHandle -> IO Word8
    getByte BinHandle
    bh IO Word8 -> (Word8 -> IO JVal) -> IO JVal
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \case
        Word8
    1 -> Ident -> JVal
    JVar    (Ident -> JVal) -> IO Ident -> IO JVal
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO Ident
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    2 -> [JExpr] -> JVal
    JList   ([JExpr] -> JVal) -> IO [JExpr] -> IO JVal
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO [JExpr]
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    3 -> SaneDouble -> JVal
    JDouble (SaneDouble -> JVal) -> IO SaneDouble -> IO JVal
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO SaneDouble
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    4 -> Integer -> JVal
    JInt    (Integer -> JVal) -> IO Integer -> IO JVal
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO Integer
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    5 -> FastString -> JVal
    JStr    (FastString -> JVal) -> IO FastString -> IO JVal
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO FastString
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    6 -> FastString -> JVal
    JRegEx  (FastString -> JVal) -> IO FastString -> IO JVal
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO FastString
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    7 -> UniqMap FastString JExpr -> JVal
    JHash (UniqMap FastString JExpr -> JVal)
    -> ([(FastString, JExpr)] -> UniqMap FastString JExpr)
    -> [(FastString, JExpr)]
    -> JVal
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [(FastString, JExpr)] -> UniqMap FastString JExpr
    forall k a. Uniquable k => [(k, a)] -> UniqMap k a
    listToUniqMap ([(FastString, JExpr)] -> JVal)
    -> IO [(FastString, JExpr)] -> IO JVal
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO [(FastString, JExpr)]
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    8 -> [Ident] -> JStat -> JVal
    JFunc   ([Ident] -> JStat -> JVal) -> IO [Ident] -> IO (JStat -> JVal)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO [Ident]
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (JStat -> JVal) -> IO JStat -> IO JVal
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO JStat
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    n -> String -> IO JVal
    forall a. HasCallStack => String -> a
    error (String
    "Binary get bh JVal: invalid tag: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Word8 -> String
    forall a. Show a => a -> String
    show Word8
    n)

    instance Binary Ident where
      put_ :: BinHandle -> Ident -> IO ()
    put_ BinHandle
    bh (TxtI FastString
    xs) = BinHandle -> FastString -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh FastString
    xs
      get :: BinHandle -> IO Ident
    get BinHandle
    bh = FastString -> Ident
    TxtI (FastString -> Ident) -> IO FastString -> IO Ident
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO FastString
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh

    -- we need to preserve NaN and infinities, unfortunately the Binary instance for Double does not do this
    instance Binary SaneDouble where
      put_ :: BinHandle -> SaneDouble -> IO ()
    put_ BinHandle
    bh (SaneDouble Double
    d)
        | Double -> Bool
    forall a. RealFloat a => a -> Bool
    isNaN Double
    d               = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    1
        | Double -> Bool
    forall a. RealFloat a => a -> Bool
    isInfinite Double
    d Bool -> Bool -> Bool
    && Double
    d Double -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    > Double
    0 = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    2
        | Double -> Bool
    forall a. RealFloat a => a -> Bool
    isInfinite Double
    d Bool -> Bool -> Bool
    && Double
    d Double -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    < Double
    0 = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    3
        | Double -> Bool
    forall a. RealFloat a => a -> Bool
    isNegativeZero Double
    d      = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    4
        | Bool
    otherwise             = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    5 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> Word64 -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh (Double -> Word64
    castDoubleToWord64 Double
    d)
      get :: BinHandle -> IO SaneDouble
    get BinHandle
    bh = BinHandle -> IO Word8
    getByte BinHandle
    bh IO Word8 -> (Word8 -> IO SaneDouble) -> IO SaneDouble
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \case
        Word8
    1 -> SaneDouble -> IO SaneDouble
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (SaneDouble -> IO SaneDouble) -> SaneDouble -> IO SaneDouble
    forall a b. (a -> b) -> a -> b
    $ Double -> SaneDouble
    SaneDouble (Double
    0    Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Double
    0)
        Word8
    2 -> SaneDouble -> IO SaneDouble
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (SaneDouble -> IO SaneDouble) -> SaneDouble -> IO SaneDouble
    forall a b. (a -> b) -> a -> b
    $ Double -> SaneDouble
    SaneDouble (Double
    1    Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Double
    0)
        Word8
    3 -> SaneDouble -> IO SaneDouble
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (SaneDouble -> IO SaneDouble) -> SaneDouble -> IO SaneDouble
    forall a b. (a -> b) -> a -> b
    $ Double -> SaneDouble
    SaneDouble ((-Double
    1) Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Double
    0)
        Word8
    4 -> SaneDouble -> IO SaneDouble
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (SaneDouble -> IO SaneDouble) -> SaneDouble -> IO SaneDouble
    forall a b. (a -> b) -> a -> b
    $ Double -> SaneDouble
    SaneDouble (-Double
    0)
        Word8
    5 -> Double -> SaneDouble
    SaneDouble (Double -> SaneDouble)
    -> (Word64 -> Double) -> Word64 -> SaneDouble
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Word64 -> Double
    castWord64ToDouble (Word64 -> SaneDouble) -> IO Word64 -> IO SaneDouble
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO Word64
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    n -> String -> IO SaneDouble
    forall a. HasCallStack => String -> a
    error (String
    "Binary get bh SaneDouble: invalid tag: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Word8 -> String
    forall a. Show a => a -> String
    show Word8
    n)

    instance Binary ClosureInfo where
      put_ :: BinHandle -> ClosureInfo -> IO ()
    put_ BinHandle
    bh (ClosureInfo Ident
    v CIRegs
    regs FastString
    name CILayout
    layo CIType
    typ CIStatic
    static) = do
        BinHandle -> Ident -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Ident
    v IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> CIRegs -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh CIRegs
    regs IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> FastString -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh FastString
    name IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> CILayout -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh CILayout
    layo IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> CIType -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh CIType
    typ IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> CIStatic -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh CIStatic
    static
      get :: BinHandle -> IO ClosureInfo
    get BinHandle
    bh = Ident
    -> CIRegs
    -> FastString
    -> CILayout
    -> CIType
    -> CIStatic
    -> ClosureInfo
    ClosureInfo (Ident
     -> CIRegs
     -> FastString
     -> CILayout
     -> CIType
     -> CIStatic
     -> ClosureInfo)
    -> IO Ident
    -> IO
         (CIRegs
          -> FastString -> CILayout -> CIType -> CIStatic -> ClosureInfo)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO Ident
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO
      (CIRegs
       -> FastString -> CILayout -> CIType -> CIStatic -> ClosureInfo)
    -> IO CIRegs
    -> IO (FastString -> CILayout -> CIType -> CIStatic -> ClosureInfo)
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO CIRegs
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (FastString -> CILayout -> CIType -> CIStatic -> ClosureInfo)
    -> IO FastString
    -> IO (CILayout -> CIType -> CIStatic -> ClosureInfo)
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO FastString
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (CILayout -> CIType -> CIStatic -> ClosureInfo)
    -> IO CILayout -> IO (CIType -> CIStatic -> ClosureInfo)
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO CILayout
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (CIType -> CIStatic -> ClosureInfo)
    -> IO CIType -> IO (CIStatic -> ClosureInfo)
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO CIType
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (CIStatic -> ClosureInfo) -> IO CIStatic -> IO ClosureInfo
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO CIStatic
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh

    instance Binary JSFFIType where
      put_ :: BinHandle -> JSFFIType -> IO ()
    put_ BinHandle
    bh = BinHandle -> JSFFIType -> IO ()
    forall a. Enum a => BinHandle -> a -> IO ()
    putEnum BinHandle
    bh
      get :: BinHandle -> IO JSFFIType
    get BinHandle
    bh = BinHandle -> IO JSFFIType
    forall a. Enum a => BinHandle -> IO a
    getEnum BinHandle
    bh

    instance Binary VarType where
      put_ :: BinHandle -> VarType -> IO ()
    put_ BinHandle
    bh = BinHandle -> VarType -> IO ()
    forall a. Enum a => BinHandle -> a -> IO ()
    putEnum BinHandle
    bh
      get :: BinHandle -> IO VarType
    get BinHandle
    bh = BinHandle -> IO VarType
    forall a. Enum a => BinHandle -> IO a
    getEnum BinHandle
    bh

    instance Binary CIRegs where
      put_ :: BinHandle -> CIRegs -> IO ()
    put_ BinHandle
    bh CIRegs
    CIRegsUnknown       = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    1
      put_ BinHandle
    bh (CIRegs Int
    skip [VarType]
    types) = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    2 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> Int -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Int
    skip IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> [VarType] -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh [VarType]
    types
      get :: BinHandle -> IO CIRegs
    get BinHandle
    bh = BinHandle -> IO Word8
    getByte BinHandle
    bh IO Word8 -> (Word8 -> IO CIRegs) -> IO CIRegs
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \case
        Word8
    1 -> CIRegs -> IO CIRegs
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure CIRegs
    CIRegsUnknown
        Word8
    2 -> Int -> [VarType] -> CIRegs
    CIRegs (Int -> [VarType] -> CIRegs) -> IO Int -> IO ([VarType] -> CIRegs)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO Int
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO ([VarType] -> CIRegs) -> IO [VarType] -> IO CIRegs
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO [VarType]
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    n -> String -> IO CIRegs
    forall a. HasCallStack => String -> a
    error (String
    "Binary get bh CIRegs: invalid tag: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Word8 -> String
    forall a. Show a => a -> String
    show Word8
    n)

    instance Binary JOp where
      put_ :: BinHandle -> JOp -> IO ()
    put_ BinHandle
    bh = BinHandle -> JOp -> IO ()
    forall a. Enum a => BinHandle -> a -> IO ()
    putEnum BinHandle
    bh
      get :: BinHandle -> IO JOp
    get BinHandle
    bh = BinHandle -> IO JOp
    forall a. Enum a => BinHandle -> IO a
    getEnum BinHandle
    bh

    instance Binary JUOp where
      put_ :: BinHandle -> JUOp -> IO ()
    put_ BinHandle
    bh = BinHandle -> JUOp -> IO ()
    forall a. Enum a => BinHandle -> a -> IO ()
    putEnum BinHandle
    bh
      get :: BinHandle -> IO JUOp
    get BinHandle
    bh = BinHandle -> IO JUOp
    forall a. Enum a => BinHandle -> IO a
    getEnum BinHandle
    bh

    -- 16 bit sizes should be enough...
    instance Binary CILayout where
      put_ :: BinHandle -> CILayout -> IO ()
    put_ BinHandle
    bh CILayout
    CILayoutVariable           = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    1
      put_ BinHandle
    bh (CILayoutUnknown Int
    size)     = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    2 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> Int -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Int
    size
      put_ BinHandle
    bh (CILayoutFixed Int
    size [VarType]
    types) = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    3 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> Int -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Int
    size IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> [VarType] -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh [VarType]
    types
      get :: BinHandle -> IO CILayout
    get BinHandle
    bh = BinHandle -> IO Word8
    getByte BinHandle
    bh IO Word8 -> (Word8 -> IO CILayout) -> IO CILayout
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \case
        Word8
    1 -> CILayout -> IO CILayout
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure CILayout
    CILayoutVariable
        Word8
    2 -> Int -> CILayout
    CILayoutUnknown (Int -> CILayout) -> IO Int -> IO CILayout
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO Int
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    3 -> Int -> [VarType] -> CILayout
    CILayoutFixed   (Int -> [VarType] -> CILayout)
    -> IO Int -> IO ([VarType] -> CILayout)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO Int
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO ([VarType] -> CILayout) -> IO [VarType] -> IO CILayout
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO [VarType]
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    n -> String -> IO CILayout
    forall a. HasCallStack => String -> a
    error (String
    "Binary get bh CILayout: invalid tag: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Word8 -> String
    forall a. Show a => a -> String
    show Word8
    n)

    instance Binary CIStatic where
      put_ :: BinHandle -> CIStatic -> IO ()
    put_ BinHandle
    bh (CIStaticRefs [FastString]
    refs) = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    1 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> [FastString] -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh [FastString]
    refs
      get :: BinHandle -> IO CIStatic
    get BinHandle
    bh = BinHandle -> IO Word8
    getByte BinHandle
    bh IO Word8 -> (Word8 -> IO CIStatic) -> IO CIStatic
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \case
        Word8
    1 -> [FastString] -> CIStatic
    CIStaticRefs ([FastString] -> CIStatic) -> IO [FastString] -> IO CIStatic
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO [FastString]
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    n -> String -> IO CIStatic
    forall a. HasCallStack => String -> a
    error (String
    "Binary get bh CIStatic: invalid tag: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Word8 -> String
    forall a. Show a => a -> String
    show Word8
    n)

    instance Binary CIType where
      put_ :: BinHandle -> CIType -> IO ()
    put_ BinHandle
    bh (CIFun Int
    arity Int
    regs) = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    1 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> Int -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Int
    arity IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> Int -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Int
    regs
      put_ BinHandle
    bh CIType
    CIThunk            = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    2
      put_ BinHandle
    bh (CICon Int
    conTag)     = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    3 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> Int -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Int
    conTag
      put_ BinHandle
    bh CIType
    CIPap              = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    4
      put_ BinHandle
    bh CIType
    CIBlackhole        = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    5
      put_ BinHandle
    bh CIType
    CIStackFrame       = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    6
      get :: BinHandle -> IO CIType
    get BinHandle
    bh = BinHandle -> IO Word8
    getByte BinHandle
    bh IO Word8 -> (Word8 -> IO CIType) -> IO CIType
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \case
        Word8
    1 -> Int -> Int -> CIType
    CIFun (Int -> Int -> CIType) -> IO Int -> IO (Int -> CIType)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO Int
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (Int -> CIType) -> IO Int -> IO CIType
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO Int
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    2 -> CIType -> IO CIType
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure CIType
    CIThunk
        Word8
    3 -> Int -> CIType
    CICon (Int -> CIType) -> IO Int -> IO CIType
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO Int
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    4 -> CIType -> IO CIType
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure CIType
    CIPap
        Word8
    5 -> CIType -> IO CIType
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure CIType
    CIBlackhole
        Word8
    6 -> CIType -> IO CIType
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure CIType
    CIStackFrame
        Word8
    n -> String -> IO CIType
    forall a. HasCallStack => String -> a
    error (String
    "Binary get bh CIType: invalid tag: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Word8 -> String
    forall a. Show a => a -> String
    show Word8
    n)

    instance Binary ExportedFun where
      put_ :: BinHandle -> ExportedFun -> IO ()
    put_ BinHandle
    bh (ExportedFun Module
    modu LexicalFastString
    symb) = BinHandle -> Module -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Module
    modu IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> LexicalFastString -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh LexicalFastString
    symb
      get :: BinHandle -> IO ExportedFun
    get BinHandle
    bh = Module -> LexicalFastString -> ExportedFun
    ExportedFun (Module -> LexicalFastString -> ExportedFun)
    -> IO Module -> IO (LexicalFastString -> ExportedFun)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO Module
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (LexicalFastString -> ExportedFun)
    -> IO LexicalFastString -> IO ExportedFun
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO LexicalFastString
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh

    instance Binary StaticInfo where
      put_ :: BinHandle -> StaticInfo -> IO ()
    put_ BinHandle
    bh (StaticInfo FastString
    ident StaticVal
    val Maybe Ident
    cc) = BinHandle -> FastString -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh FastString
    ident IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> StaticVal -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh StaticVal
    val IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> Maybe Ident -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Maybe Ident
    cc
      get :: BinHandle -> IO StaticInfo
    get BinHandle
    bh = FastString -> StaticVal -> Maybe Ident -> StaticInfo
    StaticInfo (FastString -> StaticVal -> Maybe Ident -> StaticInfo)
    -> IO FastString -> IO (StaticVal -> Maybe Ident -> StaticInfo)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO FastString
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (StaticVal -> Maybe Ident -> StaticInfo)
    -> IO StaticVal -> IO (Maybe Ident -> StaticInfo)
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO StaticVal
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (Maybe Ident -> StaticInfo) -> IO (Maybe Ident) -> IO StaticInfo
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO (Maybe Ident)
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh

    instance Binary StaticVal where
      put_ :: BinHandle -> StaticVal -> IO ()
    put_ BinHandle
    bh (StaticFun FastString
    f [StaticArg]
    args)   = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    1 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> FastString -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh FastString
    f  IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> [StaticArg] -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh [StaticArg]
    args
      put_ BinHandle
    bh (StaticThunk Maybe (FastString, [StaticArg])
    t)      = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    2 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> Maybe (FastString, [StaticArg]) -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Maybe (FastString, [StaticArg])
    t
      put_ BinHandle
    bh (StaticUnboxed StaticUnboxed
    u)    = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    3 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> StaticUnboxed -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh StaticUnboxed
    u
      put_ BinHandle
    bh (StaticData FastString
    dc [StaticArg]
    args) = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    4 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> FastString -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh FastString
    dc IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> [StaticArg] -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh [StaticArg]
    args
      put_ BinHandle
    bh (StaticList [StaticArg]
    xs Maybe FastString
    t)    = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    5 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> [StaticArg] -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh [StaticArg]
    xs IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> Maybe FastString -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Maybe FastString
    t
      get :: BinHandle -> IO StaticVal
    get BinHandle
    bh = BinHandle -> IO Word8
    getByte BinHandle
    bh IO Word8 -> (Word8 -> IO StaticVal) -> IO StaticVal
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \case
        Word8
    1 -> FastString -> [StaticArg] -> StaticVal
    StaticFun     (FastString -> [StaticArg] -> StaticVal)
    -> IO FastString -> IO ([StaticArg] -> StaticVal)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO FastString
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO ([StaticArg] -> StaticVal) -> IO [StaticArg] -> IO StaticVal
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO [StaticArg]
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    2 -> Maybe (FastString, [StaticArg]) -> StaticVal
    StaticThunk   (Maybe (FastString, [StaticArg]) -> StaticVal)
    -> IO (Maybe (FastString, [StaticArg])) -> IO StaticVal
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO (Maybe (FastString, [StaticArg]))
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    3 -> StaticUnboxed -> StaticVal
    StaticUnboxed (StaticUnboxed -> StaticVal) -> IO StaticUnboxed -> IO StaticVal
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO StaticUnboxed
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    4 -> FastString -> [StaticArg] -> StaticVal
    StaticData    (FastString -> [StaticArg] -> StaticVal)
    -> IO FastString -> IO ([StaticArg] -> StaticVal)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO FastString
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO ([StaticArg] -> StaticVal) -> IO [StaticArg] -> IO StaticVal
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO [StaticArg]
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    5 -> [StaticArg] -> Maybe FastString -> StaticVal
    StaticList    ([StaticArg] -> Maybe FastString -> StaticVal)
    -> IO [StaticArg] -> IO (Maybe FastString -> StaticVal)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO [StaticArg]
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (Maybe FastString -> StaticVal)
    -> IO (Maybe FastString) -> IO StaticVal
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO (Maybe FastString)
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    n -> String -> IO StaticVal
    forall a. HasCallStack => String -> a
    error (String
    "Binary get bh StaticVal: invalid tag " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Word8 -> String
    forall a. Show a => a -> String
    show Word8
    n)

    instance Binary StaticUnboxed where
      put_ :: BinHandle -> StaticUnboxed -> IO ()
    put_ BinHandle
    bh (StaticUnboxedBool Bool
    b)           = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    1 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> Bool -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Bool
    b
      put_ BinHandle
    bh (StaticUnboxedInt Integer
    i)            = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    2 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> Integer -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Integer
    i
      put_ BinHandle
    bh (StaticUnboxedDouble SaneDouble
    d)         = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    3 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> SaneDouble -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh SaneDouble
    d
      put_ BinHandle
    bh (StaticUnboxedString ByteString
    str)       = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    4 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> ByteString -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh ByteString
    str
      put_ BinHandle
    bh (StaticUnboxedStringOffset ByteString
    str) = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    5 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> ByteString -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh ByteString
    str
      get :: BinHandle -> IO StaticUnboxed
    get BinHandle
    bh = BinHandle -> IO Word8
    getByte BinHandle
    bh IO Word8 -> (Word8 -> IO StaticUnboxed) -> IO StaticUnboxed
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \case
        Word8
    1 -> Bool -> StaticUnboxed
    StaticUnboxedBool         (Bool -> StaticUnboxed) -> IO Bool -> IO StaticUnboxed
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO Bool
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    2 -> Integer -> StaticUnboxed
    StaticUnboxedInt          (Integer -> StaticUnboxed) -> IO Integer -> IO StaticUnboxed
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO Integer
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    3 -> SaneDouble -> StaticUnboxed
    StaticUnboxedDouble       (SaneDouble -> StaticUnboxed) -> IO SaneDouble -> IO StaticUnboxed
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO SaneDouble
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    4 -> ByteString -> StaticUnboxed
    StaticUnboxedString       (ByteString -> StaticUnboxed) -> IO ByteString -> IO StaticUnboxed
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO ByteString
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    5 -> ByteString -> StaticUnboxed
    StaticUnboxedStringOffset (ByteString -> StaticUnboxed) -> IO ByteString -> IO StaticUnboxed
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO ByteString
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    n -> String -> IO StaticUnboxed
    forall a. HasCallStack => String -> a
    error (String
    "Binary get bh StaticUnboxed: invalid tag " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Word8 -> String
    forall a. Show a => a -> String
    show Word8
    n)

    instance Binary StaticArg where
      put_ :: BinHandle -> StaticArg -> IO ()
    put_ BinHandle
    bh (StaticObjArg FastString
    i)      = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    1 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> FastString -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh FastString
    i
      put_ BinHandle
    bh (StaticLitArg StaticLit
    p)      = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    2 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> StaticLit -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh StaticLit
    p
      put_ BinHandle
    bh (StaticConArg FastString
    c [StaticArg]
    args) = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    3 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> FastString -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh FastString
    c IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> [StaticArg] -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh [StaticArg]
    args
      get :: BinHandle -> IO StaticArg
    get BinHandle
    bh = BinHandle -> IO Word8
    getByte BinHandle
    bh IO Word8 -> (Word8 -> IO StaticArg) -> IO StaticArg
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \case
        Word8
    1 -> FastString -> StaticArg
    StaticObjArg (FastString -> StaticArg) -> IO FastString -> IO StaticArg
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO FastString
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    2 -> StaticLit -> StaticArg
    StaticLitArg (StaticLit -> StaticArg) -> IO StaticLit -> IO StaticArg
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO StaticLit
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    3 -> FastString -> [StaticArg] -> StaticArg
    StaticConArg (FastString -> [StaticArg] -> StaticArg)
    -> IO FastString -> IO ([StaticArg] -> StaticArg)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO FastString
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO ([StaticArg] -> StaticArg) -> IO [StaticArg] -> IO StaticArg
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO [StaticArg]
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    n -> String -> IO StaticArg
    forall a. HasCallStack => String -> a
    error (String
    "Binary get bh StaticArg: invalid tag " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Word8 -> String
    forall a. Show a => a -> String
    show Word8
    n)

    instance Binary StaticLit where
      put_ :: BinHandle -> StaticLit -> IO ()
    put_ BinHandle
    bh (BoolLit Bool
    b)    = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    1 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> Bool -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Bool
    b
      put_ BinHandle
    bh (IntLit Integer
    i)     = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    2 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> Integer -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Integer
    i
      put_ BinHandle
    bh StaticLit
    NullLit        = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    3
      put_ BinHandle
    bh (DoubleLit SaneDouble
    d)  = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    4 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> SaneDouble -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh SaneDouble
    d
      put_ BinHandle
    bh (StringLit FastString
    t)  = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    5 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> FastString -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh FastString
    t
      put_ BinHandle
    bh (BinLit ByteString
    b)     = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    6 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> ByteString -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh ByteString
    b
      put_ BinHandle
    bh (LabelLit Bool
    b FastString
    t) = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    7 IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> Bool -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh Bool
    b IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BinHandle -> FastString -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh FastString
    t
      get :: BinHandle -> IO StaticLit
    get BinHandle
    bh = BinHandle -> IO Word8
    getByte BinHandle
    bh IO Word8 -> (Word8 -> IO StaticLit) -> IO StaticLit
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \case
        Word8
    1 -> Bool -> StaticLit
    BoolLit   (Bool -> StaticLit) -> IO Bool -> IO StaticLit
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO Bool
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    2 -> Integer -> StaticLit
    IntLit    (Integer -> StaticLit) -> IO Integer -> IO StaticLit
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO Integer
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    3 -> StaticLit -> IO StaticLit
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure StaticLit
    NullLit
        Word8
    4 -> SaneDouble -> StaticLit
    DoubleLit (SaneDouble -> StaticLit) -> IO SaneDouble -> IO StaticLit
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO SaneDouble
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    5 -> FastString -> StaticLit
    StringLit (FastString -> StaticLit) -> IO FastString -> IO StaticLit
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO FastString
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    6 -> ByteString -> StaticLit
    BinLit    (ByteString -> StaticLit) -> IO ByteString -> IO StaticLit
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO ByteString
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    7 -> Bool -> FastString -> StaticLit
    LabelLit  (Bool -> FastString -> StaticLit)
    -> IO Bool -> IO (FastString -> StaticLit)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> BinHandle -> IO Bool
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh IO (FastString -> StaticLit) -> IO FastString -> IO StaticLit
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> BinHandle -> IO FastString
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh
        Word8
    n -> String -> IO StaticLit
    forall a. HasCallStack => String -> a
    error (String
    "Binary get bh StaticLit: invalid tag " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Word8 -> String
    forall a. Show a => a -> String
    show Word8
    n)