{-# OPTIONS_GHC -fno-warn-name-shadowing #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE CPP #-}
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
[HValue]
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
(HValue -> IO HValueRef) -> [HValue] -> IO [HValueRef]
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 HValue -> IO HValueRef
forall a. a -> IO (RemoteRef a)
mkRemoteRef [HValue]
hvals
createBCO :: Array Int HValue -> ResolvedBCO -> IO HValue
createBCO :: Array Int HValue -> ResolvedBCO -> IO HValue
createBCO Array Int HValue
_ ResolvedBCO{Bool
Int
UArray Int Word16
UArray Int Word64
SizedSeq ResolvedBCOPtr
resolvedBCOIsLE :: Bool
resolvedBCOArity :: Int
resolvedBCOInstrs :: UArray Int Word16
resolvedBCOBitmap :: UArray Int Word64
resolvedBCOLits :: UArray Int Word64
resolvedBCOPtrs :: SizedSeq ResolvedBCOPtr
resolvedBCOPtrs :: ResolvedBCO -> SizedSeq ResolvedBCOPtr
resolvedBCOLits :: ResolvedBCO -> UArray Int Word64
resolvedBCOBitmap :: ResolvedBCO -> UArray Int Word64
resolvedBCOInstrs :: ResolvedBCO -> UArray Int 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. 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 BCO
linked_bco <- Array Int HValue -> ResolvedBCO -> IO BCO
linkBCO' Array Int HValue
arr ResolvedBCO
bco
if (ResolvedBCO -> Int
resolvedBCOArity ResolvedBCO
bco Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0)
then HValue -> IO HValue
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Any -> HValue
HValue (BCO -> Any
forall a b. a -> b
unsafeCoerce BCO
linked_bco))
else case BCO -> (# Any #)
forall a. BCO -> (# a #)
mkApUpd0# BCO
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) }
toWordArray :: UArray Int Word64 -> UArray Int Word
toWordArray :: UArray Int Word64 -> UArray Int Word
toWordArray = (Word64 -> Word) -> UArray Int Word64 -> UArray Int Word
forall (a :: * -> * -> *) e' e i.
(IArray a e', IArray a e, Ix i) =>
(e' -> e) -> a i e' -> a i e
amap Word64 -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral
linkBCO' :: Array Int HValue -> ResolvedBCO -> IO BCO
linkBCO' :: Array Int HValue -> ResolvedBCO -> IO BCO
linkBCO' Array Int HValue
arr ResolvedBCO{Bool
Int
UArray Int Word16
UArray Int Word64
SizedSeq ResolvedBCOPtr
resolvedBCOPtrs :: ResolvedBCO -> SizedSeq ResolvedBCOPtr
resolvedBCOLits :: ResolvedBCO -> UArray Int Word64
resolvedBCOBitmap :: ResolvedBCO -> UArray Int Word64
resolvedBCOInstrs :: ResolvedBCO -> UArray Int Word16
resolvedBCOArity :: ResolvedBCO -> Int
resolvedBCOIsLE :: ResolvedBCO -> Bool
resolvedBCOIsLE :: Bool
resolvedBCOArity :: Int
resolvedBCOInstrs :: UArray Int Word16
resolvedBCOBitmap :: UArray Int Word64
resolvedBCOLits :: UArray Int Word64
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 :: UArray i e -> ByteArray#
barr UArray i e
a = case UArray i e
a of UArray i
_lo i
_hi Int
n ByteArray#
b -> if Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then ByteArray#
empty# else ByteArray#
b
insns_barr :: ByteArray#
insns_barr = UArray Int Word16 -> ByteArray#
forall {i} {e}. UArray i e -> ByteArray#
barr UArray Int Word16
resolvedBCOInstrs
bitmap_barr :: ByteArray#
bitmap_barr = UArray Int Word -> ByteArray#
forall {i} {e}. UArray i e -> ByteArray#
barr (UArray Int Word64 -> UArray Int Word
toWordArray UArray Int Word64
resolvedBCOBitmap)
literals_barr :: ByteArray#
literals_barr = UArray Int Word -> ByteArray#
forall {i} {e}. UArray i e -> ByteArray#
barr (UArray Int Word64 -> UArray Int Word
toWordArray UArray Int Word64
resolvedBCOLits)
PtrsArr MutableArray# RealWorld HValue
marr <- Array Int HValue -> Word -> [ResolvedBCOPtr] -> IO PtrsArr
mkPtrsArray Array Int HValue
arr Word
n_ptrs [ResolvedBCOPtr]
ptrs
(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 ->
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
PtrsArr
marr <- Int -> IO PtrsArr
newPtrsArray (Word -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word
n_ptrs)
let
fill :: ResolvedBCOPtr -> Int -> IO ()
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
HValue
hv <- HValueRef -> IO HValue
forall a. RemoteRef a -> IO a
localRef HValueRef
r
Int -> HValue -> PtrsArr -> IO ()
writePtrsArrayHValue Int
i HValue
hv PtrsArr
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
bco <- Array Int HValue -> ResolvedBCO -> IO BCO
linkBCO' Array Int HValue
arr ResolvedBCO
bco
Int -> BCO -> PtrsArr -> IO ()
writePtrsArrayBCO Int
i BCO
bco PtrsArr
marr
fill (ResolvedBCOPtrBreakArray RemoteRef BreakArray
r) Int
i = do
BA MutableByteArray# RealWorld
mba <- RemoteRef BreakArray -> IO BreakArray
forall a. RemoteRef a -> IO a
localRef RemoteRef BreakArray
r
Int -> MutableByteArray# RealWorld -> PtrsArr -> IO ()
forall s. Int -> MutableByteArray# s -> PtrsArr -> IO ()
writePtrsArrayMBA Int
i MutableByteArray# RealWorld
mba PtrsArr
marr
(ResolvedBCOPtr -> Int -> IO ())
-> [ResolvedBCOPtr] -> [Int] -> IO ()
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m ()
zipWithM_ ResolvedBCOPtr -> Int -> IO ()
fill [ResolvedBCOPtr]
ptrs [Int
0..]
PtrsArr -> IO PtrsArr
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return PtrsArr
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# Any Any -> Int# -> Any -> State# Any -> State# Any)
-> MutableArray# s a -> Int# -> Addr# -> State# s -> State# s
forall a b. a -> b
unsafeCoerce# MutableArray# Any Any -> Int# -> Any -> State# Any -> State# Any
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# Any Any -> Int# -> Any -> State# Any -> State# Any)
-> MutableArray# RealWorld HValue
-> Int#
-> BCO
-> State# RealWorld
-> State# RealWorld
forall a b. a -> b
unsafeCoerce# MutableArray# Any Any -> Int# -> Any -> State# Any -> State# Any
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# Any Any -> Int# -> Any -> State# Any -> State# Any)
-> MutableArray# RealWorld HValue
-> Int#
-> MutableByteArray# s
-> State# RealWorld
-> State# RealWorld
forall a b. a -> b
unsafeCoerce# MutableArray# Any Any -> Int# -> Any -> State# Any -> State# Any
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 #)
}}