{-# LANGUAGE TupleSections #-}
{-# LANGUAGE ForeignFunctionInterface #-}

module GHCi.StaticPtrTable ( sptAddEntry ) where

import Prelude -- See note [Why do we import Prelude here?]
import Data.Word
import Foreign
import GHC.Fingerprint
import GHCi.RemoteTypes

-- | Used by GHCi to add an SPT entry for a set of interactive bindings.
sptAddEntry :: Fingerprint -> HValue -> IO ()
sptAddEntry :: Fingerprint -> HValue -> IO ()
sptAddEntry (Fingerprint a :: Word64
a b :: Word64
b) (HValue x :: Any
x) = do
    -- We own the memory holding the key (fingerprint) which gets inserted into
    -- the static pointer table and can't free it until the SPT entry is removed
    -- (which is currently never).
    Ptr Word64
fpr_ptr <- [Word64] -> IO (Ptr Word64)
forall a. Storable a => [a] -> IO (Ptr a)
newArray [Word64
a,Word64
b]
    StablePtr Any
sptr <- Any -> IO (StablePtr Any)
forall a. a -> IO (StablePtr a)
newStablePtr Any
x
    Ptr (Ptr ())
ent_ptr <- IO (Ptr (Ptr ()))
forall a. Storable a => IO (Ptr a)
malloc
    Ptr (Ptr ()) -> Ptr () -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr (Ptr ())
ent_ptr (StablePtr Any -> Ptr ()
forall a. StablePtr a -> Ptr ()
castStablePtrToPtr StablePtr Any
sptr)
    Ptr Word64 -> Ptr (Ptr ()) -> IO ()
spt_insert_stableptr Ptr Word64
fpr_ptr Ptr (Ptr ())
ent_ptr

foreign import ccall "hs_spt_insert_stableptr"
    spt_insert_stableptr :: Ptr Word64 -> Ptr (Ptr ()) -> IO ()