{-# LANGUAGE
  MultiParamTypeClasses,
  FunctionalDependencies,
  OverloadedStrings,
  RankNTypes
  #-}
module LLVM.Internal.ExecutionEngine where

import LLVM.Prelude

import Control.Exception
import Control.Monad.IO.Class
import Control.Monad.AnyCont

import Data.IORef
import Foreign.Ptr
import Foreign.C (CUInt, CString)
import Foreign.Marshal.Alloc (allocaBytes)

import qualified LLVM.Internal.FFI.PtrHierarchy as FFI
import qualified LLVM.Internal.FFI.ExecutionEngine as FFI
import qualified LLVM.Internal.FFI.Module as FFI
import qualified LLVM.Internal.FFI.LLVMCTypes as FFI

import LLVM.Internal.Module
import LLVM.Internal.Context
import LLVM.Internal.Coding
import qualified LLVM.CodeModel as CodeModel
import LLVM.Internal.Target
import qualified LLVM.AST as A
import GHC.Stack

removeModule :: Ptr FFI.ExecutionEngine -> Ptr FFI.Module -> IO ()
removeModule :: Ptr ExecutionEngine -> Ptr Module -> IO ()
removeModule Ptr ExecutionEngine
e Ptr Module
m = (() -> IO ()) -> AnyContT IO () -> IO ()
forall a (m :: * -> *) r. (a -> m r) -> AnyContT m a -> m r
runAnyContT' () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (AnyContT IO () -> IO ()) -> AnyContT IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
  Ptr (Ptr Module)
d0 <- AnyContT IO (Ptr (Ptr Module))
forall a (m :: * -> *).
(Storable a, MonadAnyCont IO m) =>
m (Ptr a)
alloca
  Ptr CString
d1 <- AnyContT IO (Ptr CString)
forall a (m :: * -> *).
(Storable a, MonadAnyCont IO m) =>
m (Ptr a)
alloca
  CUInt
r <- IO CUInt -> AnyContT IO CUInt
forall a. IO a -> AnyContT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO CUInt -> AnyContT IO CUInt) -> IO CUInt -> AnyContT IO CUInt
forall a b. (a -> b) -> a -> b
$ Ptr ExecutionEngine
-> Ptr Module -> Ptr (Ptr Module) -> Ptr CString -> IO CUInt
FFI.removeModule Ptr ExecutionEngine
e Ptr Module
m Ptr (Ptr Module)
d0 Ptr CString
d1
  Bool -> AnyContT IO () -> AnyContT IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (CUInt
r CUInt -> CUInt -> Bool
forall a. Eq a => a -> a -> Bool
/= CUInt
0) (AnyContT IO () -> AnyContT IO ())
-> AnyContT IO () -> AnyContT IO ()
forall a b. (a -> b) -> a -> b
$ String -> AnyContT IO ()
forall a. String -> AnyContT IO a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"FFI.removeModule failure"

-- | a 'ExecutableModule' e represents a 'Module' which is currently "in" an
-- 'ExecutionEngine', and so the functions of which may be executed.
data ExecutableModule e = ExecutableModule e (Ptr FFI.Module)

-- | <http://llvm.org/doxygen/classllvm_1_1ExecutionEngine.html>
class ExecutionEngine e f | e -> f where
  withModuleInEngine :: e -> Module -> (ExecutableModule e -> IO a) -> IO a
  getFunction :: HasCallStack => ExecutableModule e -> A.Name -> IO (Maybe f)

instance ExecutionEngine (Ptr FFI.ExecutionEngine) (FunPtr ()) where
  withModuleInEngine :: forall a.
Ptr ExecutionEngine
-> Module
-> (ExecutableModule (Ptr ExecutionEngine) -> IO a)
-> IO a
withModuleInEngine Ptr ExecutionEngine
e Module
m ExecutableModule (Ptr ExecutionEngine) -> IO a
f = do
    Ptr Module
m' <- Module -> IO (Ptr Module)
forall (m :: * -> *). MonadIO m => Module -> m (Ptr Module)
readModule Module
m
    IO () -> IO () -> IO a -> IO a
