{-# OPTIONS_GHC -fno-warn-name-shadowing #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE CPP #-}
{-# OPTIONS_GHC -Wno-warnings-deprecations #-}
module GHCi.CreateBCO (createBCOs) where
import Prelude
import GHCi.ResolvedBCO
import GHCi.RemoteTypes
import GHCi.BreakArray
import GHC.Data.SizedSeq
import System.IO (fixIO)
import Control.Monad
import Data.Array.Base
import Foreign hiding (newArray)
import Unsafe.Coerce (unsafeCoerce)
import GHC.Arr ( Array(..) )
import GHC.Exts
import GHC.IO
import Control.Exception ( ErrorCall(..) )
createBCOs :: [ResolvedBCO] -> IO [HValueRef]
createBCOs :: [ResolvedBCO] -> IO [HValueRef]
createBCOs [ResolvedBCO]
bcos = do
let n_bcos :: Int
n_bcos = [ResolvedBCO] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [ResolvedBCO]
bcos
hvals <- ([HValue] -> IO [HValue]) -> IO [HValue]
forall a. (a -> IO a) -> IO a
fixIO (([HValue] -> IO [HValue]) -> IO [HValue])
-> ([HValue] -> IO [HValue]) -> IO [HValue]
forall a b. (a -> b) -> a -> b
$ \[HValue]
hvs -> do
let arr :: Array Int HValue
arr = (Int, Int) -> [HValue] -> Array Int HValue
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
(i, i) -> [e] -> a i e
listArray (Int
0, Int
n_bcosInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) [HValue]
hvs
(ResolvedBCO -> IO HValue) -> [ResolvedBCO] -> IO [HValue]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (Array Int HValue -> ResolvedBCO -> IO HValue
createBCO Array Int HValue
arr) [ResolvedBCO]
bcos
mapM mkRemoteRef hvals
createBCO :: Array Int HValue -> ResolvedBCO -> IO HValue
createBCO :: Array Int HValue -> ResolvedBCO -> IO HValue
createBCO Array Int HValue
_ ResolvedBCO{Bool
Int
SizedSeq ResolvedBCOPtr
BCOByteArray Word
BCOByteArray Word16
resolvedBCOIsLE :: Bool
resolvedBCOArity :: Int
resolvedBCOInstrs :: BCOByteArray Word16
resolvedBCOBitmap :: BCOByteArray Word
resolvedBCOLits :: BCOByteArray Word
resolvedBCOPtrs :: SizedSeq ResolvedBCOPtr
resolvedBCOPtrs :: ResolvedBCO -> SizedSeq ResolvedBCOPtr
resolvedBCOLits :: ResolvedBCO -> BCOByteArray Word
resolvedBCOBitmap :: ResolvedBCO -> BCOByteArray Word
resolvedBCOInstrs :: ResolvedBCO -> BCOByteArray Word16
resolvedBCOArity :: ResolvedBCO -> Int
resolvedBCOIsLE :: ResolvedBCO -> Bool
..} | Bool
resolvedBCOIsLE Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
/= Bool
isLittleEndian
= ErrorCall -> IO HValue
forall e a. (HasCallStack, Exception e) => e -> IO a
throwIO (String -> ErrorCall
ErrorCall (String -> ErrorCall) -> String -> ErrorCall
forall a b. (a -> b) -> a -> b
$
[String] -> String
unlines [ String
"The endianness of the ResolvedBCO does not match"
, String
"the systems endianness. Using ghc and iserv in a"
, String
"mixed endianness setup is not supported!"
])
createBCO Array Int HValue
arr ResolvedBCO
bco
= do linked_bco <- Array Int HValue -> ResolvedBCO -> IO BCO
linkBCO' Array Int HValue
arr ResolvedBCO
bco
if (resolvedBCOArity bco > 0)
then return (HValue (unsafeCoerce linked_bco))
else case mkApUpd0# linked_bco of { (# Any
final_bco #) ->
HValue -> IO HValue
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Any -> HValue
HValue Any
final_bco) }
linkBCO' :: Array Int HValue -> ResolvedBCO -> IO BCO
linkBCO' :: Array Int HValue -> ResolvedBCO -> IO BCO
linkBCO' Array Int HValue
arr ResolvedBCO{Bool
Int
SizedSeq ResolvedBCOPtr
BCOByteArray Word
BCOByteArray Word16
resolvedBCOPtrs :: ResolvedBCO -> SizedSeq ResolvedBCOPtr
resolvedBCOLits :: ResolvedBCO -> BCOByteArray Word
resolvedBCOBitmap :: ResolvedBCO -> BCOByteArray Word
resolvedBCOInstrs :: ResolvedBCO -> BCOByteArray Word16
resolvedBCOArity :: ResolvedBCO -> Int
resolvedBCOIsLE :: ResolvedBCO -> Bool
resolvedBCOIsLE :: Bool
resolvedBCOArity :: Int
resolvedBCOInstrs :: BCOByteArray Word16
resolvedBCOBitmap :: BCOByteArray Word
resolvedBCOLits :: BCOByteArray Word
resolvedBCOPtrs :: SizedSeq ResolvedBCOPtr
..} = do
let
ptrs :: [ResolvedBCOPtr]
ptrs = SizedSeq ResolvedBCOPtr -> [ResolvedBCOPtr]
forall a. SizedSeq a -> [a]
ssElts SizedSeq ResolvedBCOPtr
resolvedBCOPtrs
n_ptrs :: Word
n_ptrs = SizedSeq ResolvedBCOPtr -> Word
forall a. SizedSeq a -> Word
sizeSS SizedSeq ResolvedBCOPtr
resolvedBCOPtrs
!(I# Int#
arity#) = Int
resolvedBCOArity
!(EmptyArr ByteArray#
empty#) = EmptyArr
emptyArr
barr :: ByteArray# -> ByteArray#
barr ByteArray#
arr# = if Int# -> Int
I# (ByteArray# -> Int#
sizeofByteArray# ByteArray#
arr#) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then ByteArray#
empty# else ByteArray#
arr#
insns_barr :: ByteArray#
insns_barr = ByteArray# -> ByteArray#
barr (BCOByteArray Word16 -> ByteArray#
forall a. BCOByteArray a -> ByteArray#
getBCOByteArray BCOByteArray Word16
resolvedBCOInstrs)
bitmap_barr :: ByteArray#
bitmap_barr = ByteArray# -> ByteArray#
barr (BCOByteArray Word -> ByteArray#
forall a. BCOByteArray a -> ByteArray#
getBCOByteArray BCOByteArray Word
resolvedBCOBitmap)
literals_barr :: ByteArray#
literals_barr = ByteArray# -> ByteArray#
barr (BCOByteArray Word -> ByteArray#
forall a. BCOByteArray a -> ByteArray#
getBCOByteArray BCOByteArray Word
resolvedBCOLits)
PtrsArr marr <- Array Int HValue -> Word -> [ResolvedBCOPtr] -> IO PtrsArr
mkPtrsArray Array Int HValue
arr Word
n_ptrs [ResolvedBCOPtr]
ptrs
IO $ \State# RealWorld
s ->
case MutableArray# RealWorld HValue
-> State# RealWorld -> (# State# RealWorld, Array# HValue #)
forall d a.
MutableArray# d a -> State# d -> (# State# d, Array# a #)
unsafeFreezeArray# MutableArray# RealWorld HValue
marr State# RealWorld
s of { (# State# RealWorld
s, Array# HValue
arr #) ->
case ByteArray#
-> ByteArray# -> Array# HValue -> Int# -> ByteArray# -> IO BCO
forall a.
ByteArray#
-> ByteArray# -> Array# a -> Int# -> ByteArray# -> IO BCO
newBCO ByteArray#
insns_barr ByteArray#
literals_barr Array# HValue
arr Int#
arity# ByteArray#
bitmap_barr of { IO State# RealWorld -> (# State# RealWorld, BCO #)
io ->
State# RealWorld -> (# State# RealWorld, BCO #)
io State# RealWorld
s
}}
mkPtrsArray :: Array Int HValue -> Word -> [ResolvedBCOPtr] -> IO PtrsArr
mkPtrsArray :: Array Int HValue -> Word -> [ResolvedBCOPtr] -> IO PtrsArr
mkPtrsArray Array Int HValue
arr Word
n_ptrs [ResolvedBCOPtr]
ptrs = do
marr <- Int -> IO PtrsArr
newPtrsArray (Word -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word
n_ptrs)
let
fill (ResolvedBCORef Int
n) Int
i =
Int -> HValue -> PtrsArr -> IO ()
writePtrsArrayHValue Int
i (Array Int HValue
arr Array Int HValue -> Int -> HValue
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
! Int
n) PtrsArr
marr
fill (ResolvedBCOPtr HValueRef
r) Int
i = do
hv <- HValueRef -> IO HValue
forall a. RemoteRef a -> IO a
localRef HValueRef
r
writePtrsArrayHValue i hv marr
fill (ResolvedBCOStaticPtr RemotePtr ()
r) Int
i = do
Int -> Ptr () -> PtrsArr -> IO ()
forall a. Int -> Ptr a -> PtrsArr -> IO ()
writePtrsArrayPtr Int
i (RemotePtr () -> Ptr ()
forall a. RemotePtr a -> Ptr a
fromRemotePtr RemotePtr ()
r) PtrsArr
marr
fill (ResolvedBCOPtrBCO ResolvedBCO
bco) Int
i = do
bco <- Array Int HValue -> ResolvedBCO -> IO BCO
linkBCO' Array Int HValue
arr ResolvedBCO
bco
writePtrsArrayBCO i bco marr
fill (ResolvedBCOPtrBreakArray RemoteRef BreakArray
r) Int
i = do
BA mba <- RemoteRef BreakArray -> IO BreakArray
forall a. RemoteRef a -> IO a
localRef RemoteRef BreakArray
r
writePtrsArrayMBA i mba marr
zipWithM_ fill ptrs [0..]
return marr
data PtrsArr = PtrsArr (MutableArray# RealWorld HValue)
newPtrsArray :: Int -> IO PtrsArr
newPtrsArray :: Int -> IO PtrsArr
newPtrsArray (I# Int#
i) = (State# RealWorld -> (# State# RealWorld, PtrsArr #)) -> IO PtrsArr
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, PtrsArr #))
-> IO PtrsArr)
-> (State# RealWorld -> (# State# RealWorld, PtrsArr #))
-> IO PtrsArr
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s ->
case Int#
-> HValue
-> State# RealWorld
-> (# State# RealWorld, MutableArray# RealWorld HValue #)
forall a d.
Int# -> a -> State# d -> (# State# d, MutableArray# d a #)
newArray# Int#
i HValue
forall a. HasCallStack => a
undefined State# RealWorld
s of (# State# RealWorld
s', MutableArray# RealWorld HValue
arr #) -> (# State# RealWorld
s', MutableArray# RealWorld HValue -> PtrsArr
PtrsArr MutableArray# RealWorld HValue
arr #)
writePtrsArrayHValue :: Int -> HValue -> PtrsArr -> IO ()
writePtrsArrayHValue :: Int -> HValue -> PtrsArr -> IO ()
writePtrsArrayHValue (I# Int#
i) HValue
hv (PtrsArr MutableArray# RealWorld HValue
arr) = (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, () #)) -> IO ())
-> (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s ->
case MutableArray# RealWorld HValue
-> Int# -> HValue -> State# RealWorld -> State# RealWorld
forall d a. MutableArray# d a -> Int# -> a -> State# d -> State# d
writeArray# MutableArray# RealWorld HValue
arr Int#
i HValue
hv State# RealWorld
s of State# RealWorld
s' -> (# State# RealWorld
s', () #)
writePtrsArrayPtr :: Int -> Ptr a -> PtrsArr -> IO ()
writePtrsArrayPtr :: forall a. Int -> Ptr a -> PtrsArr -> IO ()
writePtrsArrayPtr (I# Int#
i) (Ptr Addr#
a#) (PtrsArr MutableArray# RealWorld HValue
arr) = (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, () #)) -> IO ())
-> (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s ->
case MutableArray# RealWorld HValue
-> Int# -> Addr# -> State# RealWorld -> State# RealWorld
forall s a.
MutableArray# s a -> Int# -> Addr# -> State# s -> State# s
writeArrayAddr# MutableArray# RealWorld HValue
arr Int#
i Addr#
a# State# RealWorld
s of State# RealWorld
s' -> (# State# RealWorld
s', () #)
{-# NOINLINE writeArrayAddr# #-}
writeArrayAddr# :: MutableArray# s a -> Int# -> Addr# -> State# s -> State# s
#if defined(javascript_HOST_ARCH)
writeArrayAddr# = error "writeArrayAddr#: currently unsupported with the JS backend"
#else
writeArrayAddr# :: forall s a.
MutableArray# s a -> Int# -> Addr# -> State# s -> State# s
writeArrayAddr# MutableArray# s a
marr Int#
i Addr#
addr State# s
s = (MutableArray# (ZonkAny 4) (ZonkAny 5)
-> Int# -> ZonkAny 5 -> State# (ZonkAny 4) -> State# (ZonkAny 4))
-> MutableArray# s a -> Int# -> Addr# -> State# s -> State# s
forall a b. a -> b
unsafeCoerce# MutableArray# (ZonkAny 4) (ZonkAny 5)
-> Int# -> ZonkAny 5 -> State# (ZonkAny 4) -> State# (ZonkAny 4)
forall d a. MutableArray# d a -> Int# -> a -> State# d -> State# d
writeArray# MutableArray# s a
marr Int#
i Addr#
addr State# s
s
#endif
writePtrsArrayBCO :: Int -> BCO -> PtrsArr -> IO ()
writePtrsArrayBCO :: Int -> BCO -> PtrsArr -> IO ()
writePtrsArrayBCO (I# Int#
i) BCO
bco (PtrsArr MutableArray# RealWorld HValue
arr) = (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, () #)) -> IO ())
-> (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s ->
case ((MutableArray# (ZonkAny 2) (ZonkAny 3)
-> Int# -> ZonkAny 3 -> State# (ZonkAny 2) -> State# (ZonkAny 2))
-> MutableArray# RealWorld HValue
-> Int#
-> BCO
-> State# RealWorld
-> State# RealWorld
forall a b. a -> b
unsafeCoerce# MutableArray# (ZonkAny 2) (ZonkAny 3)
-> Int# -> ZonkAny 3 -> State# (ZonkAny 2) -> State# (ZonkAny 2)
forall d a. MutableArray# d a -> Int# -> a -> State# d -> State# d
writeArray#) MutableArray# RealWorld HValue
arr Int#
i BCO
bco State# RealWorld
s of State# RealWorld
s' -> (# State# RealWorld
s', () #)
writePtrsArrayMBA :: Int -> MutableByteArray# s -> PtrsArr -> IO ()
writePtrsArrayMBA :: forall s. Int -> MutableByteArray# s -> PtrsArr -> IO ()
writePtrsArrayMBA (I# Int#
i) MutableByteArray# s
mba (PtrsArr MutableArray# RealWorld HValue
arr) = (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, () #)) -> IO ())
-> (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s ->
case ((MutableArray# (ZonkAny 0) (ZonkAny 1)
-> Int# -> ZonkAny 1 -> State# (ZonkAny 0) -> State# (ZonkAny 0))
-> MutableArray# RealWorld HValue
-> Int#
-> MutableByteArray# s
-> State# RealWorld
-> State# RealWorld
forall a b. a -> b
unsafeCoerce# MutableArray# (ZonkAny 0) (ZonkAny 1)
-> Int# -> ZonkAny 1 -> State# (ZonkAny 0) -> State# (ZonkAny 0)
forall d a. MutableArray# d a -> Int# -> a -> State# d -> State# d
writeArray#) MutableArray# RealWorld HValue
arr Int#
i MutableByteArray# s
mba State# RealWorld
s of State# RealWorld
s' -> (# State# RealWorld
s', () #)
newBCO :: ByteArray# -> ByteArray# -> Array# a -> Int# -> ByteArray# -> IO BCO
newBCO :: forall a.
ByteArray#
-> ByteArray# -> Array# a -> Int# -> ByteArray# -> IO BCO
newBCO ByteArray#
instrs ByteArray#
lits Array# a
ptrs Int#
arity ByteArray#
bitmap = (State# RealWorld -> (# State# RealWorld, BCO #)) -> IO BCO
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, BCO #)) -> IO BCO)
-> (State# RealWorld -> (# State# RealWorld, BCO #)) -> IO BCO
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s ->
ByteArray#
-> ByteArray#
-> Array# a
-> Int#
-> ByteArray#
-> State# RealWorld
-> (# State# RealWorld, BCO #)
forall a d.
ByteArray#
-> ByteArray#
-> Array# a
-> Int#
-> ByteArray#
-> State# d
-> (# State# d, BCO #)
newBCO# ByteArray#
instrs ByteArray#
lits Array# a
ptrs Int#
arity ByteArray#
bitmap State# RealWorld
s
data EmptyArr = EmptyArr ByteArray#
{-# NOINLINE emptyArr #-}
emptyArr :: EmptyArr
emptyArr :: EmptyArr
emptyArr = IO EmptyArr -> EmptyArr
forall a. IO a -> a
unsafeDupablePerformIO (IO EmptyArr -> EmptyArr) -> IO EmptyArr -> EmptyArr
forall a b. (a -> b) -> a -> b
$ (State# RealWorld -> (# State# RealWorld, EmptyArr #))
-> IO EmptyArr
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, EmptyArr #))
-> IO EmptyArr)
-> (State# RealWorld -> (# State# RealWorld, EmptyArr #))
-> IO EmptyArr
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s ->
case Int#
-> State# RealWorld
-> (# State# RealWorld, MutableByteArray# RealWorld #)
forall d. Int# -> State# d -> (# State# d, MutableByteArray# d #)
newByteArray# Int#
0# State# RealWorld
s of { (# State# RealWorld
s, MutableByteArray# RealWorld
arr #) ->
case MutableByteArray# RealWorld
-> State# RealWorld -> (# State# RealWorld, ByteArray# #)
forall d.
MutableByteArray# d -> State# d -> (# State# d, ByteArray# #)
unsafeFreezeByteArray# MutableByteArray# RealWorld
arr State# RealWorld
s of { (# State# RealWorld
s, ByteArray#
farr #) ->
(# State# RealWorld
s, ByteArray# -> EmptyArr
EmptyArr ByteArray#
farr #)
}}