module Unison.Runtime.ANF.Serialize.ValueV5
  ( getValueWithHeader,
    putValueWithHeader,
    putVersionedValue,
    versionedValueBytes,
  )
where

import Control.Monad (replicateM)
import Data.ByteString.Builder (Builder)
import Data.ByteString.Builder qualified as BU
import Data.ByteString.Lazy qualified as L
import Unison.Reference (Reference)
import Unison.Runtime.ANF as ANF hiding (Tag)
import Unison.Runtime.ANF.Serialize.CodeV4
import Unison.Runtime.ANF.Serialize.Tags
import Unison.Runtime.Referenced
import Unison.Runtime.Serialize hiding
  ( getConstructorReference,
    getReference,
    getReferent,
    putConstructorReference,
    putReference,
    putReferent,
  )
import Unison.Runtime.Serialize qualified as SER
import Unison.Runtime.Serialize.Get
import Unison.Util.Text qualified as Util.Text
import Prelude hiding (getChar, putChar)

putGroupRef :: GroupRef RefNum -> Builder
putGroupRef :: GroupRef RefNum -> Builder
putGroupRef (GR RefNum
r Word64
i) = RefNum -> Builder
putRefNum RefNum
r Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word64 -> Builder
forall a.
(Integral a, Integral (Unsigned a), Bits (Unsigned a)) =>
a -> Builder
putVarInt Word64
i
{-# INLINE putGroupRef #-}

getGroupRef :: (PrimBase m) => Get m (GroupRef RefNum)
getGroupRef :: forall (m :: * -> *). PrimBase m => Get m (GroupRef RefNum)
getGroupRef = RefNum -> Word64 -> GroupRef RefNum
forall ref. ref -> Word64 -> GroupRef ref
GR (RefNum -> Word64 -> GroupRef RefNum)
-> Get m RefNum -> Get m (Word64 -> GroupRef RefNum)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get m RefNum
forall (m :: * -> *). PrimBase m => Get m RefNum
getRefNum Get m (Word64 -> GroupRef RefNum)
-> Get m Word64 -> Get m (GroupRef RefNum)
forall a b. Get m (a -> b) -> Get m a -> Get m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get m Word64
forall int (m :: * -> *).
(Bits int, Num int, Ord int, PrimBase m) =>
Get m int
getVarInt
{-# INLINE getGroupRef #-}

-- Notes
--
-- Starting with version 4 of the value format, it is expected that
-- unboxed data does not actually occur in the values being sent. For
-- most values this was not a problem:
--
--   - Partial applications had no way of directly including unboxed
--     values, because they all result from surface level unison
--     applications
--   - Unboxed values in Data only occurred to represent certain
--     builtin types. Those have been replaced by BLits.
--
-- However, some work was required to make sure no unboxed data ended
-- up in Cont. The runtime has been modified to avoid using the
-- unboxed stack in generated code, so now only builtins use it,
-- effectively. Since continuations are never captured inside builtins
-- (and even if we wanted to do that, we could arrange for a clean
-- unboxed stack), this is no longer a problem, either.
--
-- So, unboxed data is completely absent from the format. We are now
-- exchanging unison surface values, effectively.
--
-- -----------------
--
-- Version 5 departs significantly from previous versions to try to
-- optimize the format. The two major changes are:
--
--   1. Using variable width integers everywhere to avoid
--      unnecessarily padded values for tags and such
--   2. Pulling references out into a header section so that each is
--      only serialized once, and most reference occurrences are just
--      numbers.
--
-- this second change reduces the size of the format considerably, as
-- most of the serialized representation previously was repeated
-- occurrences of the 64 byte hashes.
--
-- At the moment, the reference change is implemented by using stable
-- names, and expecting canonically constructed values. This was done
-- to avoid a significant refactoring effort, but should be able to be
-- reworked in the future.
putValue :: Value RefNum -> Builder
putValue :: Value RefNum -> Builder
putValue = \case
  Partial GroupRef RefNum
gr ValList RefNum
vs ->
    VaTag -> Builder
forall t. Tag t => t -> Builder
putTag VaTag
PartialT
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> GroupRef RefNum -> Builder
putGroupRef GroupRef RefNum
gr
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> (Value RefNum -> Builder) -> ValList RefNum -> Builder
forall (f :: * -> *) a.
Foldable f =>
(a -> Builder) -> f a -> Builder
putFoldable Value RefNum -> Builder
putValue ValList RefNum
vs
  Data RefNum
r Word64
t ValList RefNum
vs ->
    VaTag -> Builder
forall t. Tag t => t -> Builder
putTag VaTag
DataT
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> RefNum -> Builder
putRefNum RefNum
r
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word64 -> Builder
forall a.
(Integral a, Integral (Unsigned a), Bits (Unsigned a)) =>
a -> Builder
putVarInt Word64
t
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> (Value RefNum -> Builder) -> ValList RefNum -> Builder
forall (f :: * -> *) a.
Foldable f =>
(a -> Builder) -> f a -> Builder
putFoldable Value RefNum -> Builder
putValue ValList RefNum
vs
  Cont ValList RefNum
bs Cont RefNum
k ->
    VaTag -> Builder
forall t. Tag t => t -> Builder
putTag VaTag
ContT
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> (Value RefNum -> Builder) -> ValList RefNum -> Builder
forall (f :: * -> *) a.
Foldable f =>
(a -> Builder) -> f a -> Builder
putFoldable Value RefNum -> Builder
putValue ValList RefNum
bs
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Cont RefNum -> Builder
putCont Cont RefNum
k
  BLit BLit RefNum
l -> VaTag -> Builder
forall t. Tag t => t -> Builder
putTag VaTag
BLitT Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> BLit RefNum -> Builder
putBLit BLit RefNum
l

getValue :: (PrimBase m) => Get m (Value RefNum)
getValue :: forall (m :: * -> *). PrimBase m => Get m (Value RefNum)
getValue =
  Get m VaTag
forall (m :: * -> *) t. (PrimBase m, Tag t) => Get m t
getTag Get m VaTag
-> (VaTag -> Get m (Value RefNum)) -> Get m (Value RefNum)
forall a b. Get m a -> (a -> Get m b) -> Get m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    VaTag
PartialT -> do
      GroupRef RefNum
gr <- Get m (GroupRef RefNum)
forall (m :: * -> *). PrimBase m => Get m (GroupRef RefNum)
getGroupRef
      ValList RefNum
vs <- Get m (Value RefNum) -> Get m (ValList RefNum)
forall (m :: * -> *) a. PrimBase m => Get m a -> Get m [a]
getList Get m (Value RefNum)
forall (m :: * -> *). PrimBase m => Get m (Value RefNum)
getValue
      pure $ GroupRef RefNum -> ValList RefNum -> Value RefNum
forall ref. GroupRef ref -> ValList ref -> Value ref
Partial GroupRef RefNum
gr ValList RefNum
vs
    VaTag
DataT -> do
      RefNum
r <- Get m RefNum
forall (m :: * -> *). PrimBase m => Get m RefNum
getRefNum
      Word64
w <- Get m Word64
forall int (m :: * -> *).
(Bits int, Num int, Ord int, PrimBase m) =>
Get m int
getVarInt
      ValList RefNum
vs <- Get m (Value RefNum) -> Get m (ValList RefNum)
forall (m :: * -> *) a. PrimBase m => Get m a -> Get m [a]
getList Get m (Value RefNum)
forall (m :: * -> *). PrimBase m => Get m (Value RefNum)
getValue
      pure $ RefNum -> Word64 -> ValList RefNum -> Value RefNum
forall ref. ref -> Word64 -> ValList ref -> Value ref
Data RefNum
r Word64
w ValList RefNum
vs
    VaTag
ContT -> do
      ValList RefNum
bs <- Get m (Value RefNum) -> Get m (ValList RefNum)
forall (m :: * -> *) a. PrimBase m => Get m a -> Get m [a]
getList Get m (Value RefNum)
forall (m :: * -> *). PrimBase m => Get m (Value RefNum)
getValue
      Cont RefNum
k <- Get m (Cont RefNum)
forall (m :: * -> *). PrimBase m => Get m (Cont RefNum)
getCont
      pure $ ValList RefNum -> Cont RefNum -> Value RefNum
forall ref. ValList ref -> Cont ref -> Value ref
Cont ValList RefNum
bs Cont RefNum
k
    VaTag
BLitT -> BLit RefNum -> Value RefNum
forall ref. BLit ref -> Value ref
BLit (BLit RefNum -> Value RefNum)
-> Get m (BLit RefNum) -> Get m (Value RefNum)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get m (BLit RefNum)
forall (m :: * -> *). PrimBase m => Get m (BLit RefNum)
getBLit
{-# INLINEABLE getValue #-}

putCont :: Cont RefNum -> Builder
putCont :: Cont RefNum -> Builder
putCont = \case
  Cont RefNum
KE -> CoTag -> Builder
forall t. Tag t => t -> Builder
putTag CoTag
KET
  Mark Word64
a [RefNum]
rs [(RefNum, Value RefNum)]
ds Cont RefNum
k ->
    CoTag -> Builder
forall t. Tag t => t -> Builder
putTag CoTag
MarkT
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word64 -> Builder
forall a.
(Integral a, Integral (Unsigned a), Bits (Unsigned a)) =>
a -> Builder
putVarInt Word64
a
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> (RefNum -> Builder) -> [RefNum] -> Builder
forall (f :: * -> *) a.
Foldable f =>
(a -> Builder) -> f a -> Builder
putFoldable RefNum -> Builder
putRefNum [RefNum]
rs
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> (RefNum -> Builder)
-> (Value RefNum -> Builder) -> [(RefNum, Value RefNum)] -> Builder
forall a b. (a -> Builder) -> (b -> Builder) -> [(a, b)] -> Builder
putMapping RefNum -> Builder
putRefNum Value RefNum -> Builder
putValue [(RefNum, Value RefNum)]
ds
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Cont RefNum -> Builder
putCont Cont RefNum
k
  Push Word64
f Word64
n GroupRef RefNum
gr Cont RefNum
k ->
    CoTag -> Builder
forall t. Tag t => t -> Builder
putTag CoTag
PushT
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word64 -> Builder
forall a.
(Integral a, Integral (Unsigned a), Bits (Unsigned a)) =>
a -> Builder
putVarInt Word64
f
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word64 -> Builder
forall a.
(Integral a, Integral (Unsigned a), Bits (Unsigned a)) =>
a -> Builder
putVarInt Word64
n
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> GroupRef RefNum -> Builder
putGroupRef GroupRef RefNum
gr
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Cont RefNum -> Builder
putCont Cont RefNum
k

getCont :: (PrimBase m) => Get m (Cont RefNum)
getCont :: forall (m :: * -> *). PrimBase m => Get m (Cont RefNum)
getCont =
  Get m CoTag
forall (m :: * -> *) t. (PrimBase m, Tag t) => Get m t
getTag Get m CoTag
-> (CoTag -> Get m (Cont RefNum)) -> Get m (Cont RefNum)
forall a b. Get m a -> (a -> Get m b) -> Get m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    CoTag
KET -> Cont RefNum -> Get m (Cont RefNum)
forall a. a -> Get m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Cont RefNum
forall ref. Cont ref
KE
    CoTag
MarkT ->
      Word64
-> [RefNum]
-> [(RefNum, Value RefNum)]
-> Cont RefNum
-> Cont RefNum
forall ref.
Word64 -> [ref] -> [(ref, Value ref)] -> Cont ref -> Cont ref
Mark
        (Word64
 -> [RefNum]
 -> [(RefNum, Value RefNum)]
 -> Cont RefNum
 -> Cont RefNum)
-> Get m Word64
-> Get
     m
     ([RefNum]
      -> [(RefNum, Value RefNum)] -> Cont RefNum -> Cont RefNum)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get m Word64
forall int (m :: * -> *).
(Bits int, Num int, Ord int, PrimBase m) =>
Get m int
getVarInt
        Get
  m
  ([RefNum]
   -> [(RefNum, Value RefNum)] -> Cont RefNum -> Cont RefNum)
-> Get m [RefNum]
-> Get m ([(RefNum, Value RefNum)] -> Cont RefNum -> Cont RefNum)
forall a b. Get m (a -> b) -> Get m a -> Get m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get m RefNum -> Get m [RefNum]
forall (m :: * -> *) a. PrimBase m => Get m a -> Get m [a]
getList Get m RefNum
forall (m :: * -> *). PrimBase m => Get m RefNum
getRefNum
        Get m ([(RefNum, Value RefNum)] -> Cont RefNum -> Cont RefNum)
-> Get m [(RefNum, Value RefNum)]
-> Get m (Cont RefNum -> Cont RefNum)
forall a b. Get m (a -> b) -> Get m a -> Get m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get m RefNum
-> Get m (Value RefNum) -> Get m [(RefNum, Value RefNum)]
forall (m :: * -> *) a b.
PrimBase m =>
Get m a -> Get m b -> Get m [(a, b)]
getMapping Get m RefNum
forall (m :: * -> *). PrimBase m => Get m RefNum
getRefNum Get m (Value RefNum)
forall (m :: * -> *). PrimBase m => Get m (Value RefNum)
getValue
        Get m (Cont RefNum -> Cont RefNum)
-> Get m (Cont RefNum) -> Get m (Cont RefNum)
forall a b. Get m (a -> b) -> Get m a -> Get m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get m (Cont RefNum)
forall (m :: * -> *). PrimBase m => Get m (Cont RefNum)
getCont
    CoTag
PushT ->
      Word64 -> Word64 -> GroupRef RefNum -> Cont RefNum -> Cont RefNum
forall ref.
Word64 -> Word64 -> GroupRef ref -> Cont ref -> Cont ref
Push
        (Word64 -> Word64 -> GroupRef RefNum -> Cont RefNum -> Cont RefNum)
-> Get m Word64
-> Get m (Word64 -> GroupRef RefNum -> Cont RefNum -> Cont RefNum)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get m Word64
forall int (m :: * -> *).
(Bits int, Num int, Ord int, PrimBase m) =>
Get m int
getVarInt
        Get m (Word64 -> GroupRef RefNum -> Cont RefNum -> Cont RefNum)
-> Get m Word64
-> Get m (GroupRef RefNum -> Cont RefNum -> Cont RefNum)
forall a b. Get m (a -> b) -> Get m a -> Get m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get m Word64
forall int (m :: * -> *).
(Bits int, Num int, Ord int, PrimBase m) =>
Get m int
getVarInt
        Get m (GroupRef RefNum -> Cont RefNum -> Cont RefNum)
-> Get m (GroupRef RefNum) -> Get m (Cont RefNum -> Cont RefNum)
forall a b. Get m (a -> b) -> Get m a -> Get m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get m (GroupRef RefNum)
forall (m :: * -> *). PrimBase m => Get m (GroupRef RefNum)
getGroupRef
        Get m (Cont RefNum -> Cont RefNum)
-> Get m (Cont RefNum) -> Get m (Cont RefNum)
forall a b. Get m (a -> b) -> Get m a -> Get m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get m (Cont RefNum)
forall (m :: * -> *). PrimBase m => Get m (Cont RefNum)
getCont
{-# INLINEABLE getCont #-}

putBLit :: BLit RefNum -> Builder
putBLit :: BLit RefNum -> Builder
putBLit = \case
  Text Text
t -> BLTag -> Builder
forall t. Tag t => t -> Builder
putTag BLTag
TextT Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Text -> Builder
putText (Text -> Text
Util.Text.toText Text
t)
  List Seq (Value RefNum)
s -> BLTag -> Builder
forall t. Tag t => t -> Builder
putTag BLTag
ListT Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> (Value RefNum -> Builder) -> Seq (Value RefNum) -> Builder
forall (f :: * -> *) a.
Foldable f =>
(a -> Builder) -> f a -> Builder
putFoldable Value RefNum -> Builder
putValue Seq (Value RefNum)
s
  TmLink Referent' RefNum
r -> BLTag -> Builder
forall t. Tag t => t -> Builder
putTag BLTag
TmLinkT Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Referent' RefNum -> Builder
putNumberedReferent Referent' RefNum
r
  TyLink RefNum
r -> BLTag -> Builder
forall t. Tag t => t -> Builder
putTag BLTag
TyLinkT Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> RefNum -> Builder
putRefNum RefNum
r
  Bytes Bytes
b -> BLTag -> Builder
forall t. Tag t => t -> Builder
putTag BLTag
BytesT Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Bytes -> Builder
putBytes Bytes
b
  Quote Value RefNum
vl -> BLTag -> Builder
forall t. Tag t => t -> Builder
putTag BLTag
QuoteT Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Value RefNum -> Builder
putValue Value RefNum
vl
  Code (CodeRep SuperGroup RefNum Symbol
sg Cacheability
ch) ->
    BLTag -> Builder
forall t. Tag t => t -> Builder
putTag BLTag
tag Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Bool -> SuperGroup RefNum Symbol -> Builder
forall v. Var v => Bool -> SuperGroup RefNum v -> Builder
putGroup Bool
False SuperGroup RefNum Symbol
sg
    where
      tag :: BLTag
tag
        | Cacheability
Cacheable <- Cacheability
ch = BLTag
CachedCodeT
        | Bool
otherwise = BLTag
CodeT
  BArr ByteArray
a -> BLTag -> Builder
forall t. Tag t => t -> Builder
putTag BLTag
BArrT Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> ByteArray -> Builder
putByteArray ByteArray
a
  Pos Word64
n -> BLTag -> Builder
forall t. Tag t => t -> Builder
putTag BLTag
PosT Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word64 -> Builder
forall n.
(Bits n, Bits (Unsigned n), Integral n, Integral (Unsigned n)) =>
n -> Builder
putPositive Word64
n
  Neg Word64
n -> BLTag -> Builder
forall t. Tag t => t -> Builder
putTag BLTag
NegT Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word64 -> Builder
forall n.
(Bits n, Bits (Unsigned n), Integral n, Integral (Unsigned n)) =>
n -> Builder
putPositive Word64
n
  Char Char
c -> BLTag -> Builder
forall t. Tag t => t -> Builder
putTag BLTag
CharT Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Char -> Builder
putChar Char
c
  Float Double
d -> BLTag -> Builder
forall t. Tag t => t -> Builder
putTag BLTag
FloatT Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Double -> Builder
putFloat Double
d
  Arr Array (Value RefNum)
a -> BLTag -> Builder
forall t. Tag t => t -> Builder
putTag BLTag
ArrT Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> (Value RefNum -> Builder) -> Array (Value RefNum) -> Builder
forall (f :: * -> *) a.
Foldable f =>
(a -> Builder) -> f a -> Builder
putFoldable Value RefNum -> Builder
putValue Array (Value RefNum)
a
  Map [(Value RefNum, Value RefNum)]
m ->
    BLTag -> Builder
forall t. Tag t => t -> Builder
putTag BLTag
MapT Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> (Value RefNum -> Builder)
-> (Value RefNum -> Builder)
-> [(Value RefNum, Value RefNum)]
-> Builder
forall a b. (a -> Builder) -> (b -> Builder) -> [(a, b)] -> Builder
putMapping Value RefNum -> Builder
putValue Value RefNum -> Builder
putValue [(Value RefNum, Value RefNum)]
m

getBLit :: (PrimBase m) => Get m (BLit RefNum)
getBLit :: forall (m :: * -> *). PrimBase m => Get m (BLit RefNum)
getBLit =
  Get m BLTag
forall (m :: * -> *) t. (PrimBase m, Tag t) => Get m t
getTag Get m BLTag
-> (BLTag -> Get m (BLit RefNum)) -> Get m (BLit RefNum)
forall a b. Get m a -> (a -> Get m b) -> Get m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    BLTag
TextT -> Text -> BLit RefNum
forall ref. Text -> BLit ref
Text (Text -> BLit RefNum) -> (Text -> Text) -> Text -> BLit RefNum
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
Util.Text.fromText (Text -> BLit RefNum) -> Get m Text -> Get m (BLit RefNum)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get m Text
forall (m :: * -> *). PrimBase m => Get m Text
getText
    BLTag
ListT -> Seq (Value RefNum) -> BLit RefNum
forall ref. Seq (Value ref) -> BLit ref
List (Seq (Value RefNum) -> BLit RefNum)
-> Get m (Seq (Value RefNum)) -> Get m (BLit RefNum)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get m (Value RefNum) -> Get m (Seq (Value RefNum))
forall (m :: * -> *) a. PrimBase m => Get m a -> Get m (Seq a)
getSeq Get m (Value RefNum)
forall (m :: * -> *). PrimBase m => Get m (Value RefNum)
getValue
    BLTag
TmLinkT -> Referent' RefNum -> BLit RefNum
forall ref. Referent' ref -> BLit ref
TmLink (Referent' RefNum -> BLit RefNum)
-> Get m (Referent' RefNum) -> Get m (BLit RefNum)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get m (Referent' RefNum)
forall (m :: * -> *). PrimBase m => Get m (Referent' RefNum)
getNumberedReferent
    BLTag
TyLinkT -> RefNum -> BLit RefNum
forall ref. ref -> BLit ref
TyLink (RefNum -> BLit RefNum) -> Get m RefNum -> Get m (BLit RefNum)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get m RefNum
forall (m :: * -> *). PrimBase m => Get m RefNum
getRefNum
    BLTag
BytesT -> Bytes -> BLit RefNum
forall ref. Bytes -> BLit ref
Bytes (Bytes -> BLit RefNum) -> Get m Bytes -> Get m (BLit RefNum)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get m Bytes
forall (m :: * -> *). PrimBase m => Get m Bytes
getBytes
    BLTag
QuoteT -> Value RefNum -> BLit RefNum
forall ref. Value ref -> BLit ref
Quote (Value RefNum -> BLit RefNum)
-> Get m (Value RefNum) -> Get m (BLit RefNum)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get m (Value RefNum)
forall (m :: * -> *). PrimBase m => Get m (Value RefNum)
getValue
    BLTag
CodeT ->
      Code RefNum -> BLit RefNum
forall ref. Code ref -> BLit ref
Code (Code RefNum -> BLit RefNum)
-> (SuperGroup RefNum Symbol -> Code RefNum)
-> SuperGroup RefNum Symbol
-> BLit RefNum
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SuperGroup RefNum Symbol -> Cacheability -> Code RefNum)
-> Cacheability -> SuperGroup RefNum Symbol -> Code RefNum
forall a b c. (a -> b -> c) -> b -> a -> c
flip SuperGroup RefNum Symbol -> Cacheability -> Code RefNum
forall ref. SuperGroup ref Symbol -> Cacheability -> Code ref
CodeRep Cacheability
Uncacheable (SuperGroup RefNum Symbol -> BLit RefNum)
-> Get m (SuperGroup RefNum Symbol) -> Get m (BLit RefNum)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get m (SuperGroup RefNum Symbol)
forall (m :: * -> *) v.
(PrimBase m, Var v) =>
Get m (SuperGroup RefNum v)
getGroup
    BLTag
BArrT -> ByteArray -> BLit RefNum
forall ref. ByteArray -> BLit ref
BArr (ByteArray -> BLit RefNum)
-> Get m ByteArray -> Get m (BLit RefNum)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get m ByteArray
forall (m :: * -> *). PrimBase m => Get m ByteArray
getByteArray
    BLTag
PosT -> Word64 -> BLit RefNum
forall ref. Word64 -> BLit ref
Pos (Word64 -> BLit RefNum) -> Get m Word64 -> Get m (BLit RefNum)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get m Word64
forall (m :: * -> *) n.
(Bounded n, Integral n, PrimBase m) =>
Get m n
getPositive
    BLTag
NegT -> Word64 -> BLit RefNum
forall ref. Word64 -> BLit ref
Neg (Word64 -> BLit RefNum) -> Get m Word64 -> Get m (BLit RefNum)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get m Word64
forall (m :: * -> *) n.
(Bounded n, Integral n, PrimBase m) =>
Get m n
getPositive
    BLTag
CharT -> Char -> BLit RefNum
forall ref. Char -> BLit ref
Char (Char -> BLit RefNum) -> Get m Char -> Get m (BLit RefNum)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get m Char
forall (m :: * -> *). PrimBase m => Get m Char
getChar
    BLTag
FloatT -> Double -> BLit RefNum
forall ref. Double -> BLit ref
Float (Double -> BLit RefNum) -> Get m Double -> Get m (BLit RefNum)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get m Double
forall (m :: * -> *). PrimBase m => Get m Double
getFloat
    BLTag
ArrT -> Array (Value RefNum) -> BLit RefNum
forall ref. Array (Value ref) -> BLit ref
Arr (Array (Value RefNum) -> BLit RefNum)
-> Get m (Array (Value RefNum)) -> Get m (BLit RefNum)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get m (Value RefNum) -> Get m (Array (Value RefNum))
forall (m :: * -> *) a. PrimBase m => Get m a -> Get m (Array a)
getArray Get m (Value RefNum)
forall (m :: * -> *). PrimBase m => Get m (Value RefNum)
getValue
    BLTag
CachedCodeT -> Code RefNum -> BLit RefNum
forall ref. Code ref -> BLit ref
Code (Code RefNum -> BLit RefNum)
-> (SuperGroup RefNum Symbol -> Code RefNum)
-> SuperGroup RefNum Symbol
-> BLit RefNum
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SuperGroup RefNum Symbol -> Cacheability -> Code RefNum)
-> Cacheability -> SuperGroup RefNum Symbol -> Code RefNum
forall a b c. (a -> b -> c) -> b -> a -> c
flip SuperGroup RefNum Symbol -> Cacheability -> Code RefNum
forall ref. SuperGroup ref Symbol -> Cacheability -> Code ref
CodeRep Cacheability
Cacheable (SuperGroup RefNum Symbol -> BLit RefNum)
-> Get m (SuperGroup RefNum Symbol) -> Get m (BLit RefNum)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get m (SuperGroup RefNum Symbol)
forall (m :: * -> *) v.
(PrimBase m, Var v) =>
Get m (SuperGroup RefNum v)
getGroup
    BLTag
MapT -> [(Value RefNum, Value RefNum)] -> BLit RefNum
forall ref. [(Value ref, Value ref)] -> BLit ref
Map ([(Value RefNum, Value RefNum)] -> BLit RefNum)
-> Get m [(Value RefNum, Value RefNum)] -> Get m (BLit RefNum)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get m (Value RefNum)
-> Get m (Value RefNum) -> Get m [(Value RefNum, Value RefNum)]
forall (m :: * -> *) a b.
PrimBase m =>
Get m a -> Get m b -> Get m [(a, b)]
getMapping Get m (Value RefNum)
forall (m :: * -> *). PrimBase m => Get m (Value RefNum)
getValue Get m (Value RefNum)
forall (m :: * -> *). PrimBase m => Get m (Value RefNum)
getValue
{-# INLINEABLE getBLit #-}

putValueWithHeader ::
  [Reference] -> [Reference] -> Value RefNum -> Builder
putValueWithHeader :: [Reference] -> [Reference] -> Value RefNum -> Builder
putValueWithHeader [Reference]
tyrs [Reference]
tmrs Value RefNum
v =
  (Reference -> Builder) -> [Reference] -> Builder
forall (f :: * -> *) a.
Foldable f =>
(a -> Builder) -> f a -> Builder
putFoldable Reference -> Builder
SER.putReference [Reference]
tyrs
    Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> (Reference -> Builder) -> [Reference] -> Builder
forall (f :: * -> *) a.
Foldable f =>
(a -> Builder) -> f a -> Builder
putFoldable Reference -> Builder
SER.putReference [Reference]
tmrs
    Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Value RefNum -> Builder
putValue Value RefNum
v

putVersionedValue ::
  [Reference] -> [Reference] -> Value RefNum -> Builder
putVersionedValue :: [Reference] -> [Reference] -> Value RefNum -> Builder
putVersionedValue [Reference]
tyrs [Reference]
tmrs Value RefNum
v =
  Word32 -> Builder
BU.word32BE Word32
5 Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> [Reference] -> [Reference] -> Value RefNum -> Builder
putValueWithHeader [Reference]
tyrs [Reference]
tmrs Value RefNum
v

versionedValueBytes ::
  [Reference] -> [Reference] -> Value RefNum -> L.ByteString
versionedValueBytes :: [Reference] -> [Reference] -> Value RefNum -> ByteString
versionedValueBytes [Reference]
tyrs [Reference]
tmrs Value RefNum
v =
  Builder -> ByteString
BU.toLazyByteString (Builder -> ByteString) -> Builder -> ByteString
forall a b. (a -> b) -> a -> b
$ [Reference] -> [Reference] -> Value RefNum -> Builder
putVersionedValue [Reference]
tyrs [Reference]
tmrs Value RefNum
v

getValueWithHeader :: (PrimBase m) => Get m (Referenced Value)
getValueWithHeader :: forall (m :: * -> *). PrimBase m => Get m (Referenced Value)
getValueWithHeader = do
  Int
tyl <- Get m Int
forall (m :: * -> *) n.
(PrimBase m, Integral n, Integral (Unsigned n), Bits n,
 Bits (Unsigned n)) =>
Get m n
getLength
  [Reference]
tys <- Int -> Get m Reference -> Get m [Reference]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
tyl Get m Reference
forall (m :: * -> *). PrimBase m => Get m Reference
SER.getReference
  Int
tml <- Get m Int
forall (m :: * -> *) n.
(PrimBase m, Integral n, Integral (Unsigned n), Bits n,
 Bits (Unsigned n)) =>
Get m n
getLength
  [Reference]
tms <- Int -> Get m Reference -> Get m [Reference]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
tml Get m Reference
forall (m :: * -> *). PrimBase m => Get m Reference
SER.getReference
  Value RefNum
v <- Get m (Value RefNum)
forall (m :: * -> *). PrimBase m => Get m (Value RefNum)
getValue
  pure ([Reference] -> [Reference] -> Value RefNum -> Referenced Value
forall (t :: * -> *).
[Reference] -> [Reference] -> t RefNum -> Referenced t
WithRefs [Reference]
tys [Reference]
tms Value RefNum
v)
{-# INLINEABLE getValueWithHeader #-}