forall a b c. IO a -> IO b -> IO c -> IO c
bracket_ (Ptr ExecutionEngine -> Ptr Module -> IO ()
FFI.addModule Ptr ExecutionEngine
e Ptr Module
m') (Ptr ExecutionEngine -> Ptr Module -> IO ()
removeModule Ptr ExecutionEngine
e Ptr Module
m') (ExecutableModule (Ptr ExecutionEngine) -> IO a
f (Ptr ExecutionEngine
-> Ptr Module -> ExecutableModule (Ptr ExecutionEngine)
forall e. e -> Ptr Module -> ExecutableModule e
ExecutableModule Ptr ExecutionEngine
e Ptr Module
m'))
  getFunction :: HasCallStack =>
ExecutableModule (Ptr ExecutionEngine)
-> Name -> IO (Maybe (FunPtr ()))
getFunction (ExecutableModule Ptr ExecutionEngine
e Ptr Module
m) (A.Name ShortByteString
name) = (Maybe (FunPtr ()) -> IO (Maybe (FunPtr ())))
-> AnyContT IO (Maybe (FunPtr ())) -> IO (Maybe (FunPtr ()))
forall a (m :: * -> *) r. (a -> m r) -> AnyContT m a -> m r
runAnyContT' Maybe (FunPtr ()) -> IO (Maybe (FunPtr ()))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (AnyContT IO (Maybe (FunPtr ())) -> IO (Maybe (FunPtr ())))
-> AnyContT IO (Maybe (FunPtr ())) -> IO (Maybe (FunPtr ()))
forall a b. (a -> b) -> a -> b
$ do
    CString
name <- ShortByteString -> AnyContT IO CString
forall (e :: * -> *) h c. (EncodeM e h c, HasCallStack) => h -> e c
encodeM ShortByteString
name
    Ptr Function
f <- IO (Ptr Function) -> AnyContT IO (Ptr Function)
forall a. IO a -> AnyContT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Ptr Function) -> AnyContT IO (Ptr Function))
-> IO (Ptr Function) -> AnyContT IO (Ptr Function)
forall a b. (a -> b) -> a -> b
$ Ptr Module -> CString -> IO (Ptr Function)
FFI.getNamedFunction Ptr Module
m CString
name
    if Ptr Function
f Ptr Function -> Ptr Function -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr Function
forall a. Ptr a
nullPtr 
      then 
        Maybe (FunPtr ()) -> AnyContT IO (Maybe (FunPtr ()))
forall a. a -> AnyContT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (FunPtr ())
forall a. Maybe a
Nothing
      else
        do
          Ptr ()
p <- IO (Ptr ()) -> AnyContT IO (Ptr ())
forall a. IO a -> AnyContT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Ptr ()) -> AnyContT IO (Ptr ()))
-> IO (Ptr ()) -> AnyContT IO (Ptr ())
forall a b. (a -> b) -> a -> b
$ Ptr ExecutionEngine -> Ptr GlobalValue -> IO (Ptr ())
FFI.getPointerToGlobal Ptr ExecutionEngine
e (Ptr Function -> Ptr GlobalValue
forall a b. DescendentOf a b => Ptr b -> Ptr a
FFI.upCast Ptr Function
f)
          Maybe (FunPtr ()) -> AnyContT IO (Maybe (FunPtr ()))
forall a. a -> AnyContT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (FunPtr ()) -> AnyContT IO (Maybe (FunPtr ())))
-> Maybe (FunPtr ()) -> AnyContT IO (Maybe (FunPtr ()))
forall a b. (a -> b) -> a -> b
$ if Ptr ()
p Ptr () -> Ptr () -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr ()
forall a. Ptr a
nullPtr then Maybe (FunPtr ())
forall a. Maybe a
Nothing else FunPtr () -> Maybe (FunPtr ())
forall a. a -> Maybe a
Just (Ptr () -> FunPtr ()
forall a b. Ptr a -> FunPtr b
castPtrToFunPtr Ptr ()
p)
  getFunction ExecutableModule (Ptr ExecutionEngine)
_ Name
_ = String -> IO (Maybe (FunPtr ()))
forall a. HasCallStack => String -> a
error String
"Only named functions can be looked up"

withExecutionEngine :: 
  Context ->
  Maybe (Ptr FFI.Module) -> 
  (Ptr (Ptr FFI.ExecutionEngine) -> Ptr FFI.Module -> Ptr (FFI.OwnerTransfered CString) -> IO CUInt) ->
  (Ptr FFI.ExecutionEngine -> IO a) ->
  IO a
