{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedRecordDot #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE UndecidableInstances #-}
module JVM.Data.Convert.ConstantPool where
import Data.IndexedMap (IndexedMap)
import Data.IndexedMap qualified as IM
import Data.Text.Encoding
import Data.Tuple (swap)
import Data.Vector qualified as V
import JVM.Data.Abstract.ConstantPool
import JVM.Data.Convert.Descriptor
import JVM.Data.Convert.Numbers
import JVM.Data.Convert.Type
import JVM.Data.Raw.ClassFile qualified as Raw
import JVM.Data.Raw.ConstantPool
import JVM.Data.Raw.MagicNumbers
import JVM.Data.Raw.Types
import Effectful
import Effectful.State.Static.Local
import Effectful.TH (makeEffect)
import Effectful.Dispatch.Dynamic (interpret)
data ConstantPoolState = ConstantPoolState
{ ConstantPoolState -> IndexedMap ConstantPoolInfo
constantPool :: IndexedMap ConstantPoolInfo
, ConstantPoolState -> IndexedMap BootstrapMethod
bootstrapMethods :: IndexedMap Raw.BootstrapMethod
}
deriving (Int -> ConstantPoolState -> ShowS
[ConstantPoolState] -> ShowS
ConstantPoolState -> String
(Int -> ConstantPoolState -> ShowS)
-> (ConstantPoolState -> String)
-> ([ConstantPoolState] -> ShowS)
-> Show ConstantPoolState
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ConstantPoolState -> ShowS
showsPrec :: Int -> ConstantPoolState -> ShowS
$cshow :: ConstantPoolState -> String
show :: ConstantPoolState -> String
$cshowList :: [ConstantPoolState] -> ShowS
showList :: [ConstantPoolState] -> ShowS
Show, ConstantPoolState -> ConstantPoolState -> Bool
(ConstantPoolState -> ConstantPoolState -> Bool)
-> (ConstantPoolState -> ConstantPoolState -> Bool)
-> Eq ConstantPoolState
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ConstantPoolState -> ConstantPoolState -> Bool
== :: ConstantPoolState -> ConstantPoolState -> Bool
$c/= :: ConstantPoolState -> ConstantPoolState -> Bool
/= :: ConstantPoolState -> ConstantPoolState -> Bool
Eq, Eq ConstantPoolState
Eq ConstantPoolState =>
(ConstantPoolState -> ConstantPoolState -> Ordering)
-> (ConstantPoolState -> ConstantPoolState -> Bool)
-> (ConstantPoolState -> ConstantPoolState -> Bool)
-> (ConstantPoolState -> ConstantPoolState -> Bool)
-> (ConstantPoolState -> ConstantPoolState -> Bool)
-> (ConstantPoolState -> ConstantPoolState -> ConstantPoolState)
-> (ConstantPoolState -> ConstantPoolState -> ConstantPoolState)
-> Ord ConstantPoolState
ConstantPoolState -> ConstantPoolState -> Bool
ConstantPoolState -> ConstantPoolState -> Ordering
ConstantPoolState -> ConstantPoolState -> ConstantPoolState
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 :: ConstantPoolState -> ConstantPoolState -> Ordering
compare :: ConstantPoolState -> ConstantPoolState -> Ordering
$c< :: ConstantPoolState -> ConstantPoolState -> Bool
< :: ConstantPoolState -> ConstantPoolState -> Bool
$c<= :: ConstantPoolState -> ConstantPoolState -> Bool
<= :: ConstantPoolState -> ConstantPoolState -> Bool
$c> :: ConstantPoolState -> ConstantPoolState -> Bool
> :: ConstantPoolState -> ConstantPoolState -> Bool
$c>= :: ConstantPoolState -> ConstantPoolState -> Bool
>= :: ConstantPoolState -> ConstantPoolState -> Bool
$cmax :: ConstantPoolState -> ConstantPoolState -> ConstantPoolState
max :: ConstantPoolState -> ConstantPoolState -> ConstantPoolState
$cmin :: ConstantPoolState -> ConstantPoolState -> ConstantPoolState
min :: ConstantPoolState -> ConstantPoolState -> ConstantPoolState
Ord)
data ConstantPool m a where
GetCP :: ConstantPool m ConstantPoolState
SetCP :: ConstantPoolState -> ConstantPool m ()
makeEffect ''ConstantPool
lookupOrInsertMOver :: (ConstantPool :> r, Ord a) => a -> (ConstantPoolState -> IndexedMap a) -> (ConstantPoolState -> IndexedMap a -> ConstantPoolState) -> Eff r Int
lookupOrInsertMOver :: forall (r :: [Effect]) a.
(ConstantPool :> r, Ord a) =>
a
-> (ConstantPoolState -> IndexedMap a)
-> (ConstantPoolState -> IndexedMap a -> ConstantPoolState)
-> Eff r Int
lookupOrInsertMOver a
cpInfo ConstantPoolState -> IndexedMap a
get ConstantPoolState -> IndexedMap a -> ConstantPoolState
set = do
cp <- Eff r ConstantPoolState
forall {k} (es :: [Effect]).
(HasCallStack, ConstantPool :> es) =>
Eff es ConstantPoolState
getCP
let (i, newCP) = IM.lookupOrInsert cpInfo (get cp)
setCP (set cp newCP)
pure i
lookupOrInsertMCP :: (ConstantPool :> r) => ConstantPoolInfo -> Eff r Int
lookupOrInsertMCP :: forall (r :: [Effect]).
(ConstantPool :> r) =>
ConstantPoolInfo -> Eff r Int
lookupOrInsertMCP ConstantPoolInfo
cpInfo = ConstantPoolInfo
-> (ConstantPoolState -> IndexedMap ConstantPoolInfo)
-> (ConstantPoolState
-> IndexedMap ConstantPoolInfo -> ConstantPoolState)
-> Eff r Int
forall (r :: [Effect]) a.
(ConstantPool :> r, Ord a) =>
a
-> (ConstantPoolState -> IndexedMap a)
-> (ConstantPoolState -> IndexedMap a -> ConstantPoolState)
-> Eff r Int
lookupOrInsertMOver ConstantPoolInfo
cpInfo (.constantPool) (\ConstantPoolState
s IndexedMap ConstantPoolInfo
x -> ConstantPoolState
s{constantPool = x})
lookupOrInsertMBM :: (ConstantPool :> r) => Raw.BootstrapMethod -> Eff r Int
lookupOrInsertMBM :: forall (r :: [Effect]).
(ConstantPool :> r) =>
BootstrapMethod -> Eff r Int
lookupOrInsertMBM BootstrapMethod
bmInfo = BootstrapMethod
-> (ConstantPoolState -> IndexedMap BootstrapMethod)
-> (ConstantPoolState
-> IndexedMap BootstrapMethod -> ConstantPoolState)
-> Eff r Int
forall (r :: [Effect]) a.
(ConstantPool :> r, Ord a) =>
a
-> (ConstantPoolState -> IndexedMap a)
-> (ConstantPoolState -> IndexedMap a -> ConstantPoolState)
-> Eff r Int
lookupOrInsertMOver BootstrapMethod
bmInfo (.bootstrapMethods) (\ConstantPoolState
s IndexedMap BootstrapMethod
x -> ConstantPoolState
s{bootstrapMethods = x})
transformEntry :: (ConstantPool :> r) => ConstantPoolEntry -> Eff r Int
transformEntry :: forall (r :: [Effect]).
(ConstantPool :> r) =>
ConstantPoolEntry -> Eff r Int
transformEntry (CPUTF8Entry Text
text) = ConstantPoolInfo -> Eff r Int
forall (r :: [Effect]).
(ConstantPool :> r) =>
ConstantPoolInfo -> Eff r Int
lookupOrInsertMCP (ByteString -> ConstantPoolInfo
UTF8Info (ByteString -> ConstantPoolInfo) -> ByteString -> ConstantPoolInfo
forall a b. (a -> b) -> a -> b
$ Text -> ByteString
encodeUtf8 Text
text)
transformEntry (CPIntegerEntry Int
i) = ConstantPoolInfo -> Eff r Int
forall (r :: [Effect]).
(ConstantPool :> r) =>
ConstantPoolInfo -> Eff r Int
lookupOrInsertMCP (U4 -> ConstantPoolInfo
IntegerInfo (U4 -> ConstantPoolInfo) -> U4 -> ConstantPoolInfo
forall a b. (a -> b) -> a -> b
$ Int -> U4
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
i)
transformEntry (CPFloatEntry Float
f) = ConstantPoolInfo -> Eff r Int
forall (r :: [Effect]).
(ConstantPool :> r) =>
ConstantPoolInfo -> Eff r Int
lookupOrInsertMCP (U4 -> ConstantPoolInfo
FloatInfo (Float -> U4
toJVMFloat Float
f))
transformEntry (CPStringEntry Text
msg) = do
i <- ConstantPoolEntry -> Eff r Int
forall (r :: [Effect]).
(ConstantPool :> r) =>
ConstantPoolEntry -> Eff r Int
transformEntry (Text -> ConstantPoolEntry
CPUTF8Entry Text
msg)
lookupOrInsertMCP (StringInfo $ fromIntegral i)
transformEntry (CPLongEntry Int64
i) = do
let (U4
high, U4
low) = Int64 -> (U4, U4)
toJVMLong Int64
i
ConstantPoolInfo -> Eff r Int
forall (r :: [Effect]).
(ConstantPool :> r) =>
ConstantPoolInfo -> Eff r Int
lookupOrInsertMCP (U4 -> U4 -> ConstantPoolInfo
LongInfo U4
high U4
low)
transformEntry (CPDoubleEntry Double
d) = do
let (U4
high, U4
low) = Int64 -> (U4, U4)
toJVMLong (Double -> Int64
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
round Double
d)
ConstantPoolInfo -> Eff r Int
forall (r :: [Effect]).
(ConstantPool :> r) =>
ConstantPoolInfo -> Eff r Int
lookupOrInsertMCP (U4 -> U4 -> ConstantPoolInfo
DoubleInfo U4
high U4
low)
transformEntry (CPClassEntry ClassInfoType
name) = do
let className :: Text
className = ClassInfoType -> Text
classInfoTypeDescriptor ClassInfoType
name
nameIndex <- ConstantPoolEntry -> Eff r Int
forall (r :: [Effect]).
(ConstantPool :> r) =>
ConstantPoolEntry -> Eff r Int
transformEntry (Text -> ConstantPoolEntry
CPUTF8Entry Text
className)
lookupOrInsertMCP (ClassInfo $ fromIntegral nameIndex)
transformEntry (CPMethodRefEntry (MethodRef ClassInfoType
classRef Text
name MethodDescriptor
methodDescriptor)) = do
classIndex <- ConstantPoolEntry -> Eff r Int
forall (r :: [Effect]).
(ConstantPool :> r) =>
ConstantPoolEntry -> Eff r Int
transformEntry (ClassInfoType -> ConstantPoolEntry
CPClassEntry ClassInfoType
classRef)
nameAndTypeIndex <- transformEntry (CPNameAndTypeEntry name (convertMethodDescriptor methodDescriptor))
lookupOrInsertMCP (MethodRefInfo (fromIntegral classIndex) (fromIntegral nameAndTypeIndex))
transformEntry (CPInterfaceMethodRefEntry (MethodRef ClassInfoType
classRef Text
name MethodDescriptor
methodDescriptor)) = do
classIndex <- ConstantPoolEntry -> Eff r Int
forall (r :: [Effect]).
(ConstantPool :> r) =>
ConstantPoolEntry -> Eff r Int
transformEntry (ClassInfoType -> ConstantPoolEntry
CPClassEntry ClassInfoType
classRef)
nameAndTypeIndex <- transformEntry (CPNameAndTypeEntry name (convertMethodDescriptor methodDescriptor))
lookupOrInsertMCP (InterfaceMethodRefInfo (fromIntegral classIndex) (fromIntegral nameAndTypeIndex))
transformEntry (CPNameAndTypeEntry Text
name Text
descriptor) = do
nameIndex <- ConstantPoolEntry -> Eff r Int
forall (r :: [Effect]).
(ConstantPool :> r) =>
ConstantPoolEntry -> Eff r Int
transformEntry (Text -> ConstantPoolEntry
CPUTF8Entry Text
name)
descriptorIndex <- transformEntry (CPUTF8Entry descriptor)
lookupOrInsertMCP (NameAndTypeInfo (fromIntegral nameIndex) (fromIntegral descriptorIndex))
transformEntry (CPFieldRefEntry (FieldRef ClassInfoType
classRef Text
name FieldType
fieldType)) = do
classIndex <- ConstantPoolEntry -> Eff r Int
forall (r :: [Effect]).
(ConstantPool :> r) =>
ConstantPoolEntry -> Eff r Int
transformEntry (ClassInfoType -> ConstantPoolEntry
CPClassEntry ClassInfoType
classRef)
nameAndTypeIndex <- transformEntry (CPNameAndTypeEntry name (fieldTypeDescriptor fieldType))
lookupOrInsertMCP (FieldRefInfo (fromIntegral classIndex) (fromIntegral nameAndTypeIndex))
transformEntry (CPMethodHandleEntry MethodHandleEntry
methodHandleEntry) = do
let transformFieldMHE :: FieldRef -> Eff r U2
transformFieldMHE f :: FieldRef
f@(FieldRef{}) = ConstantPoolEntry -> Eff r U2
forall (r :: [Effect]).
(ConstantPool :> r) =>
ConstantPoolEntry -> Eff r U2
findIndexOf (FieldRef -> ConstantPoolEntry
CPFieldRefEntry FieldRef
f)
let transformMethodMHE :: MethodRef -> Eff r U2
transformMethodMHE m :: MethodRef
m@(MethodRef{}) = ConstantPoolEntry -> Eff r U2
forall (r :: [Effect]).
(ConstantPool :> r) =>
ConstantPoolEntry -> Eff r U2
findIndexOf (MethodRef -> ConstantPoolEntry
CPMethodRefEntry MethodRef
m)
(referenceKind, referenceIndex) <- case MethodHandleEntry
methodHandleEntry of
MHGetField FieldRef
fr -> do
fri <- FieldRef -> Eff r U2
forall {r :: [Effect]}. (ConstantPool :> r) => FieldRef -> Eff r U2
transformFieldMHE FieldRef
fr
pure (_REF_getField, fri)
MHGetStatic FieldRef
fr -> do
fri <- FieldRef -> Eff r U2
forall {r :: [Effect]}. (ConstantPool :> r) => FieldRef -> Eff r U2
transformFieldMHE FieldRef
fr
pure (_REF_getStatic, fri)
MHPutField FieldRef
fr -> do
fri <- FieldRef -> Eff r U2
forall {r :: [Effect]}. (ConstantPool :> r) => FieldRef -> Eff r U2
transformFieldMHE FieldRef
fr
pure (_REF_putField, fri)
MHPutStatic FieldRef
fr -> do
fri <- FieldRef -> Eff r U2
forall {r :: [Effect]}. (ConstantPool :> r) => FieldRef -> Eff r U2
transformFieldMHE FieldRef
fr
pure (_REF_putStatic, fri)
MHInvokeVirtual MethodRef
mr -> do
mri <- MethodRef -> Eff r U2
forall {r :: [Effect]}.
(ConstantPool :> r) =>
MethodRef -> Eff r U2
transformMethodMHE MethodRef
mr
pure (_REF_invokeVirtual, mri)
MHNewInvokeSpecial MethodRef
mr -> do
mri <- MethodRef -> Eff r U2
forall {r :: [Effect]}.
(ConstantPool :> r) =>
MethodRef -> Eff r U2
transformMethodMHE MethodRef
mr
pure (_REF_newInvokeSpecial, mri)
MHInvokeStatic MethodRef
mr -> do
mri <- MethodRef -> Eff r U2
forall {r :: [Effect]}.
(ConstantPool :> r) =>
MethodRef -> Eff r U2
transformMethodMHE MethodRef
mr
pure (_REF_invokeStatic, mri)
MHInvokeSpecial MethodRef
mr -> do
mri <- MethodRef -> Eff r U2
forall {r :: [Effect]}.
(ConstantPool :> r) =>
MethodRef -> Eff r U2
transformMethodMHE MethodRef
mr
pure (_REF_invokeSpecial, mri)
MHInvokeInterface MethodRef
mr -> do
mri <- MethodRef -> Eff r U2
forall {r :: [Effect]}.
(ConstantPool :> r) =>
MethodRef -> Eff r U2
transformMethodMHE MethodRef
mr
pure (_REF_invokeInterface, mri)
lookupOrInsertMCP (MethodHandleInfo referenceKind referenceIndex)
transformEntry (CPInvokeDynamicEntry BootstrapMethod
bootstrapMethod Text
name MethodDescriptor
methodDescriptor) = do
nameAndTypeIndex <- ConstantPoolEntry -> Eff r U2
forall (r :: [Effect]).
(ConstantPool :> r) =>
ConstantPoolEntry -> Eff r U2
findIndexOf (Text -> Text -> ConstantPoolEntry
CPNameAndTypeEntry Text
name (MethodDescriptor -> Text
convertMethodDescriptor MethodDescriptor
methodDescriptor))
bmIndex <- convertBootstrapMethod bootstrapMethod
lookupOrInsertMCP
( InvokeDynamicInfo
( fromIntegral bmIndex - 1
)
(fromIntegral nameAndTypeIndex)
)
transformEntry (CPMethodTypeEntry MethodDescriptor
methodDescriptor) = do
descriptorIndex <- ConstantPoolEntry -> Eff r Int
forall (r :: [Effect]).
(ConstantPool :> r) =>
ConstantPoolEntry -> Eff r Int
transformEntry (Text -> ConstantPoolEntry
CPUTF8Entry (MethodDescriptor -> Text
convertMethodDescriptor MethodDescriptor
methodDescriptor))
lookupOrInsertMCP (MethodTypeInfo (fromIntegral descriptorIndex))
convertBootstrapMethod :: (ConstantPool :> r) => BootstrapMethod -> Eff r Int
convertBootstrapMethod :: forall (r :: [Effect]).
(ConstantPool :> r) =>
BootstrapMethod -> Eff r Int
convertBootstrapMethod (BootstrapMethod MethodHandleEntry
mhEntry [BootstrapArgument]
args) = do
mhIndex <- ConstantPoolEntry -> Eff r U2
forall (r :: [Effect]).
(ConstantPool :> r) =>
ConstantPoolEntry -> Eff r U2
findIndexOf (MethodHandleEntry -> ConstantPoolEntry
CPMethodHandleEntry MethodHandleEntry
mhEntry)
bsArgs <- traverse (findIndexOf . bmArgToCPEntry) args
let bootstrapMethod = U2 -> Vector U2 -> BootstrapMethod
Raw.BootstrapMethod (U2 -> U2
forall a b. (Integral a, Num b) => a -> b
fromIntegral U2
mhIndex) ([U2] -> Vector U2
forall a. [a] -> Vector a
V.fromList [U2]
bsArgs)
lookupOrInsertMBM bootstrapMethod
instance Semigroup ConstantPoolState where
(ConstantPoolState IndexedMap ConstantPoolInfo
cp1 IndexedMap BootstrapMethod
bm1) <> :: ConstantPoolState -> ConstantPoolState -> ConstantPoolState
<> (ConstantPoolState IndexedMap ConstantPoolInfo
cp2 IndexedMap BootstrapMethod
bm2) = IndexedMap ConstantPoolInfo
-> IndexedMap BootstrapMethod -> ConstantPoolState
ConstantPoolState (IndexedMap ConstantPoolInfo
cp1 IndexedMap ConstantPoolInfo
-> IndexedMap ConstantPoolInfo -> IndexedMap ConstantPoolInfo
forall a. Semigroup a => a -> a -> a
<> IndexedMap ConstantPoolInfo
cp2) (IndexedMap BootstrapMethod
bm1 IndexedMap BootstrapMethod
-> IndexedMap BootstrapMethod -> IndexedMap BootstrapMethod
forall a. Semigroup a => a -> a -> a
<> IndexedMap BootstrapMethod
bm2)
instance Monoid ConstantPoolState where
mempty :: ConstantPoolState
mempty = IndexedMap ConstantPoolInfo
-> IndexedMap BootstrapMethod -> ConstantPoolState
ConstantPoolState IndexedMap ConstantPoolInfo
forall a. Monoid a => a
mempty IndexedMap BootstrapMethod
forall a. Monoid a => a
mempty
findIndexOf :: (ConstantPool :> r) => ConstantPoolEntry -> Eff r U2
findIndexOf :: forall (r :: [Effect]).
(ConstantPool :> r) =>
ConstantPoolEntry -> Eff r U2
findIndexOf = (Int -> U2) -> Eff r Int -> Eff r U2
forall a b. (a -> b) -> Eff r a -> Eff r b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> U2
toU2OrError (Eff r Int -> Eff r U2)
-> (ConstantPoolEntry -> Eff r Int)
-> ConstantPoolEntry
-> Eff r U2
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConstantPoolEntry -> Eff r Int
forall (r :: [Effect]).
(ConstantPool :> r) =>
ConstantPoolEntry -> Eff r Int
transformEntry
where
toU2OrError :: Int -> U2
toU2OrError :: Int -> U2
toU2OrError Int
i =
if Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> U2 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a. Bounded a => a
maxBound @U2)
then String -> U2
forall a. HasCallStack => String -> a
error String
"Constant pool index out of bounds, too many entries?"
else Int -> U2
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
i
constantPoolToState :: State ConstantPoolState :> r => Eff (ConstantPool ': r) a -> Eff r a
constantPoolToState :: forall (r :: [Effect]) a.
(State ConstantPoolState :> r) =>
Eff (ConstantPool : r) a -> Eff r a
constantPoolToState = EffectHandler ConstantPool r -> Eff (ConstantPool : r) a -> Eff r a
forall (e :: Effect) (es :: [Effect]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic) =>
EffectHandler e es -> Eff (e : es) a -> Eff es a
interpret (EffectHandler ConstantPool r
-> Eff (ConstantPool : r) a -> Eff r a)
-> EffectHandler ConstantPool r
-> Eff (ConstantPool : r) a
-> Eff r a
forall a b. (a -> b) -> a -> b
$ \LocalEnv localEs r
_ -> \case
ConstantPool (Eff localEs) a
GetCP -> (a -> a) -> Eff r a
forall s (es :: [Effect]) a.
(HasCallStack, State s :> es) =>
(s -> a) -> Eff es a
gets a -> a
forall a. a -> a
id
SetCP ConstantPoolState
s -> (ConstantPoolState -> ConstantPoolState) -> Eff r ()
forall s (es :: [Effect]).
(HasCallStack, State s :> es) =>
(s -> s) -> Eff es ()
modify (ConstantPoolState -> ConstantPoolState -> ConstantPoolState
forall a b. a -> b -> a
const ConstantPoolState
s)
runConstantPoolWith :: ConstantPoolState -> Eff (ConstantPool ': r) a -> Eff r (a, ConstantPoolState)
runConstantPoolWith :: forall (r :: [Effect]) a.
ConstantPoolState
-> Eff (ConstantPool : r) a -> Eff r (a, ConstantPoolState)
runConstantPoolWith ConstantPoolState
s =
ConstantPoolState
-> Eff (State ConstantPoolState : r) a
-> Eff r (a, ConstantPoolState)
forall s (es :: [Effect]) a.
HasCallStack =>
s -> Eff (State s : es) a -> Eff es (a, s)
runState ConstantPoolState
s
(Eff (State ConstantPoolState : r) a
-> Eff r (a, ConstantPoolState))
-> (Eff (ConstantPool : r) a
-> Eff (State ConstantPoolState : r) a)
-> Eff (ConstantPool : r) a
-> Eff r (a, ConstantPoolState)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Eff (ConstantPool : State ConstantPoolState : r) a
-> Eff (State ConstantPoolState : r) a
forall (r :: [Effect]) a.
(State ConstantPoolState :> r) =>
Eff (ConstantPool : r) a -> Eff r a
constantPoolToState
(Eff (ConstantPool : State ConstantPoolState : r) a
-> Eff (State ConstantPoolState : r) a)
-> (Eff (ConstantPool : r) a
-> Eff (ConstantPool : State ConstantPoolState : r) a)
-> Eff (ConstantPool : r) a
-> Eff (State ConstantPoolState : r) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Eff (ConstantPool : r) a
-> Eff (ConstantPool : State ConstantPoolState : r) a
forall (subEs :: [Effect]) (es :: [Effect]) a.
Subset subEs es =>
Eff subEs a -> Eff es a
inject
runConstantPool :: Eff (ConstantPool ': r) a -> Eff r (a, ConstantPoolState)
runConstantPool :: forall (r :: [Effect]) a.
Eff (ConstantPool : r) a -> Eff r (a, ConstantPoolState)
runConstantPool = ConstantPoolState
-> Eff (ConstantPool : r) a -> Eff r (a, ConstantPoolState)
forall (r :: [Effect]) a.
ConstantPoolState
-> Eff (ConstantPool : r) a -> Eff r (a, ConstantPoolState)
runConstantPoolWith ConstantPoolState
forall a. Monoid a => a
mempty