{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
{-# OPTIONS_HADDOCK not-home #-}
module Effectful.Internal.Env
(
Env(..)
, Ref(..)
, Version
, Storage(..)
, StorageData(..)
, copyStorageData
, restoreStorageData
, AnyRelinker
, toAnyRelinker
, fromAnyRelinker
, AnyEffect
, toAnyEffect
, fromAnyEffect
, Relinker(..)
, dummyRelinker
, Dispatch(..)
, SideEffects(..)
, DispatchOf
, EffectRep
, emptyEnv
, cloneEnv
, sizeEnv
, tailEnv
, consEnv
, unconsEnv
, replaceEnv
, unreplaceEnv
, subsumeEnv
, injectEnv
, getEnv
, putEnv
, stateEnv
, modifyEnv
) where
import Control.Monad
import Control.Monad.Primitive
import Data.IORef.Strict
import Data.Primitive.PrimArray
import Data.Primitive.SmallArray
import Data.Primitive.Types
import GHC.Exts ((*#), (+#))
import GHC.Stack
import Effectful.Internal.Effect
import Effectful.Internal.Utils
type role Env nominal
data Env (es :: [Effect]) = Env
{ forall (es :: [Effect]). Env es -> Int
envOffset :: !Int
, forall (es :: [Effect]). Env es -> PrimArray Ref
envRefs :: !(PrimArray Ref)
, forall (es :: [Effect]). Env es -> IORef' Storage
envStorage :: !(IORef' Storage)
}
data Ref = Ref !Int !Version
instance Prim Ref where
sizeOf# :: Ref -> Int#
sizeOf# Ref
_ = Int#
2# Int# -> Int# -> Int#
*# Int -> Int#
forall a. Prim a => a -> Int#
sizeOf# (Int
forall a. HasCallStack => a
undefined :: Int)
alignment# :: Ref -> Int#
alignment# Ref
_ = Int -> Int#
forall a. Prim a => a -> Int#
alignment# (Int
forall a. HasCallStack => a
undefined :: Int)
indexByteArray# :: ByteArray# -> Int# -> Ref
indexByteArray# ByteArray#
arr Int#
i =
let n :: Int#
n = Int#
2# Int# -> Int# -> Int#
*# Int#
i
ref :: Int
ref = ByteArray# -> Int# -> Int
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
arr Int#
n
version :: Version
version = ByteArray# -> Int# -> Version
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
arr (Int#
n Int# -> Int# -> Int#
+# Int#
1#)
in Int -> Version -> Ref
Ref Int
ref Version
version
readByteArray# :: forall s.
MutableByteArray# s -> Int# -> State# s -> (# State# s, Ref #)
readByteArray# MutableByteArray# s
arr Int#
i State# s
s0 =
let n :: Int#
n = Int#
2# Int# -> Int# -> Int#
*# Int#
i
!(# State# s
s1, Int
ref #) = MutableByteArray# s -> Int# -> State# s -> (# State# s, Int #)
forall s.
MutableByteArray# s -> Int# -> State# s -> (# State# s, Int #)
forall a s.
Prim a =>
MutableByteArray# s -> Int# -> State# s -> (# State# s, a #)
readByteArray# MutableByteArray# s
arr Int#
n State# s
s0
!(# State# s
s2, Version
version #) = MutableByteArray# s -> Int# -> State# s -> (# State# s, Version #)
forall s.
MutableByteArray# s -> Int# -> State# s -> (# State# s, Version #)
forall a s.
Prim a =>
MutableByteArray# s -> Int# -> State# s -> (# State# s, a #)
readByteArray# MutableByteArray# s
arr (Int#
n Int# -> Int# -> Int#
+# Int#
1#) State# s
s1
in (# State# s
s2, Int -> Version -> Ref
Ref Int
ref Version
version #)
writeByteArray# :: forall s.
MutableByteArray# s -> Int# -> Ref -> State# s -> State# s
writeByteArray# MutableByteArray# s
arr Int#
i (Ref Int
ref Version
version) State# s
s0 =
let n :: Int#
n = Int#
2# Int# -> Int# -> Int#
*# Int#
i
s1 :: State# s
s1 = MutableByteArray# s -> Int# -> Int -> State# s -> State# s
forall s.
MutableByteArray# s -> Int# -> Int -> State# s -> State# s
forall a s.
Prim a =>
MutableByteArray# s -> Int# -> a -> State# s -> State# s
writeByteArray# MutableByteArray# s
arr Int#
n Int
ref State# s
s0
s2 :: State# s
s2 = MutableByteArray# s -> Int# -> Version -> State# s -> State# s
forall s.
MutableByteArray# s -> Int# -> Version -> State# s -> State# s
forall a s.
Prim a =>
MutableByteArray# s -> Int# -> a -> State# s -> State# s
writeByteArray# MutableByteArray# s
arr (Int#
n Int# -> Int# -> Int#
+# Int#
1#) Version
version State# s
s1
in State# s
s2
setByteArray# :: forall s.
MutableByteArray# s -> Int# -> Int# -> Ref -> State# s -> State# s
setByteArray# = MutableByteArray# s -> Int# -> Int# -> Ref -> State# s -> State# s
forall a s.
Prim a =>
MutableByteArray# s -> Int# -> Int# -> a -> State# s -> State# s
defaultSetByteArray#
indexOffAddr# :: Addr# -> Int# -> Ref
indexOffAddr# Addr#
addr Int#
i =
let n :: Int#
n = Int#
2# Int# -> Int# -> Int#
*# Int#
i
ref :: Int
ref = Addr# -> Int# -> Int
forall a. Prim a => Addr# -> Int# -> a
indexOffAddr# Addr#
addr Int#
n
version :: Version
version = Addr# -> Int# -> Version
forall a. Prim a => Addr# -> Int# -> a
indexOffAddr# Addr#
addr (Int#
n Int# -> Int# -> Int#
+# Int#
1#)
in Int -> Version -> Ref
Ref Int
ref Version
version
readOffAddr# :: forall s. Addr# -> Int# -> State# s -> (# State# s, Ref #)
readOffAddr# Addr#
addr Int#
i State# s
s0 =
let n :: Int#
n = Int#
2# Int# -> Int# -> Int#
*# Int#
i
!(# State# s
s1, Int
ref #) = Addr# -> Int# -> State# s -> (# State# s, Int #)
forall s. Addr# -> Int# -> State# s -> (# State# s, Int #)
forall a s.
Prim a =>
Addr# -> Int# -> State# s -> (# State# s, a #)
readOffAddr# Addr#
addr Int#
n State# s
s0
!(# State# s
s2, Version
version #) = Addr# -> Int# -> State# s -> (# State# s, Version #)
forall s. Addr# -> Int# -> State# s -> (# State# s, Version #)
forall a s.
Prim a =>
Addr# -> Int# -> State# s -> (# State# s, a #)
readOffAddr# Addr#
addr (Int#
n Int# -> Int# -> Int#
+# Int#
1#) State# s
s1
in (# State# s
s2, Int -> Version -> Ref
Ref Int
ref Version
version #)
writeOffAddr# :: forall s. Addr# -> Int# -> Ref -> State# s -> State# s
writeOffAddr# Addr#
addr Int#
i (Ref Int
ref Version
version) State# s
s0 =
let n :: Int#
n = Int#
2# Int# -> Int# -> Int#
*# Int#
i
s1 :: State# s
s1 = Addr# -> Int# -> Int -> State# s -> State# s
forall s. Addr# -> Int# -> Int -> State# s -> State# s
forall a s. Prim a => Addr# -> Int# -> a -> State# s -> State# s
writeOffAddr# Addr#
addr Int#
n Int
ref State# s
s0
s2 :: State# s
s2 = Addr# -> Int# -> Version -> State# s -> State# s
forall s. Addr# -> Int# -> Version -> State# s -> State# s
forall a s. Prim a => Addr# -> Int# -> a -> State# s -> State# s
writeOffAddr# Addr#
addr (Int#
n Int# -> Int# -> Int#
+# Int#
1#) Version
version State# s
s1
in State# s
s2
setOffAddr# :: forall s. Addr# -> Int# -> Int# -> Ref -> State# s -> State# s
setOffAddr# = Addr# -> Int# -> Int# -> Ref -> State# s -> State# s
forall a s.
Prim a =>
Addr# -> Int# -> Int# -> a -> State# s -> State# s
defaultSetOffAddr#
newtype Version = Version Int
deriving newtype (Version -> Version -> Bool
(Version -> Version -> Bool)
-> (Version -> Version -> Bool) -> Eq Version
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Version -> Version -> Bool
== :: Version -> Version -> Bool
$c/= :: Version -> Version -> Bool
/= :: Version -> Version -> Bool
Eq, Eq Version
Eq Version =>
(Version -> Version -> Ordering)
-> (Version -> Version -> Bool)
-> (Version -> Version -> Bool)
-> (Version -> Version -> Bool)
-> (Version -> Version -> Bool)
-> (Version -> Version -> Version)
-> (Version -> Version -> Version)
-> Ord Version
Version -> Version -> Bool
Version -> Version -> Ordering
Version -> Version -> Version
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 :: Version -> Version -> Ordering
compare :: Version -> Version -> Ordering
$c< :: Version -> Version -> Bool
< :: Version -> Version -> Bool
$c<= :: Version -> Version -> Bool
<= :: Version -> Version -> Bool
$c> :: Version -> Version -> Bool
> :: Version -> Version -> Bool
$c>= :: Version -> Version -> Bool
>= :: Version -> Version -> Bool
$cmax :: Version -> Version -> Version
max :: Version -> Version -> Version
$cmin :: Version -> Version -> Version
min :: Version -> Version -> Version
Ord, Addr# -> Int# -> Version
ByteArray# -> Int# -> Version
Proxy Version -> Int#
Version -> Int#
(Proxy Version -> Int#)
-> (Version -> Int#)
-> (Proxy Version -> Int#)
-> (Version -> Int#)
-> (ByteArray# -> Int# -> Version)
-> (forall s.
MutableByteArray# s -> Int# -> State# s -> (# State# s, Version #))
-> (forall s.
MutableByteArray# s -> Int# -> Version -> State# s -> State# s)
-> (forall s.
MutableByteArray# s
-> Int# -> Int# -> Version -> State# s -> State# s)
-> (Addr# -> Int# -> Version)
-> (forall s. Addr# -> Int# -> State# s -> (# State# s, Version #))
-> (forall s. Addr# -> Int# -> Version -> State# s -> State# s)
-> (forall s.
Addr# -> Int# -> Int# -> Version -> State# s -> State# s)
-> Prim Version
forall s. Addr# -> Int# -> Int# -> Version -> State# s -> State# s
forall s. Addr# -> Int# -> State# s -> (# State# s, Version #)
forall s. Addr# -> Int# -> Version -> State# s -> State# s
forall s.
MutableByteArray# s
-> Int# -> Int# -> Version -> State# s -> State# s
forall s.
MutableByteArray# s -> Int# -> State# s -> (# State# s, Version #)
forall s.
MutableByteArray# s -> Int# -> Version -> State# s -> State# s
forall a.
(Proxy a -> Int#)
-> (a -> Int#)
-> (Proxy a -> Int#)
-> (a -> Int#)
-> (ByteArray# -> Int# -> a)
-> (forall s.
MutableByteArray# s -> Int# -> State# s -> (# State# s, a #))
-> (forall s.
MutableByteArray# s -> Int# -> a -> State# s -> State# s)
-> (forall s.
MutableByteArray# s -> Int# -> Int# -> a -> State# s -> State# s)
-> (Addr# -> Int# -> a)
-> (forall s. Addr# -> Int# -> State# s -> (# State# s, a #))
-> (forall s. Addr# -> Int# -> a -> State# s -> State# s)
-> (forall s. Addr# -> Int# -> Int# -> a -> State# s -> State# s)
-> Prim a
$csizeOfType# :: Proxy Version -> Int#
sizeOfType# :: Proxy Version -> Int#
$csizeOf# :: Version -> Int#
sizeOf# :: Version -> Int#
$calignmentOfType# :: Proxy Version -> Int#
alignmentOfType# :: Proxy Version -> Int#
$calignment# :: Version -> Int#
alignment# :: Version -> Int#
$cindexByteArray# :: ByteArray# -> Int# -> Version
indexByteArray# :: ByteArray# -> Int# -> Version
$creadByteArray# :: forall s.
MutableByteArray# s -> Int# -> State# s -> (# State# s, Version #)
readByteArray# :: forall s.
MutableByteArray# s -> Int# -> State# s -> (# State# s, Version #)
$cwriteByteArray# :: forall s.
MutableByteArray# s -> Int# -> Version -> State# s -> State# s
writeByteArray# :: forall s.
MutableByteArray# s -> Int# -> Version -> State# s -> State# s
$csetByteArray# :: forall s.
MutableByteArray# s
-> Int# -> Int# -> Version -> State# s -> State# s
setByteArray# :: forall s.
MutableByteArray# s
-> Int# -> Int# -> Version -> State# s -> State# s
$cindexOffAddr# :: Addr# -> Int# -> Version
indexOffAddr# :: Addr# -> Int# -> Version
$creadOffAddr# :: forall s. Addr# -> Int# -> State# s -> (# State# s, Version #)
readOffAddr# :: forall s. Addr# -> Int# -> State# s -> (# State# s, Version #)
$cwriteOffAddr# :: forall s. Addr# -> Int# -> Version -> State# s -> State# s
writeOffAddr# :: forall s. Addr# -> Int# -> Version -> State# s -> State# s
$csetOffAddr# :: forall s. Addr# -> Int# -> Int# -> Version -> State# s -> State# s
setOffAddr# :: forall s. Addr# -> Int# -> Int# -> Version -> State# s -> State# s
Prim, Int -> Version -> ShowS
[Version] -> ShowS
Version -> String
(Int -> Version -> ShowS)
-> (Version -> String) -> ([Version] -> ShowS) -> Show Version
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Version -> ShowS
showsPrec :: Int -> Version -> ShowS
$cshow :: Version -> String
show :: Version -> String
$cshowList :: [Version] -> ShowS
showList :: [Version] -> ShowS
Show)
data Storage = Storage
{ Storage -> Version
stVersion :: !Version
, Storage -> StorageData
stData :: {-# UNPACK #-} !StorageData
}
newtype AnyEffect = AnyEffect Any
toAnyEffect :: EffectRep (DispatchOf e) e -> AnyEffect
toAnyEffect :: forall (e :: Effect). EffectRep (DispatchOf e) e -> AnyEffect
toAnyEffect = Any -> AnyEffect
AnyEffect (Any -> AnyEffect)
-> (EffectRep (DispatchOf e) e -> Any)
-> EffectRep (DispatchOf e) e
-> AnyEffect
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EffectRep (DispatchOf e) e -> Any
forall a. a -> Any
toAny
fromAnyEffect :: AnyEffect -> EffectRep (DispatchOf e) e
fromAnyEffect :: forall (e :: Effect). AnyEffect -> EffectRep (DispatchOf e) e
fromAnyEffect (AnyEffect Any
e) = Any -> EffectRep (DispatchOf e) e
forall a. Any -> a
fromAny Any
e
newtype AnyRelinker = AnyRelinker Any
toAnyRelinker :: Relinker (EffectRep (DispatchOf e)) e -> AnyRelinker
toAnyRelinker :: forall (e :: Effect).
Relinker (EffectRep (DispatchOf e)) e -> AnyRelinker
toAnyRelinker = Any -> AnyRelinker
AnyRelinker (Any -> AnyRelinker)
-> (Relinker (EffectRep (DispatchOf e)) e -> Any)
-> Relinker (EffectRep (DispatchOf e)) e
-> AnyRelinker
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Relinker (EffectRep (DispatchOf e)) e -> Any
forall a. a -> Any
toAny
fromAnyRelinker :: AnyRelinker -> Relinker (EffectRep (DispatchOf e)) e
fromAnyRelinker :: forall (e :: Effect).
AnyRelinker -> Relinker (EffectRep (DispatchOf e)) e
fromAnyRelinker (AnyRelinker Any
f) = Any -> Relinker (EffectRep (DispatchOf e)) e
forall a. Any -> a
fromAny Any
f
data StorageData = StorageData
{ StorageData -> Int
sdSize :: !Int
, StorageData -> MutablePrimArray RealWorld Version
sdVersions :: !(MutablePrimArray RealWorld Version)
, StorageData -> SmallMutableArray RealWorld AnyEffect
sdEffects :: !(SmallMutableArray RealWorld AnyEffect)
, StorageData -> SmallMutableArray RealWorld AnyRelinker
sdRelinkers :: !(SmallMutableArray RealWorld AnyRelinker)
}
copyStorageData :: HasCallStack => StorageData -> IO StorageData
copyStorageData :: HasCallStack => StorageData -> IO StorageData
copyStorageData (StorageData Int
storageSize MutablePrimArray RealWorld Version
vs0 SmallMutableArray RealWorld AnyEffect
es0 SmallMutableArray RealWorld AnyRelinker
fs0) = do
Int
vsSize <- MutablePrimArray (PrimState IO) Version -> IO Int
forall (m :: Type -> Type) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a -> m Int
getSizeofMutablePrimArray MutablePrimArray RealWorld Version
MutablePrimArray (PrimState IO) Version
vs0
Int
esSize <- SmallMutableArray (PrimState IO) AnyEffect -> IO Int
forall (m :: Type -> Type) a.
PrimMonad m =>
SmallMutableArray (PrimState m) a -> m Int
getSizeofSmallMutableArray SmallMutableArray RealWorld AnyEffect
SmallMutableArray (PrimState IO) AnyEffect
es0
Int
fsSize <- SmallMutableArray (PrimState IO) AnyRelinker -> IO Int
forall (m :: Type -> Type) a.
PrimMonad m =>
SmallMutableArray (PrimState m) a -> m Int
getSizeofSmallMutableArray SmallMutableArray RealWorld AnyRelinker
SmallMutableArray (PrimState IO) AnyRelinker
fs0
Bool -> IO () -> IO ()
forall (f :: Type -> Type). Applicative f => Bool -> f () -> f ()
when (Int
vsSize Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
esSize) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
String -> IO ()
forall a. HasCallStack => String -> a
error (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"vsSize (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
vsSize String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
") /= esSize (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
esSize String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
Bool -> IO () -> IO ()
forall (f :: Type -> Type). Applicative f => Bool -> f () -> f ()
when (Int
esSize Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
fsSize) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
String -> IO ()
forall a. HasCallStack => String -> a
error (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"esSize (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
esSize String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
") /= fsSize (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
fsSize String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
MutablePrimArray RealWorld Version
vs <- MutablePrimArray (PrimState IO) Version
-> Int -> Int -> IO (MutablePrimArray (PrimState IO) Version)
forall (m :: Type -> Type) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a
-> Int -> Int -> m (MutablePrimArray (PrimState m) a)
cloneMutablePrimArray MutablePrimArray RealWorld Version
MutablePrimArray (PrimState IO) Version
vs0 Int
0 Int
vsSize
SmallMutableArray RealWorld AnyEffect
es <- SmallMutableArray (PrimState IO) AnyEffect
-> Int -> Int -> IO (SmallMutableArray (PrimState IO) AnyEffect)
forall (m :: Type -> Type) a.
PrimMonad m =>
SmallMutableArray (PrimState m) a
-> Int -> Int -> m (SmallMutableArray (PrimState m) a)
cloneSmallMutableArray SmallMutableArray RealWorld AnyEffect
SmallMutableArray (PrimState IO) AnyEffect
es0 Int
0 Int
esSize
SmallMutableArray RealWorld AnyRelinker
fs <- SmallMutableArray (PrimState IO) AnyRelinker
-> Int -> Int -> IO (SmallMutableArray (PrimState IO) AnyRelinker)
forall (m :: Type -> Type) a.
PrimMonad m =>
SmallMutableArray (PrimState m) a
-> Int -> Int -> m (SmallMutableArray (PrimState m) a)
cloneSmallMutableArray SmallMutableArray RealWorld AnyRelinker
SmallMutableArray (PrimState IO) AnyRelinker
fs0 Int
0 Int
fsSize
StorageData -> IO StorageData
forall a. a -> IO a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (StorageData -> IO StorageData) -> StorageData -> IO StorageData
forall a b. (a -> b) -> a -> b
$ Int
-> MutablePrimArray RealWorld Version
-> SmallMutableArray RealWorld AnyEffect
-> SmallMutableArray RealWorld AnyRelinker
-> StorageData
StorageData Int
storageSize MutablePrimArray RealWorld Version
vs SmallMutableArray RealWorld AnyEffect
es SmallMutableArray RealWorld AnyRelinker
fs
restoreStorageData :: HasCallStack => StorageData -> Env es -> IO ()
restoreStorageData :: forall (es :: [Effect]).
HasCallStack =>
StorageData -> Env es -> IO ()
restoreStorageData StorageData
newStorageData Env es
env = do
IORef' Storage -> (Storage -> Storage) -> IO ()
forall a. IORef' a -> (a -> a) -> IO ()
modifyIORef' (Env es -> IORef' Storage
forall (es :: [Effect]). Env es -> IORef' Storage
envStorage Env es
env) ((Storage -> Storage) -> IO ()) -> (Storage -> Storage) -> IO ()
forall a b. (a -> b) -> a -> b
$ \(Storage Version
version StorageData
oldStorageData) ->
let oldSize :: Int
oldSize = StorageData -> Int
sdSize StorageData
oldStorageData
newSize :: Int
newSize = StorageData -> Int
sdSize StorageData
newStorageData
in if Int
newSize Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
oldSize
then String -> Storage
forall a. HasCallStack => String -> a
error (String -> Storage) -> String -> Storage
forall a b. (a -> b) -> a -> b
$ String
"newSize (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
newSize String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
") /= oldSize (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
oldSize String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
else Version -> StorageData -> Storage
Storage Version
version StorageData
newStorageData
newtype Relinker :: (Effect -> Type) -> Effect -> Type where
Relinker
:: (HasCallStack => (forall es. Env es -> IO (Env es)) -> rep e -> IO (rep e))
-> Relinker rep e
dummyRelinker :: Relinker rep e
dummyRelinker :: forall (rep :: Effect -> Type) (e :: Effect). Relinker rep e
dummyRelinker = (HasCallStack =>
(forall (es :: [Effect]). Env es -> IO (Env es))
-> rep e -> IO (rep e))
-> Relinker rep e
forall (rep :: Effect -> Type) (e :: Effect).
(HasCallStack =>
(forall (es :: [Effect]). Env es -> IO (Env es))
-> rep e -> IO (rep e))
-> Relinker rep e
Relinker ((HasCallStack =>
(forall (es :: [Effect]). Env es -> IO (Env es))
-> rep e -> IO (rep e))
-> Relinker rep e)
-> (HasCallStack =>
(forall (es :: [Effect]). Env es -> IO (Env es))
-> rep e -> IO (rep e))
-> Relinker rep e
forall a b. (a -> b) -> a -> b
$ \forall (es :: [Effect]). Env es -> IO (Env es)
_ -> rep e -> IO (rep e)
forall a. a -> IO a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure
data Dispatch = Dynamic | Static SideEffects
data SideEffects = NoSideEffects | WithSideEffects
type family DispatchOf (e :: Effect) :: Dispatch
type family EffectRep (d :: Dispatch) :: Effect -> Type
emptyEnv :: HasCallStack => IO (Env '[])
emptyEnv :: HasCallStack => IO (Env '[])
emptyEnv = Int -> PrimArray Ref -> IORef' Storage -> Env '[]
forall (es :: [Effect]).
Int -> PrimArray Ref -> IORef' Storage -> Env es
Env Int
0
(PrimArray Ref -> IORef' Storage -> Env '[])
-> IO (PrimArray Ref) -> IO (IORef' Storage -> Env '[])
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> (MutablePrimArray RealWorld Ref -> IO (PrimArray Ref)
MutablePrimArray (PrimState IO) Ref -> IO (PrimArray Ref)
forall (m :: Type -> Type) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray (MutablePrimArray RealWorld Ref -> IO (PrimArray Ref))
-> IO (MutablePrimArray RealWorld Ref) -> IO (PrimArray Ref)
forall (m :: Type -> Type) a b. Monad m => (a -> m b) -> m a -> m b
=<< Int -> IO (MutablePrimArray (PrimState IO) Ref)
forall (m :: Type -> Type) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray Int
0)
IO (IORef' Storage -> Env '[])
-> IO (IORef' Storage) -> IO (Env '[])
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> (Storage -> IO (IORef' Storage)
forall a. a -> IO (IORef' a)
newIORef' (Storage -> IO (IORef' Storage))
-> IO Storage -> IO (IORef' Storage)
forall (m :: Type -> Type) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO Storage
HasCallStack => IO Storage
emptyStorage)
cloneEnv :: HasCallStack => Env es -> IO (Env es)
cloneEnv :: forall (es :: [Effect]). HasCallStack => Env es -> IO (Env es)
cloneEnv (Env Int
offset PrimArray Ref
refs IORef' Storage
storage0) = do
Storage Version
version StorageData
storageData0 <- IORef' Storage -> IO Storage
forall a. IORef' a -> IO a
readIORef' IORef' Storage
storage0
storageData :: StorageData
storageData@(StorageData Int
storageSize MutablePrimArray RealWorld Version
_ SmallMutableArray RealWorld AnyEffect
es SmallMutableArray RealWorld AnyRelinker
fs) <- HasCallStack => StorageData -> IO StorageData
StorageData -> IO StorageData
copyStorageData StorageData
storageData0
IORef' Storage
storage <- Storage -> IO (IORef' Storage)
forall a. a -> IO (IORef' a)
newIORef' (Storage -> IO (IORef' Storage)) -> Storage -> IO (IORef' Storage)
forall a b. (a -> b) -> a -> b
$ Version -> StorageData -> Storage
Storage Version
version StorageData
storageData
let relinkEffects :: Int -> IO ()
relinkEffects = \case
Int
0 -> () -> IO ()
forall a. a -> IO a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure ()
Int
k -> do
let i :: Int
i = Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
Relinker HasCallStack =>
(forall (es :: [Effect]). Env es -> IO (Env es))
-> EffectRep (DispatchOf Any) Any
-> IO (EffectRep (DispatchOf Any) Any)
relinker <- AnyRelinker -> Relinker (EffectRep (DispatchOf Any)) Any
forall (e :: Effect).
AnyRelinker -> Relinker (EffectRep (DispatchOf e)) e
fromAnyRelinker (AnyRelinker -> Relinker (EffectRep (DispatchOf Any)) Any)
-> IO AnyRelinker -> IO (Relinker (EffectRep (DispatchOf Any)) Any)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> SmallMutableArray (PrimState IO) AnyRelinker
-> Int -> IO AnyRelinker
forall (m :: Type -> Type) a.
PrimMonad m =>
SmallMutableArray (PrimState m) a -> Int -> m a
readSmallArray SmallMutableArray RealWorld AnyRelinker
SmallMutableArray (PrimState IO) AnyRelinker
fs Int
i
SmallMutableArray (PrimState IO) AnyEffect -> Int -> IO AnyEffect
forall (m :: Type -> Type) a.
PrimMonad m =>
SmallMutableArray (PrimState m) a -> Int -> m a
readSmallArray SmallMutableArray RealWorld AnyEffect
SmallMutableArray (PrimState IO) AnyEffect
es Int
i
IO AnyEffect
-> (AnyEffect -> IO (EffectRep (DispatchOf Any) Any))
-> IO (EffectRep (DispatchOf Any) Any)
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= HasCallStack =>
(forall (es :: [Effect]). Env es -> IO (Env es))
-> EffectRep (DispatchOf Any) Any
-> IO (EffectRep (DispatchOf Any) Any)
(forall (es :: [Effect]). Env es -> IO (Env es))
-> EffectRep (DispatchOf Any) Any
-> IO (EffectRep (DispatchOf Any) Any)
relinker (IORef' Storage -> Env es -> IO (Env es)
forall (es :: [Effect]). IORef' Storage -> Env es -> IO (Env es)
relinkEnv IORef' Storage
storage) (EffectRep (DispatchOf Any) Any
-> IO (EffectRep (DispatchOf Any) Any))
-> (AnyEffect -> EffectRep (DispatchOf Any) Any)
-> AnyEffect
-> IO (EffectRep (DispatchOf Any) Any)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AnyEffect -> EffectRep (DispatchOf Any) Any
forall (e :: Effect). AnyEffect -> EffectRep (DispatchOf e) e
fromAnyEffect
IO (EffectRep (DispatchOf Any) Any)
-> (EffectRep (DispatchOf Any) Any -> IO ()) -> IO ()
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= SmallMutableArray RealWorld AnyEffect -> Int -> AnyEffect -> IO ()
forall a. SmallMutableArray RealWorld a -> Int -> a -> IO ()
writeSmallArray' SmallMutableArray RealWorld AnyEffect
es Int
i (AnyEffect -> IO ())
-> (EffectRep (DispatchOf Any) Any -> AnyEffect)
-> EffectRep (DispatchOf Any) Any
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EffectRep (DispatchOf Any) Any -> AnyEffect
forall (e :: Effect). EffectRep (DispatchOf e) e -> AnyEffect
toAnyEffect
Int -> IO ()
relinkEffects Int
i
Int -> IO ()
relinkEffects Int
storageSize
Env es -> IO (Env es)
forall a. a -> IO a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Env es -> IO (Env es)) -> Env es -> IO (Env es)
forall a b. (a -> b) -> a -> b
$ Int -> PrimArray Ref -> IORef' Storage -> Env es
forall (es :: [Effect]).
Int -> PrimArray Ref -> IORef' Storage -> Env es
Env Int
offset PrimArray Ref
refs IORef' Storage
storage
{-# NOINLINE cloneEnv #-}
sizeEnv :: Env es -> IO Int
sizeEnv :: forall (es :: [Effect]). Env es -> IO Int
sizeEnv (Env Int
offset PrimArray Ref
refs IORef' Storage
_) = do
Int -> IO Int
forall a. a -> IO a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Int -> IO Int) -> Int -> IO Int
forall a b. (a -> b) -> a -> b
$ PrimArray Ref -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray Ref
refs Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
offset
tailEnv :: Env (e : es) -> IO (Env es)
tailEnv :: forall (e :: Effect) (es :: [Effect]). Env (e : es) -> IO (Env es)
tailEnv (Env Int
offset PrimArray Ref
refs IORef' Storage
storage) = do
Env es -> IO (Env es)
forall a. a -> IO a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Env es -> IO (Env es)) -> Env es -> IO (Env es)
forall a b. (a -> b) -> a -> b
$ Int -> PrimArray Ref -> IORef' Storage -> Env es
forall (es :: [Effect]).
Int -> PrimArray Ref -> IORef' Storage -> Env es
Env (Int
offset Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) PrimArray Ref
refs IORef' Storage
storage
consEnv
:: HasCallStack
=> EffectRep (DispatchOf e) e
-> Relinker (EffectRep (DispatchOf e)) e
-> Env es
-> IO (Env (e : es))
consEnv :: forall (e :: Effect) (es :: [Effect]).
HasCallStack =>
EffectRep (DispatchOf e) e
-> Relinker (EffectRep (DispatchOf e)) e
-> Env es
-> IO (Env (e : es))
consEnv EffectRep (DispatchOf e) e
e Relinker (EffectRep (DispatchOf e)) e
f (Env Int
offset PrimArray Ref
refs0 IORef' Storage
storage) = do
let size :: Int
size = PrimArray Ref -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray Ref
refs0 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
offset
MutablePrimArray RealWorld Ref
mrefs <- Int -> IO (MutablePrimArray (PrimState IO) Ref)
forall (m :: Type -> Type) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray (Int
size Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
MutablePrimArray (PrimState IO) Ref
-> Int -> PrimArray Ref -> Int -> Int -> IO ()
forall (m :: Type -> Type) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a
-> Int -> PrimArray a -> Int -> Int -> m ()
copyPrimArray MutablePrimArray RealWorld Ref
MutablePrimArray (PrimState IO) Ref
mrefs Int
1 PrimArray Ref
refs0 Int
offset Int
size
Ref
ref <- IORef' Storage
-> EffectRep (DispatchOf e) e
-> Relinker (EffectRep (DispatchOf e)) e
-> IO Ref
forall (e :: Effect).
HasCallStack =>
IORef' Storage
-> EffectRep (DispatchOf e) e
-> Relinker (EffectRep (DispatchOf e)) e
-> IO Ref
insertEffect IORef' Storage
storage EffectRep (DispatchOf e) e
e Relinker (EffectRep (DispatchOf e)) e
f
MutablePrimArray (PrimState IO) Ref -> Int -> Ref -> IO ()
forall a (m :: Type -> Type).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray MutablePrimArray RealWorld Ref
MutablePrimArray (PrimState IO) Ref
mrefs Int
0 Ref
ref
PrimArray Ref
refs <- MutablePrimArray (PrimState IO) Ref -> IO (PrimArray Ref)
forall (m :: Type -> Type) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray RealWorld Ref
MutablePrimArray (PrimState IO) Ref
mrefs
Env (e : es) -> IO (Env (e : es))
forall a. a -> IO a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Env (e : es) -> IO (Env (e : es)))
-> Env (e : es) -> IO (Env (e : es))
forall a b. (a -> b) -> a -> b
$ Int -> PrimArray Ref -> IORef' Storage -> Env (e : es)
forall (es :: [Effect]).
Int -> PrimArray Ref -> IORef' Storage -> Env es
Env Int
0 PrimArray Ref
refs IORef' Storage
storage
{-# NOINLINE consEnv #-}
unconsEnv :: HasCallStack => Env (e : es) -> IO ()
unconsEnv :: forall (e :: Effect) (es :: [Effect]).
HasCallStack =>
Env (e : es) -> IO ()
unconsEnv (Env Int
_ PrimArray Ref
refs IORef' Storage
storage) = do
HasCallStack => IORef' Storage -> Ref -> IO ()
IORef' Storage -> Ref -> IO ()
deleteEffect IORef' Storage
storage (PrimArray Ref -> Int -> Ref
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray Ref
refs Int
0)
{-# NOINLINE unconsEnv #-}
replaceEnv
:: forall e es. (HasCallStack, e :> es)
=> EffectRep (DispatchOf e) e
-> Relinker (EffectRep (DispatchOf e)) e
-> Env es
-> IO (Env es)
replaceEnv :: forall (e :: Effect) (es :: [Effect]).
(HasCallStack, e :> es) =>
EffectRep (DispatchOf e) e
-> Relinker (EffectRep (DispatchOf e)) e -> Env es -> IO (Env es)
replaceEnv EffectRep (DispatchOf e) e
e Relinker (EffectRep (DispatchOf e)) e
f (Env Int
offset PrimArray Ref
refs0 IORef' Storage
storage) = do
let size :: Int
size = PrimArray Ref -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray Ref
refs0 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
offset
MutablePrimArray RealWorld Ref
mrefs <- Int -> IO (MutablePrimArray (PrimState IO) Ref)
forall (m :: Type -> Type) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray Int
size
MutablePrimArray (PrimState IO) Ref
-> Int -> PrimArray Ref -> Int -> Int -> IO ()
forall (m :: Type -> Type) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a
-> Int -> PrimArray a -> Int -> Int -> m ()
copyPrimArray MutablePrimArray RealWorld Ref
MutablePrimArray (PrimState IO) Ref
mrefs Int
0 PrimArray Ref
refs0 Int
offset Int
size
Ref
ref <- IORef' Storage
-> EffectRep (DispatchOf e) e
-> Relinker (EffectRep (DispatchOf e)) e
-> IO Ref
forall (e :: Effect).
HasCallStack =>
IORef' Storage
-> EffectRep (DispatchOf e) e
-> Relinker (EffectRep (DispatchOf e)) e
-> IO Ref
insertEffect IORef' Storage
storage EffectRep (DispatchOf e) e
e Relinker (EffectRep (DispatchOf e)) e
f
MutablePrimArray (PrimState IO) Ref -> Int -> Ref -> IO ()
forall a (m :: Type -> Type).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray MutablePrimArray RealWorld Ref
MutablePrimArray (PrimState IO) Ref
mrefs (forall (e :: Effect) (es :: [Effect]). (e :> es) => Int
reifyIndex @e @es) Ref
ref
PrimArray Ref
refs <- MutablePrimArray (PrimState IO) Ref -> IO (PrimArray Ref)
forall (m :: Type -> Type) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray RealWorld Ref
MutablePrimArray (PrimState IO) Ref
mrefs
Env es -> IO (Env es)
forall a. a -> IO a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Env es -> IO (Env es)) -> Env es -> IO (Env es)
forall a b. (a -> b) -> a -> b
$ Int -> PrimArray Ref -> IORef' Storage -> Env es
forall (es :: [Effect]).
Int -> PrimArray Ref -> IORef' Storage -> Env es
Env Int
0 PrimArray Ref
refs IORef' Storage
storage
{-# NOINLINE replaceEnv #-}
unreplaceEnv :: forall e es. (HasCallStack, e :> es) => Env es -> IO ()
unreplaceEnv :: forall (e :: Effect) (es :: [Effect]).
(HasCallStack, e :> es) =>
Env es -> IO ()
unreplaceEnv (Env Int
offset PrimArray Ref
refs IORef' Storage
storage) = do
HasCallStack => IORef' Storage -> Ref -> IO ()
IORef' Storage -> Ref -> IO ()
deleteEffect IORef' Storage
storage (Ref -> IO ()) -> Ref -> IO ()
forall a b. (a -> b) -> a -> b
$ PrimArray Ref -> Int -> Ref
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray Ref
refs (Int
offset Int -> Int -> Int
forall a. Num a => a -> a -> a
+ forall (e :: Effect) (es :: [Effect]). (e :> es) => Int
reifyIndex @e @es)
{-# NOINLINE unreplaceEnv #-}
subsumeEnv :: forall e es. e :> es => Env es -> IO (Env (e : es))
subsumeEnv :: forall (e :: Effect) (es :: [Effect]).
(e :> es) =>
Env es -> IO (Env (e : es))
subsumeEnv (Env Int
offset PrimArray Ref
refs0 IORef' Storage
storage) = do
let size :: Int
size = PrimArray Ref -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray Ref
refs0 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
offset
MutablePrimArray RealWorld Ref
mrefs <- Int -> IO (MutablePrimArray (PrimState IO) Ref)
forall (m :: Type -> Type) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray (Int
size Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
MutablePrimArray (PrimState IO) Ref
-> Int -> PrimArray Ref -> Int -> Int -> IO ()
forall (m :: Type -> Type) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a
-> Int -> PrimArray a -> Int -> Int -> m ()
copyPrimArray MutablePrimArray RealWorld Ref
MutablePrimArray (PrimState IO) Ref
mrefs Int
1 PrimArray Ref
refs0 Int
offset Int
size
MutablePrimArray (PrimState IO) Ref -> Int -> Ref -> IO ()
forall a (m :: Type -> Type).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray MutablePrimArray RealWorld Ref
MutablePrimArray (PrimState IO) Ref
mrefs Int
0 (Ref -> IO ()) -> Ref -> IO ()
forall a b. (a -> b) -> a -> b
$ PrimArray Ref -> Int -> Ref
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray Ref
refs0 (Int
offset Int -> Int -> Int
forall a. Num a => a -> a -> a
+ forall (e :: Effect) (es :: [Effect]). (e :> es) => Int
reifyIndex @e @es)
PrimArray Ref
refs <- MutablePrimArray (PrimState IO) Ref -> IO (PrimArray Ref)
forall (m :: Type -> Type) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray RealWorld Ref
MutablePrimArray (PrimState IO) Ref
mrefs
Env (e : es) -> IO (Env (e : es))
forall a. a -> IO a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Env (e : es) -> IO (Env (e : es)))
-> Env (e : es) -> IO (Env (e : es))
forall a b. (a -> b) -> a -> b
$ Int -> PrimArray Ref -> IORef' Storage -> Env (e : es)
forall (es :: [Effect]).
Int -> PrimArray Ref -> IORef' Storage -> Env es
Env Int
0 PrimArray Ref
refs IORef' Storage
storage
{-# NOINLINE subsumeEnv #-}
injectEnv :: forall subEs es. Subset subEs es => Env es -> IO (Env subEs)
injectEnv :: forall (subEs :: [Effect]) (es :: [Effect]).
Subset subEs es =>
Env es -> IO (Env subEs)
injectEnv (Env Int
offset PrimArray Ref
refs0 IORef' Storage
storage) = do
let subEs :: [Int]
subEs = forall (subEs :: [Effect]) (es :: [Effect]).
Subset subEs es =>
[Int]
reifyIndices @subEs @es
subEsSize :: Int
subEsSize = [Int] -> Int
forall a. [a] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [Int]
subEs
prefixSize :: Int
prefixSize = forall (es :: [Effect]). KnownPrefix es => Int
prefixLength @es
suffixSize :: Int
suffixSize = if forall (subEs :: [Effect]) (es :: [Effect]).
Subset subEs es =>
Bool
subsetFullyKnown @subEs @es
then Int
0
else PrimArray Ref -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray Ref
refs0 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
offset Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
prefixSize
MutablePrimArray RealWorld Ref
mrefs <- Int -> IO (MutablePrimArray (PrimState IO) Ref)
forall (m :: Type -> Type) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray (Int
subEsSize Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
suffixSize)
MutablePrimArray (PrimState IO) Ref
-> Int -> PrimArray Ref -> Int -> Int -> IO ()
forall (m :: Type -> Type) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a
-> Int -> PrimArray a -> Int -> Int -> m ()
copyPrimArray MutablePrimArray RealWorld Ref
MutablePrimArray (PrimState IO) Ref
mrefs Int
subEsSize PrimArray Ref
refs0 (Int
offset Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
prefixSize) Int
suffixSize
let writeRefs :: Int -> [Int] -> IO ()
writeRefs Int
i = \case
[] -> () -> IO ()
forall a. a -> IO a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure ()
(Int
x : [Int]
xs) -> do
MutablePrimArray (PrimState IO) Ref -> Int -> Ref -> IO ()
forall a (m :: Type -> Type).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray MutablePrimArray RealWorld Ref
MutablePrimArray (PrimState IO) Ref
mrefs Int
i (Ref -> IO ()) -> Ref -> IO ()
forall a b. (a -> b) -> a -> b
$ PrimArray Ref -> Int -> Ref
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray Ref
refs0 (Int
offset Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
x)
Int -> [Int] -> IO ()
writeRefs (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) [Int]
xs
Int -> [Int] -> IO ()
writeRefs Int
0 [Int]
subEs
PrimArray Ref
refs <- MutablePrimArray (PrimState IO) Ref -> IO (PrimArray Ref)
forall (m :: Type -> Type) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray RealWorld Ref
MutablePrimArray (PrimState IO) Ref
mrefs
Env subEs -> IO (Env subEs)
forall a. a -> IO a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Env subEs -> IO (Env subEs)) -> Env subEs -> IO (Env subEs)
forall a b. (a -> b) -> a -> b
$ Int -> PrimArray Ref -> IORef' Storage -> Env subEs
forall (es :: [Effect]).
Int -> PrimArray Ref -> IORef' Storage -> Env es
Env Int
0 PrimArray Ref
refs IORef' Storage
storage
{-# NOINLINE injectEnv #-}
getEnv
:: forall e es. (HasCallStack, e :> es)
=> Env es
-> IO (EffectRep (DispatchOf e) e)
getEnv :: forall (e :: Effect) (es :: [Effect]).
(HasCallStack, e :> es) =>
Env es -> IO (EffectRep (DispatchOf e) e)
getEnv Env es
env = do
(Int
i, SmallMutableArray RealWorld AnyEffect
es) <- forall (e :: Effect) (es :: [Effect]).
(HasCallStack, e :> es) =>
Env es -> IO (Int, SmallMutableArray RealWorld AnyEffect)
getLocation @e Env es
env
AnyEffect -> EffectRep (DispatchOf e) e
forall (e :: Effect). AnyEffect -> EffectRep (DispatchOf e) e
fromAnyEffect (AnyEffect -> EffectRep (DispatchOf e) e)
-> IO AnyEffect -> IO (EffectRep (DispatchOf e) e)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> SmallMutableArray (PrimState IO) AnyEffect -> Int -> IO AnyEffect
forall (m :: Type -> Type) a.
PrimMonad m =>
SmallMutableArray (PrimState m) a -> Int -> m a
readSmallArray SmallMutableArray RealWorld AnyEffect
SmallMutableArray (PrimState IO) AnyEffect
es Int
i
putEnv
:: forall e es. (HasCallStack, e :> es)
=> Env es
-> EffectRep (DispatchOf e) e
-> IO ()
putEnv :: forall (e :: Effect) (es :: [Effect]).
(HasCallStack, e :> es) =>
Env es -> EffectRep (DispatchOf e) e -> IO ()
putEnv Env es
env EffectRep (DispatchOf e) e
e = do
(Int
i, SmallMutableArray RealWorld AnyEffect
es) <- forall (e :: Effect) (es :: [Effect]).
(HasCallStack, e :> es) =>
Env es -> IO (Int, SmallMutableArray RealWorld AnyEffect)
getLocation @e Env es
env
SmallMutableArray RealWorld AnyEffect -> Int -> AnyEffect -> IO ()
forall a. SmallMutableArray RealWorld a -> Int -> a -> IO ()
writeSmallArray' SmallMutableArray RealWorld AnyEffect
es Int
i (EffectRep (DispatchOf e) e -> AnyEffect
forall (e :: Effect). EffectRep (DispatchOf e) e -> AnyEffect
toAnyEffect EffectRep (DispatchOf e) e
e)
stateEnv
:: forall e es a. (HasCallStack, e :> es)
=> Env es
-> (EffectRep (DispatchOf e) e -> (a, EffectRep (DispatchOf e) e))
-> IO a
stateEnv :: forall (e :: Effect) (es :: [Effect]) a.
(HasCallStack, e :> es) =>
Env es
-> (EffectRep (DispatchOf e) e -> (a, EffectRep (DispatchOf e) e))
-> IO a
stateEnv Env es
env EffectRep (DispatchOf e) e -> (a, EffectRep (DispatchOf e) e)
f = do
(Int
i, SmallMutableArray RealWorld AnyEffect
es) <- forall (e :: Effect) (es :: [Effect]).
(HasCallStack, e :> es) =>
Env es -> IO (Int, SmallMutableArray RealWorld AnyEffect)
getLocation @e Env es
env
(a
a, EffectRep (DispatchOf e) e
e) <- EffectRep (DispatchOf e) e -> (a, EffectRep (DispatchOf e) e)
f (EffectRep (DispatchOf e) e -> (a, EffectRep (DispatchOf e) e))
-> (AnyEffect -> EffectRep (DispatchOf e) e)
-> AnyEffect
-> (a, EffectRep (DispatchOf e) e)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AnyEffect -> EffectRep (DispatchOf e) e
forall (e :: Effect). AnyEffect -> EffectRep (DispatchOf e) e
fromAnyEffect (AnyEffect -> (a, EffectRep (DispatchOf e) e))
-> IO AnyEffect -> IO (a, EffectRep (DispatchOf e) e)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> SmallMutableArray (PrimState IO) AnyEffect -> Int -> IO AnyEffect
forall (m :: Type -> Type) a.
PrimMonad m =>
SmallMutableArray (PrimState m) a -> Int -> m a
readSmallArray SmallMutableArray RealWorld AnyEffect
SmallMutableArray (PrimState IO) AnyEffect
es Int
i
SmallMutableArray RealWorld AnyEffect -> Int -> AnyEffect -> IO ()
forall a. SmallMutableArray RealWorld a -> Int -> a -> IO ()
writeSmallArray' SmallMutableArray RealWorld AnyEffect
es Int
i (EffectRep (DispatchOf e) e -> AnyEffect
forall (e :: Effect). EffectRep (DispatchOf e) e -> AnyEffect
toAnyEffect EffectRep (DispatchOf e) e
e)
a -> IO a
forall a. a -> IO a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure a
a
modifyEnv
:: forall e es. (HasCallStack, e :> es)
=> Env es
-> (EffectRep (DispatchOf e) e -> (EffectRep (DispatchOf e) e))
-> IO ()
modifyEnv :: forall (e :: Effect) (es :: [Effect]).
(HasCallStack, e :> es) =>
Env es
-> (EffectRep (DispatchOf e) e -> EffectRep (DispatchOf e) e)
-> IO ()
modifyEnv Env es
env EffectRep (DispatchOf e) e -> EffectRep (DispatchOf e) e
f = do
(Int
i, SmallMutableArray RealWorld AnyEffect
es) <- forall (e :: Effect) (es :: [Effect]).
(HasCallStack, e :> es) =>
Env es -> IO (Int, SmallMutableArray RealWorld AnyEffect)
getLocation @e Env es
env
EffectRep (DispatchOf e) e
e <- EffectRep (DispatchOf e) e -> EffectRep (DispatchOf e) e
f (EffectRep (DispatchOf e) e -> EffectRep (DispatchOf e) e)
-> (AnyEffect -> EffectRep (DispatchOf e) e)
-> AnyEffect
-> EffectRep (DispatchOf e) e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AnyEffect -> EffectRep (DispatchOf e) e
forall (e :: Effect). AnyEffect -> EffectRep (DispatchOf e) e
fromAnyEffect (AnyEffect -> EffectRep (DispatchOf e) e)
-> IO AnyEffect -> IO (EffectRep (DispatchOf e) e)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> SmallMutableArray (PrimState IO) AnyEffect -> Int -> IO AnyEffect
forall (m :: Type -> Type) a.
PrimMonad m =>
SmallMutableArray (PrimState m) a -> Int -> m a
readSmallArray SmallMutableArray RealWorld AnyEffect
SmallMutableArray (PrimState IO) AnyEffect
es Int
i
SmallMutableArray RealWorld AnyEffect -> Int -> AnyEffect -> IO ()
forall a. SmallMutableArray RealWorld a -> Int -> a -> IO ()
writeSmallArray' SmallMutableArray RealWorld AnyEffect
es Int
i (EffectRep (DispatchOf e) e -> AnyEffect
forall (e :: Effect). EffectRep (DispatchOf e) e -> AnyEffect
toAnyEffect EffectRep (DispatchOf e) e
e)
getLocation
:: forall e es. (HasCallStack, e :> es)
=> Env es
-> IO (Int, SmallMutableArray RealWorld AnyEffect)
getLocation :: forall (e :: Effect) (es :: [Effect]).
(HasCallStack, e :> es) =>
Env es -> IO (Int, SmallMutableArray RealWorld AnyEffect)
getLocation (Env Int
offset PrimArray Ref
refs IORef' Storage
storage) = do
Storage Version
_ (StorageData Int
_ MutablePrimArray RealWorld Version
vs SmallMutableArray RealWorld AnyEffect
es SmallMutableArray RealWorld AnyRelinker
_) <- IORef' Storage -> IO Storage
forall a. IORef' a -> IO a
readIORef' IORef' Storage
storage
Version
storageVersion <- MutablePrimArray (PrimState IO) Version -> Int -> IO Version
forall a (m :: Type -> Type).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> m a
readPrimArray MutablePrimArray RealWorld Version
MutablePrimArray (PrimState IO) Version
vs Int
ref
Bool -> IO () -> IO ()
forall (f :: Type -> Type). Applicative f => Bool -> f () -> f ()
when (Version
version Version -> Version -> Bool
forall a. Eq a => a -> a -> Bool
/= Version
storageVersion) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
String -> IO ()
forall a. HasCallStack => String -> a
error (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"version (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Version -> String
forall a. Show a => a -> String
show Version
version String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
") /= storageVersion ("
String -> ShowS
forall a. [a] -> [a] -> [a]
++ Version -> String
forall a. Show a => a -> String
show Version
storageVersion String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")\n"
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"If you're attempting to run an unlifting function outside "
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"of the scope of effects it captures, have a look at "
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"UnliftingStrategy (SeqForkUnlift)."
(Int, SmallMutableArray RealWorld AnyEffect)
-> IO (Int, SmallMutableArray RealWorld AnyEffect)
forall a. a -> IO a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Int
ref, SmallMutableArray RealWorld AnyEffect
es)
where
Ref Int
ref Version
version = PrimArray Ref -> Int -> Ref
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray Ref
refs (Int
offset Int -> Int -> Int
forall a. Num a => a -> a -> a
+ forall (e :: Effect) (es :: [Effect]). (e :> es) => Int
reifyIndex @e @es)
emptyStorage :: HasCallStack => IO Storage
emptyStorage :: HasCallStack => IO Storage
emptyStorage = Version -> StorageData -> Storage
Storage Version
initialVersion (StorageData -> Storage) -> IO StorageData -> IO Storage
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> IO StorageData
storageData
where
storageData :: IO StorageData
storageData = Int
-> MutablePrimArray RealWorld Version
-> SmallMutableArray RealWorld AnyEffect
-> SmallMutableArray RealWorld AnyRelinker
-> StorageData
StorageData Int
0
(MutablePrimArray RealWorld Version
-> SmallMutableArray RealWorld AnyEffect
-> SmallMutableArray RealWorld AnyRelinker
-> StorageData)
-> IO (MutablePrimArray RealWorld Version)
-> IO
(SmallMutableArray RealWorld AnyEffect
-> SmallMutableArray RealWorld AnyRelinker -> StorageData)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> IO (MutablePrimArray (PrimState IO) Version)
forall (m :: Type -> Type) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray Int
0
IO
(SmallMutableArray RealWorld AnyEffect
-> SmallMutableArray RealWorld AnyRelinker -> StorageData)
-> IO (SmallMutableArray RealWorld AnyEffect)
-> IO (SmallMutableArray RealWorld AnyRelinker -> StorageData)
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> Int -> AnyEffect -> IO (SmallMutableArray (PrimState IO) AnyEffect)
forall (m :: Type -> Type) a.
PrimMonad m =>
Int -> a -> m (SmallMutableArray (PrimState m) a)
newSmallArray Int
0 AnyEffect
HasCallStack => AnyEffect
undefinedEffect
IO (SmallMutableArray RealWorld AnyRelinker -> StorageData)
-> IO (SmallMutableArray RealWorld AnyRelinker) -> IO StorageData
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> Int
-> AnyRelinker -> IO (SmallMutableArray (PrimState IO) AnyRelinker)
forall (m :: Type -> Type) a.
PrimMonad m =>
Int -> a -> m (SmallMutableArray (PrimState m) a)
newSmallArray Int
0 AnyRelinker
HasCallStack => AnyRelinker
undefinedRelinker
insertEffect
:: HasCallStack
=> IORef' Storage
-> EffectRep (DispatchOf e) e
-> Relinker (EffectRep (DispatchOf e)) e
-> IO Ref
insertEffect :: forall (e :: Effect).
HasCallStack =>
IORef' Storage
-> EffectRep (DispatchOf e) e
-> Relinker (EffectRep (DispatchOf e)) e
-> IO Ref
insertEffect IORef' Storage
storage EffectRep (DispatchOf e) e
e Relinker (EffectRep (DispatchOf e)) e
f = do
Storage Version
version (StorageData Int
size MutablePrimArray RealWorld Version
vs0 SmallMutableArray RealWorld AnyEffect
es0 SmallMutableArray RealWorld AnyRelinker
fs0) <- IORef' Storage -> IO Storage
forall a. IORef' a -> IO a
readIORef' IORef' Storage
storage
Int
len0 <- SmallMutableArray (PrimState IO) AnyEffect -> IO Int
forall (m :: Type -> Type) a.
PrimMonad m =>
SmallMutableArray (PrimState m) a -> m Int
getSizeofSmallMutableArray SmallMutableArray RealWorld AnyEffect
SmallMutableArray (PrimState IO) AnyEffect
es0
case Int
size Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` Int
len0 of
Ordering
GT -> String -> IO Ref
forall a. HasCallStack => String -> a
error (String -> IO Ref) -> String -> IO Ref
forall a b. (a -> b) -> a -> b
$ String
"size (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
size String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
") > len0 (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
len0 String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
Ordering
LT -> do
MutablePrimArray (PrimState IO) Version -> Int -> Version -> IO ()
forall a (m :: Type -> Type).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray MutablePrimArray RealWorld Version
MutablePrimArray (PrimState IO) Version
vs0 Int
size Version
version
SmallMutableArray RealWorld AnyEffect -> Int -> AnyEffect -> IO ()
forall a. SmallMutableArray RealWorld a -> Int -> a -> IO ()
writeSmallArray' SmallMutableArray RealWorld AnyEffect
es0 Int
size (EffectRep (DispatchOf e) e -> AnyEffect
forall (e :: Effect). EffectRep (DispatchOf e) e -> AnyEffect
toAnyEffect EffectRep (DispatchOf e) e
e)
SmallMutableArray RealWorld AnyRelinker
-> Int -> AnyRelinker -> IO ()
forall a. SmallMutableArray RealWorld a -> Int -> a -> IO ()
writeSmallArray' SmallMutableArray RealWorld AnyRelinker
fs0 Int
size (Relinker (EffectRep (DispatchOf e)) e -> AnyRelinker
forall (e :: Effect).
Relinker (EffectRep (DispatchOf e)) e -> AnyRelinker
toAnyRelinker Relinker (EffectRep (DispatchOf e)) e
f)
IORef' Storage -> Storage -> IO ()
forall a. IORef' a -> a -> IO ()
writeIORef' IORef' Storage
storage (Storage -> IO ()) -> Storage -> IO ()
forall a b. (a -> b) -> a -> b
$
Version -> StorageData -> Storage
Storage (Version -> Version
bumpVersion Version
version) (Int
-> MutablePrimArray RealWorld Version
-> SmallMutableArray RealWorld AnyEffect
-> SmallMutableArray RealWorld AnyRelinker
-> StorageData
StorageData (Int
size Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) MutablePrimArray RealWorld Version
vs0 SmallMutableArray RealWorld AnyEffect
es0 SmallMutableArray RealWorld AnyRelinker
fs0)
Ref -> IO Ref
forall a. a -> IO a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Ref -> IO Ref) -> Ref -> IO Ref
forall a b. (a -> b) -> a -> b
$ Int -> Version -> Ref
Ref Int
size Version
version
Ordering
EQ -> do
let len :: Int
len = Int -> Int
doubleCapacity Int
len0
MutablePrimArray RealWorld Version
vs <- Int -> IO (MutablePrimArray (PrimState IO) Version)
forall (m :: Type -> Type) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray Int
len
SmallMutableArray RealWorld AnyEffect
es <- Int -> AnyEffect -> IO (SmallMutableArray (PrimState IO) AnyEffect)
forall (m :: Type -> Type) a.
PrimMonad m =>
Int -> a -> m (SmallMutableArray (PrimState m) a)
newSmallArray Int
len AnyEffect
HasCallStack => AnyEffect
undefinedEffect
SmallMutableArray RealWorld AnyRelinker
fs <- Int
-> AnyRelinker -> IO (SmallMutableArray (PrimState IO) AnyRelinker)
forall (m :: Type -> Type) a.
PrimMonad m =>
Int -> a -> m (SmallMutableArray (PrimState m) a)
newSmallArray Int
len AnyRelinker
HasCallStack => AnyRelinker
undefinedRelinker
MutablePrimArray (PrimState IO) Version
-> Int
-> MutablePrimArray (PrimState IO) Version
-> Int
-> Int
-> IO ()
forall (m :: Type -> Type) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a
-> Int -> MutablePrimArray (PrimState m) a -> Int -> Int -> m ()
copyMutablePrimArray MutablePrimArray RealWorld Version
MutablePrimArray (PrimState IO) Version
vs Int
0 MutablePrimArray RealWorld Version
MutablePrimArray (PrimState IO) Version
vs0 Int
0 Int
size
SmallMutableArray (PrimState IO) AnyEffect
-> Int
-> SmallMutableArray (PrimState IO) AnyEffect
-> Int
-> Int
-> IO ()
forall (m :: Type -> Type) a.
PrimMonad m =>
SmallMutableArray (PrimState m) a
-> Int -> SmallMutableArray (PrimState m) a -> Int -> Int -> m ()
copySmallMutableArray SmallMutableArray RealWorld AnyEffect
SmallMutableArray (PrimState IO) AnyEffect
es Int
0 SmallMutableArray RealWorld AnyEffect
SmallMutableArray (PrimState IO) AnyEffect
es0 Int
0 Int
size
SmallMutableArray (PrimState IO) AnyRelinker
-> Int
-> SmallMutableArray (PrimState IO) AnyRelinker
-> Int
-> Int
-> IO ()
forall (m :: Type -> Type) a.
PrimMonad m =>
SmallMutableArray (PrimState m) a
-> Int -> SmallMutableArray (PrimState m) a -> Int -> Int -> m ()
copySmallMutableArray SmallMutableArray RealWorld AnyRelinker
SmallMutableArray (PrimState IO) AnyRelinker
fs Int
0 SmallMutableArray RealWorld AnyRelinker
SmallMutableArray (PrimState IO) AnyRelinker
fs0 Int
0 Int
size
MutablePrimArray (PrimState IO) Version -> Int -> Version -> IO ()
forall a (m :: Type -> Type).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray MutablePrimArray RealWorld Version
MutablePrimArray (PrimState IO) Version
vs Int
size Version
version
SmallMutableArray RealWorld AnyEffect -> Int -> AnyEffect -> IO ()
forall a. SmallMutableArray RealWorld a -> Int -> a -> IO ()
writeSmallArray' SmallMutableArray RealWorld AnyEffect
es Int
size (EffectRep (DispatchOf e) e -> AnyEffect
forall (e :: Effect). EffectRep (DispatchOf e) e -> AnyEffect
toAnyEffect EffectRep (DispatchOf e) e
e)
SmallMutableArray RealWorld AnyRelinker
-> Int -> AnyRelinker -> IO ()
forall a. SmallMutableArray RealWorld a -> Int -> a -> IO ()
writeSmallArray' SmallMutableArray RealWorld AnyRelinker
fs Int
size (Relinker (EffectRep (DispatchOf e)) e -> AnyRelinker
forall (e :: Effect).
Relinker (EffectRep (DispatchOf e)) e -> AnyRelinker
toAnyRelinker Relinker (EffectRep (DispatchOf e)) e
f)
IORef' Storage -> Storage -> IO ()
forall a. IORef' a -> a -> IO ()
writeIORef' IORef' Storage
storage (Storage -> IO ()) -> Storage -> IO ()
forall a b. (a -> b) -> a -> b
$
Version -> StorageData -> Storage
Storage (Version -> Version
bumpVersion Version
version) (Int
-> MutablePrimArray RealWorld Version
-> SmallMutableArray RealWorld AnyEffect
-> SmallMutableArray RealWorld AnyRelinker
-> StorageData
StorageData (Int
size Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) MutablePrimArray RealWorld Version
vs SmallMutableArray RealWorld AnyEffect
es SmallMutableArray RealWorld AnyRelinker
fs)
Ref -> IO Ref
forall a. a -> IO a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Ref -> IO Ref) -> Ref -> IO Ref
forall a b. (a -> b) -> a -> b
$ Int -> Version -> Ref
Ref Int
size Version
version
deleteEffect :: HasCallStack => IORef' Storage -> Ref -> IO ()
deleteEffect :: HasCallStack => IORef' Storage -> Ref -> IO ()
deleteEffect IORef' Storage
storage (Ref Int
ref Version
version) = do
Storage Version
currentVersion (StorageData Int
size MutablePrimArray RealWorld Version
vs SmallMutableArray RealWorld AnyEffect
es SmallMutableArray RealWorld AnyRelinker
fs) <- IORef' Storage -> IO Storage
forall a. IORef' a -> IO a
readIORef' IORef' Storage
storage
Bool -> IO () -> IO ()
forall (f :: Type -> Type). Applicative f => Bool -> f () -> f ()
when (Int
ref Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
size Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
String -> IO ()
forall a. HasCallStack => String -> a
error (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"ref (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
ref String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
") /= size - 1 (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (Int
size Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
Version
storageVersion <- MutablePrimArray (PrimState IO) Version -> Int -> IO Version
forall a (m :: Type -> Type).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> m a
readPrimArray MutablePrimArray RealWorld Version
MutablePrimArray (PrimState IO) Version
vs Int
ref
Bool -> IO () -> IO ()
forall (f :: Type -> Type). Applicative f => Bool -> f () -> f ()
when (Version
version Version -> Version -> Bool
forall a. Eq a => a -> a -> Bool
/= Version
storageVersion) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
String -> IO ()
forall a. HasCallStack => String -> a
error (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"version (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Version -> String
forall a. Show a => a -> String
show Version
version String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
") /= storageVersion ("
String -> ShowS
forall a. [a] -> [a] -> [a]
++ Version -> String
forall a. Show a => a -> String
show Version
storageVersion String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")\n"
MutablePrimArray (PrimState IO) Version -> Int -> Version -> IO ()
forall a (m :: Type -> Type).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray MutablePrimArray RealWorld Version
MutablePrimArray (PrimState IO) Version
vs Int
ref Version
undefinedVersion
SmallMutableArray (PrimState IO) AnyEffect
-> Int -> AnyEffect -> IO ()
forall (m :: Type -> Type) a.
PrimMonad m =>
SmallMutableArray (PrimState m) a -> Int -> a -> m ()
writeSmallArray SmallMutableArray RealWorld AnyEffect
SmallMutableArray (PrimState IO) AnyEffect
es Int
ref AnyEffect
HasCallStack => AnyEffect
undefinedEffect
SmallMutableArray (PrimState IO) AnyRelinker
-> Int -> AnyRelinker -> IO ()
forall (m :: Type -> Type) a.
PrimMonad m =>
SmallMutableArray (PrimState m) a -> Int -> a -> m ()
writeSmallArray SmallMutableArray RealWorld AnyRelinker
SmallMutableArray (PrimState IO) AnyRelinker
fs Int
ref AnyRelinker
HasCallStack => AnyRelinker
undefinedRelinker
IORef' Storage -> Storage -> IO ()
forall a. IORef' a -> a -> IO ()
writeIORef' IORef' Storage
storage (Storage -> IO ()) -> Storage -> IO ()
forall a b. (a -> b) -> a -> b
$ Version -> StorageData -> Storage
Storage Version
currentVersion (Int
-> MutablePrimArray RealWorld Version
-> SmallMutableArray RealWorld AnyEffect
-> SmallMutableArray RealWorld AnyRelinker
-> StorageData
StorageData (Int
size Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) MutablePrimArray RealWorld Version
vs SmallMutableArray RealWorld AnyEffect
es SmallMutableArray RealWorld AnyRelinker
fs)
relinkEnv :: IORef' Storage -> Env es -> IO (Env es)
relinkEnv :: forall (es :: [Effect]). IORef' Storage -> Env es -> IO (Env es)
relinkEnv IORef' Storage
storage (Env Int
offset PrimArray Ref
refs IORef' Storage
_) = Env es -> IO (Env es)
forall a. a -> IO a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Env es -> IO (Env es)) -> Env es -> IO (Env es)
forall a b. (a -> b) -> a -> b
$ Int -> PrimArray Ref -> IORef' Storage -> Env es
forall (es :: [Effect]).
Int -> PrimArray Ref -> IORef' Storage -> Env es
Env Int
offset PrimArray Ref
refs IORef' Storage
storage
doubleCapacity :: Int -> Int
doubleCapacity :: Int -> Int
doubleCapacity Int
n = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
1 Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
2
undefinedVersion :: Version
undefinedVersion :: Version
undefinedVersion = Int -> Version
Version Int
0
initialVersion :: Version
initialVersion :: Version
initialVersion = Int -> Version
Version Int
1
bumpVersion :: Version -> Version
bumpVersion :: Version -> Version
bumpVersion (Version Int
n) = Int -> Version
Version (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
undefinedEffect :: HasCallStack => AnyEffect
undefinedEffect :: HasCallStack => AnyEffect
undefinedEffect = EffectRep (DispatchOf Any) Any -> AnyEffect
forall (e :: Effect). EffectRep (DispatchOf e) e -> AnyEffect
toAnyEffect (EffectRep (DispatchOf Any) Any -> AnyEffect)
-> (String -> EffectRep (DispatchOf Any) Any)
-> String
-> AnyEffect
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> EffectRep (DispatchOf Any) Any
forall a. String -> a
errorWithoutStackTrace (String -> AnyEffect) -> String -> AnyEffect
forall a b. (a -> b) -> a -> b
$ [String] -> String
unlines
[ String
"Undefined effect"
, String
"Created at: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ CallStack -> String
prettyCallStack CallStack
HasCallStack => CallStack
callStack
]
undefinedRelinker :: HasCallStack => AnyRelinker
undefinedRelinker :: HasCallStack => AnyRelinker
undefinedRelinker = Relinker (EffectRep (DispatchOf Any)) Any -> AnyRelinker
forall (e :: Effect).
Relinker (EffectRep (DispatchOf e)) e -> AnyRelinker
toAnyRelinker (Relinker (EffectRep (DispatchOf Any)) Any -> AnyRelinker)
-> Relinker (EffectRep (DispatchOf Any)) Any -> AnyRelinker
forall a b. (a -> b) -> a -> b
$ (HasCallStack =>
(forall (es :: [Effect]). Env es -> IO (Env es))
-> EffectRep (DispatchOf Any) Any
-> IO (EffectRep (DispatchOf Any) Any))
-> Relinker (EffectRep (DispatchOf Any)) Any
forall (rep :: Effect -> Type) (e :: Effect).
(HasCallStack =>
(forall (es :: [Effect]). Env es -> IO (Env es))
-> rep e -> IO (rep e))
-> Relinker rep e
Relinker ((HasCallStack =>
(forall (es :: [Effect]). Env es -> IO (Env es))
-> EffectRep (DispatchOf Any) Any
-> IO (EffectRep (DispatchOf Any) Any))
-> Relinker (EffectRep (DispatchOf Any)) Any)
-> (HasCallStack =>
(forall (es :: [Effect]). Env es -> IO (Env es))
-> EffectRep (DispatchOf Any) Any
-> IO (EffectRep (DispatchOf Any) Any))
-> Relinker (EffectRep (DispatchOf Any)) Any
forall a b. (a -> b) -> a -> b
$ \forall (es :: [Effect]). Env es -> IO (Env es)
_ EffectRep (DispatchOf Any) Any
_ -> do
String -> IO (EffectRep (DispatchOf Any) Any)
forall a. String -> a
errorWithoutStackTrace (String -> IO (EffectRep (DispatchOf Any) Any))
-> String -> IO (EffectRep (DispatchOf Any) Any)
forall a b. (a -> b) -> a -> b
$ [String] -> String
unlines
[ String
"Undefined relinker"
, String
"Created at: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ CallStack -> String
prettyCallStack CallStack
creationCallStack
, String
"Called at: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ CallStack -> String
prettyCallStack CallStack
HasCallStack => CallStack
callStack
]
where
creationCallStack :: CallStack
creationCallStack = CallStack
HasCallStack => CallStack
callStack
writeSmallArray' :: SmallMutableArray RealWorld a -> Int -> a -> IO ()
writeSmallArray' :: forall a. SmallMutableArray RealWorld a -> Int -> a -> IO ()
writeSmallArray' SmallMutableArray RealWorld a
arr Int
i a
a = a
a a -> IO () -> IO ()
forall a b. a -> b -> b
`seq` SmallMutableArray (PrimState IO) a -> Int -> a -> IO ()
forall (m :: Type -> Type) a.
PrimMonad m =>
SmallMutableArray (PrimState m) a -> Int -> a -> m ()
writeSmallArray SmallMutableArray RealWorld a
SmallMutableArray (PrimState IO) a
arr Int
i a
a
#if !MIN_VERSION_primitive(0,9,0)
getSizeofSmallMutableArray :: SmallMutableArray RealWorld a -> IO Int
getSizeofSmallMutableArray arr = pure $! sizeofSmallMutableArray arr
#endif