withExecutionEngine :: forall a.
Context
-> Maybe (Ptr Module)
-> (Ptr (Ptr ExecutionEngine)
    -> Ptr Module -> Ptr (OwnerTransfered CString) -> IO CUInt)
-> (Ptr ExecutionEngine -> IO a)
-> IO a
withExecutionEngine Context
c Maybe (Ptr Module)
m Ptr (Ptr ExecutionEngine)
-> Ptr Module -> Ptr (OwnerTransfered CString) -> IO CUInt
createEngine Ptr ExecutionEngine -> IO a
f = (a -> IO a) -> AnyContT IO a -> IO a
forall a (m :: * -> *) r. (a -> m r) -> AnyContT m a -> m r
runAnyContT' a -> IO a
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (AnyContT IO a -> IO a) -> AnyContT IO a -> IO a
forall a b. (a -> b) -> a -> b
$ do
  IO () -> AnyContT IO ()
forall a. IO a -> AnyContT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO ()
initializeNativeTarget
  Ptr (Ptr ExecutionEngine)
outExecutionEngine <- AnyContT IO (Ptr (Ptr ExecutionEngine))
forall a (m :: * -> *).
(Storable a, MonadAnyCont IO m) =>
m (Ptr a)
alloca
  Ptr (OwnerTransfered CString)
outErrorCStringPtr <- AnyContT IO (Ptr (OwnerTransfered CString))
forall a (m :: * -> *).
(Storable a, MonadAnyCont IO m) =>
m (Ptr a)
alloca
  Module
dummyModule <- AnyContT IO Module
-> (Ptr Module -> AnyContT IO Module)
-> Maybe (Ptr Module)
-> AnyContT IO Module
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ((forall r. (Module -> IO r) -> IO r) -> AnyContT IO Module
forall a. (forall r. (a -> IO r) -> IO r) -> AnyContT IO a
forall (b :: * -> *) (m :: * -> *) a.
MonadAnyCont b m =>
(forall r. (a -> b r) -> b r) -> m a
anyContToM ((forall r. (Module -> IO r) -> IO r) -> AnyContT IO Module)
-> (forall r. (Module -> IO r) -> IO r) -> AnyContT IO Module
forall a b. (a -> b) -> a -> b
$
                          Context -> Module -> (Module -> IO r) -> IO r
forall a. Context -> Module -> (Module -> IO a) -> IO a
withModuleFromAST Context
c (ShortByteString
-> ShortByteString
-> Maybe DataLayout
-> Maybe ShortByteString
-> [Definition]
-> Module
A.Module ShortByteString
"" ShortByteString
"" Maybe DataLayout
forall a. Maybe a
Nothing Maybe ShortByteString
forall a. Maybe a
Nothing []))
                 (IO Module -> AnyContT IO Module
forall a. IO a -> AnyContT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Module -> AnyContT IO Module)
-> (Ptr Module -> IO Module) -> Ptr Module -> AnyContT IO Module
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr Module -> IO Module
newModule) Maybe (Ptr Module)
m
  Ptr Module
dummyModule' <- Module -> AnyContT IO (Ptr Module)
forall (m :: * -> *). MonadIO m => Module -> m (Ptr Module)
readModule Module
dummyModule
  CUInt
r <- IO CUInt -> AnyContT IO CUInt
forall a. IO a -> AnyContT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO CUInt -> AnyContT IO CUInt) -> IO CUInt -> AnyContT IO CUInt
forall a b. (a -> b) -> a -> b
$ Ptr (Ptr ExecutionEngine)
-> Ptr Module -> Ptr (OwnerTransfered CString) -> IO CUInt
createEngine Ptr (Ptr ExecutionEngine)
outExecutionEngine Ptr Module
dummyModule' Ptr (OwnerTransfered CString)
outErrorCStringPtr
  Bool -> AnyContT IO () -> AnyContT IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (CUInt
r CUInt -> CUInt -> Bool
forall a. Eq a => a -> a -> Bool
/= CUInt
0) (AnyContT IO () -> AnyContT IO ())
-> AnyContT IO () -> AnyContT IO ()
forall a b. (a -> b) -> a -> b
$ String -> AnyContT IO ()
forall a. String -> AnyContT IO a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> AnyContT IO ()) -> AnyContT IO String -> AnyContT IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr (OwnerTransfered CString) -> AnyContT IO String
forall (d :: * -> *) h c. (DecodeM d h c, HasCallStack) => c -> d h
decodeM Ptr (OwnerTransfered CString)
outErrorCStringPtr
  Ptr ExecutionEngine
executionEngine <- (forall r. (Ptr ExecutionEngine -> IO r) -> IO r)
-> AnyContT IO (Ptr ExecutionEngine)
forall a. (forall r. (a -> IO r) -> IO r) -> AnyContT IO a
forall (b :: * -> *) (m :: * -> *) a.
MonadAnyCont b m =>
(forall r. (a -> b r) -> b r) -> m a
anyContToM ((forall r. (Ptr ExecutionEngine -> IO r) -> IO r)
 -> AnyContT IO (Ptr ExecutionEngine))
-> (forall r. (Ptr ExecutionEngine -> IO r) -> IO r)
-> AnyContT IO (Ptr ExecutionEngine)
forall a b. (a -> b) -> a -> b
$ IO (Ptr ExecutionEngine)
-> (Ptr ExecutionEngine -> IO ())
-> (Ptr ExecutionEngine -> IO r)
-> IO r
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket (Ptr (Ptr ExecutionEngine) -> IO (Ptr ExecutionEngine)
forall a (m :: * -> *). (Storable a, MonadIO m) => Ptr a -> m a
peek Ptr (Ptr ExecutionEngine)
outExecutionEngine) Ptr ExecutionEngine -> IO ()
FFI.disposeExecutionEngine
  IO () -> AnyContT IO ()
forall a. IO a -> AnyContT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> AnyContT IO ()) -> IO () -> AnyContT IO ()
forall a b. (a -> b) -> a -> b
$ Ptr ExecutionEngine -> Ptr Module -> IO ()
removeModule Ptr ExecutionEngine
executionEngine Ptr Module
dummyModule'
  IO a -> AnyContT IO a
forall a. IO a -> AnyContT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> AnyContT IO a) -> IO a -> AnyContT IO a
forall a b. (a -> b) -> a -> b
$ Ptr ExecutionEngine -> IO a
f Ptr ExecutionEngine
executionEngine

data MCJITState
  = Deferred (forall a . Module -> (Ptr FFI.ExecutionEngine -> IO a) -> IO a)
  | Constructed (Ptr FFI.ExecutionEngine)

-- | <http://llvm.org/doxygen/classllvm_1_1MCJIT.html>
-- <http://blog.llvm.org/2010/04/intro-to-llvm-mc-project.html>
-- N.B. - the LLVM MCJIT does not current support adding multiple
-- modules to any one instance of the MCJIT.
newtype MCJIT = MCJIT (IORef MCJITState)

-- | bracket the creation and destruction of an 'MCJIT'
withMCJIT :: 
  Context
  -> Maybe Word -- ^ optimization level
  -> Maybe CodeModel.Model
  -> Maybe Bool -- ^ True to disable frame pointer elimination
  -> Maybe Bool -- ^ True to enable fast instruction selection
--  -> Maybe MemoryManager -- llvm-hs doesn't support this yet
  -> (MCJIT -> IO a)
  -> IO a
withMCJIT :: forall a.
Context
-> Maybe Word
-> Maybe Model
-> Maybe Bool
-> Maybe Bool
-> (MCJIT -> IO a)
-> IO a
withMCJIT Context
c Maybe Word
opt Maybe Model
cm Maybe Bool
fpe Maybe Bool
fisel MCJIT -> IO a
f = do
  IO ()
FFI.linkInMCJIT
  let createMCJITCompilerForModule :: Ptr (Ptr ExecutionEngine)
-> Ptr Module -> Ptr (OwnerTransfered CString) -> IO CUInt
createMCJITCompilerForModule Ptr (Ptr ExecutionEngine)
e Ptr Module
m Ptr (OwnerTransfered CString)
s = do
        CSize
size <- IO CSize
FFI.getMCJITCompilerOptionsSize
        Int -> (Ptr MCJITCompilerOptions -> IO CUInt) -> IO CUInt
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes (CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
size) ((Ptr MCJITCompilerOptions -> IO CUInt) -> IO CUInt)
-> (Ptr MCJITCompilerOptions -> IO CUInt) -> IO CUInt
forall a b. (a -> b) -> a -> b
$ \Ptr MCJITCompilerOptions
p -> do
          Ptr MCJITCompilerOptions -> CSize -> IO ()
FFI.initializeMCJITCompilerOptions Ptr MCJITCompilerOptions
p CSize
size
          (Word -> IO ()) -> Maybe Word -> IO ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (Ptr MCJITCompilerOptions -> CUInt -> IO ()
FFI.setMCJITCompilerOptionsOptLevel Ptr MCJITCompilerOptions
p (CUInt -> IO ()) -> (Word -> IO CUInt) -> Word -> IO ()
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Word -> IO CUInt
forall (e :: * -> *) h c. (EncodeM e h c, HasCallStack) => h -> e c
encodeM) Maybe Word
opt
          (Model -> IO ()) -> Maybe Model -> IO ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (Ptr MCJITCompilerOptions -> CodeModel -> IO ()
FFI.setMCJITCompilerOptionsCodeModel Ptr MCJITCompilerOptions
p (CodeModel -> IO ()) -> (Model -> IO CodeModel) -> Model -> IO ()
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Model -> IO CodeModel
forall (e :: * -> *) h c. (EncodeM e h c, HasCallStack) => h -> e c
encodeM) Maybe Model
cm
          (Bool -> IO ()) -> Maybe Bool -> IO ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (Ptr MCJITCompilerOptions -> LLVMBool -> IO ()
FFI.setMCJITCompilerOptionsNoFramePointerElim Ptr MCJITCompilerOptions
p (LLVMBool -> IO ()) -> (Bool -> IO LLVMBool) -> Bool -> IO ()
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Bool -> IO LLVMBool
forall (e :: * -> *) h c. (EncodeM e h c, HasCallStack) => h -> e c
encodeM) Maybe Bool
fpe
          (Bool -> IO ()) -> Maybe Bool -> IO ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (Ptr MCJITCompilerOptions -> LLVMBool -> IO ()
FFI.setMCJITCompilerOptionsEnableFastISel Ptr MCJITCompilerOptions
p (LLVMBool -> IO ()) -> (Bool -> IO LLVMBool) -> Bool -> IO ()
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Bool -> IO LLVMBool
forall (e :: * -> *) h c. (EncodeM e h c, HasCallStack) => h -> e c
encodeM) Maybe Bool
fisel
          Ptr (Ptr ExecutionEngine)
-> Ptr Module
-> Ptr MCJITCompilerOptions
-> CSize
-> Ptr (OwnerTransfered CString)
-> IO CUInt
FFI.createMCJITCompilerForModule Ptr (Ptr ExecutionEngine)
e Ptr Module
m Ptr MCJITCompilerOptions
p CSize
size Ptr (OwnerTransfered CString)
s
  IORef MCJITState
t <- MCJITState -> IO (IORef MCJITState)
forall a. a -> IO (IORef a)
newIORef ((forall a. Module -> (Ptr ExecutionEngine -> IO a) -> IO a)
-> MCJITState
Deferred ((forall a. Module -> (Ptr ExecutionEngine -> IO a) -> IO a)
 -> MCJITState)
-> (forall a. Module -> (Ptr ExecutionEngine -> IO a) -> IO a)
-> MCJITState
forall a b. (a -> b) -> a -> b
$ \Module
mod Ptr ExecutionEngine -> IO a
f -> do Ptr Module
m' <- Module -> IO (Ptr Module)
forall (m :: * -> *). MonadIO m => Module -> m (Ptr Module)
readModule Module
mod
                                         Context
-> Maybe (Ptr Module)
-> (Ptr (Ptr ExecutionEngine)
    -> Ptr Module -> Ptr (OwnerTransfered CString) -> IO CUInt)
-> (Ptr ExecutionEngine -> IO a)
-> IO a
forall a.
Context
-> Maybe (Ptr Module)
-> (Ptr (Ptr ExecutionEngine)
    -> Ptr Module -> Ptr (OwnerTransfered CString) -> IO CUInt)
-> (Ptr ExecutionEngine -> IO a)
-> IO a
withExecutionEngine Context
c (Ptr Module -> Maybe (Ptr Module)
forall a. a -> Maybe a
Just Ptr Module
m') Ptr (Ptr ExecutionEngine)
-> Ptr Module -> Ptr (OwnerTransfered CString) -> IO CUInt
createMCJITCompilerForModule Ptr ExecutionEngine -> IO a
f)
  MCJIT -> IO a
f (IORef MCJITState -> MCJIT
MCJIT IORef MCJITState
t)

instance ExecutionEngine MCJIT (FunPtr ()) where
  withModuleInEngine :: forall a.
MCJIT -> Module -> (ExecutableModule MCJIT -> IO a) -> IO a
withModuleInEngine (MCJIT IORef MCJITState
s) Module
m ExecutableModule MCJIT -> IO a
f = do
    MCJITState
jitState <- IORef MCJITState -> IO MCJITState
forall a. IORef a -> IO a
readIORef IORef MCJITState
s
    let f' :: ExecutableModule e -> IO a
f' (ExecutableModule e
_ Ptr Module
m) = ExecutableModule MCJIT -> IO a
f (MCJIT -> Ptr Module -> ExecutableModule MCJIT
forall e. e -> Ptr Module -> ExecutableModule e
ExecutableModule (IORef MCJITState -> MCJIT
MCJIT IORef MCJITState
s) Ptr Module
m)
    case MCJITState
jitState of
      Deferred forall a. Module -> (Ptr ExecutionEngine -> IO a) -> IO a
c -> Module -> (Ptr ExecutionEngine -> IO a) -> IO a
forall a. Module -> (Ptr ExecutionEngine -> IO a) -> IO a
c Module
m ((Ptr ExecutionEngine -> IO a) -> IO a)
-> (Ptr ExecutionEngine -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \Ptr ExecutionEngine
e -> 
        IO () -> IO () -> IO a -> IO a
forall a b c. IO a -> IO b -> IO c -> IO c
bracket_ 
         (IORef MCJITState -> MCJITState -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef MCJITState
s (Ptr ExecutionEngine -> MCJITState
Constructed Ptr ExecutionEngine
e))
         (IORef MCJITState -> MCJITState -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef MCJITState
s MCJITState
jitState)
         (Ptr ExecutionEngine
-> Module
-> (ExecutableModule (Ptr ExecutionEngine) -> IO a)
-> IO a
forall a.
Ptr ExecutionEngine
-> Module
-> (ExecutableModule (Ptr ExecutionEngine) -> IO a)
-> IO a
forall e f a.
ExecutionEngine e f =>
e -> Module -> (ExecutableModule e -> IO a) -> IO a
withModuleInEngine Ptr ExecutionEngine
e Module
m ExecutableModule (Ptr ExecutionEngine) -> IO a
forall {e}. ExecutableModule e -> IO a
f')
      Constructed Ptr ExecutionEngine
e -> Ptr ExecutionEngine
-> Module
-> (ExecutableModule (Ptr ExecutionEngine) -> IO a)
-> IO a
forall a.
Ptr ExecutionEngine
-> Module
-> (ExecutableModule (Ptr ExecutionEngine) -> IO a)
-> IO a
forall e f a.
ExecutionEngine e f =>
e -> Module -> (ExecutableModule e -> IO a) -> IO a
withModuleInEngine Ptr ExecutionEngine
e Module
m ExecutableModule (Ptr ExecutionEngine) -> IO a
forall {e}. ExecutableModule e -> IO a
f'

  getFunction :: HasCallStack =>
ExecutableModule MCJIT -> Name -> IO (Maybe (FunPtr ()))
getFunction (ExecutableModule (MCJIT IORef MCJITState
r) Ptr Module
m) Name
n = do
    MCJITState
s <- IO MCJITState -> IO MCJITState
forall a. IO a -> IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO MCJITState -> IO MCJITState) -> IO MCJITState -> IO MCJITState
forall a b. (a -> b) -> a -> b
$ IORef MCJITState -> IO MCJITState
forall a. IORef a -> IO a
readIORef IORef MCJITState
r
    case MCJITState
s of
      Deferred forall a. Module -> (Ptr ExecutionEngine -> IO a) -> IO a
_ -> Maybe (FunPtr ()) -> IO (Maybe (FunPtr ()))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (FunPtr ())
forall a. Maybe a
Nothing
      Constructed Ptr ExecutionEngine
e -> ExecutableModule (Ptr ExecutionEngine)
-> Name -> IO (Maybe (FunPtr ()))
forall e f.
(ExecutionEngine e f, HasCallStack) =>
ExecutableModule e -> Name -> IO (Maybe f)
getFunction (Ptr ExecutionEngine
-> Ptr Module -> ExecutableModule (Ptr ExecutionEngine)
forall e. e -> Ptr Module -> ExecutableModule e
ExecutableModule Ptr ExecutionEngine
e Ptr Module
m) Name
n