1- {-# LANGUAGE ForeignFunctionInterface, FlexibleInstances, UndecidableInstances, OverlappingInstances, ScopedTypeVariables, GeneralizedNewtypeDeriving, DeriveDataTypeable #-}
1+ {-# LANGUAGE ForeignFunctionInterface, FlexibleInstances, UndecidableInstances, OverlappingInstances, ScopedTypeVariables, GeneralizedNewtypeDeriving #-}
22module LLVM.ExecutionEngine.Engine (
3- EngineAccess ,
4- runEngineAccess ,
5- {-
63 ExecutionEngine ,
7- -}
8- createExecutionEngine , addModule , removeModule ,
9- {- runStaticConstructors, runStaticDestructors, -}
4+ createExecutionEngine , destroyExecutionEngine , touchExecutionEngine ,
5+ addModule , removeModule ,
6+ runStaticConstructors , runStaticDestructors ,
107 getExecutionEngineTargetData ,
118 getPointerToFunction ,
129 addFunctionValue , addGlobalMappings ,
@@ -16,14 +13,11 @@ module LLVM.ExecutionEngine.Engine(
1613 GenericValue , Generic (.. )
1714 ) where
1815import Control.Monad.State
19- import Control.Applicative (Applicative , )
20- import Control.Concurrent.MVar
21- import Data.Typeable
2216import Data.Int
2317import Data.Word
2418import Foreign.Marshal.Alloc (alloca , free )
2519import Foreign.Marshal.Array (withArrayLen )
26- import Foreign.ForeignPtr (ForeignPtr , newForeignPtr , withForeignPtr )
20+ import Foreign.ForeignPtr (ForeignPtr , finalizeForeignPtr , newForeignPtr , touchForeignPtr , withForeignPtr )
2721import Foreign.Marshal.Utils (fromBool )
2822import Foreign.C.String (peekCString )
2923import Foreign.Ptr (Ptr , FunPtr , castFunPtrToPtr )
@@ -33,14 +27,13 @@ import Foreign.Storable (peek)
3327import Foreign.StablePtr (StablePtr , castStablePtrToPtr , castPtrToStablePtr , )
3428import System.IO.Unsafe (unsafePerformIO )
3529
36- import LLVM.Core.Util (Module , createModule )
30+ import LLVM.Core.Util (Module )
3731import qualified LLVM.FFI.ExecutionEngine as FFI
3832import qualified LLVM.FFI.Target as FFI
3933import qualified LLVM.FFI.Core as FFI (ValueRef )
4034import qualified LLVM.Core.Util as U
4135import LLVM.Core.Type (IsFirstClass , typeRef )
4236
43- {-
4437-- | The type of the JITer.
4538newtype ExecutionEngine = ExecutionEngine {
4639 fromExecutionEngine :: ForeignPtr FFI. ExecutionEngine
@@ -52,20 +45,26 @@ withExecutionEngine = withForeignPtr . fromExecutionEngine
5245
5346-- | Create an execution engine for a module provider.
5447-- Warning, do not call this function more than once.
55- createExecutionEngine :: ModuleProvider -> IO ExecutionEngine
56- createExecutionEngine prov =
57- withModuleProvider prov $ \provPtr ->
48+ createExecutionEngine :: Module -> IO ExecutionEngine
49+ createExecutionEngine m =
50+ U. withModule m $ \ mPtr ->
5851 alloca $ \ eePtr ->
5952 alloca $ \ errPtr -> do
60- ret <- FFI.createExecutionEngine eePtr provPtr errPtr
61- if ret == 1
53+ ret <- FFI. createExecutionEngineForModule eePtr mPtr errPtr
54+ if ret
6255 then do err <- peek errPtr
6356 errStr <- peekCString err
6457 free err
6558 ioError . userError $ errStr
6659 else do ptr <- peek eePtr
6760 liftM ExecutionEngine $ newForeignPtr FFI. ptrDisposeExecutionEngine ptr
6861
62+ destroyExecutionEngine :: ExecutionEngine -> IO ()
63+ destroyExecutionEngine = finalizeForeignPtr . fromExecutionEngine
64+
65+ touchExecutionEngine :: ExecutionEngine -> IO ()
66+ touchExecutionEngine = touchForeignPtr . fromExecutionEngine
67+
6968runStaticConstructors :: ExecutionEngine -> IO ()
7069runStaticConstructors ee = withExecutionEngine ee FFI. runStaticConstructors
7170
@@ -75,70 +74,6 @@ runStaticDestructors ee = withExecutionEngine ee FFI.runStaticDestructors
7574getExecutionEngineTargetData :: ExecutionEngine -> IO FFI. TargetDataRef
7675getExecutionEngineTargetData ee = withExecutionEngine ee FFI. getExecutionEngineTargetData
7776
78- getPointerToFunction :: ExecutionEngine -> Function f -> IO (FunPtr f)
79- getPointerToFunction ee (Value f) =
80- withExecutionEngine ee $ \ eePtr ->
81- FFI.getPointerToGlobal eePtr f
82- -}
83-
84- -- This global variable holds the one and only execution engine.
85- -- It may be missing, but it never dies.
86- -- XXX We could provide a destructor, what about functions obtained by runFunction?
87- {-# NOINLINE theEngine #-}
88- theEngine :: MVar (Maybe (Ptr FFI. ExecutionEngine ))
89- theEngine = unsafePerformIO $ newMVar Nothing
90-
91- createExecutionEngine :: Module -> IO (Ptr FFI. ExecutionEngine )
92- createExecutionEngine m =
93- U. withModule m $ \ mPtr ->
94- alloca $ \ eePtr ->
95- alloca $ \ errPtr -> do
96- failed <- FFI. createJITCompilerForModule eePtr mPtr 2 errPtr
97- if failed
98- then do
99- err <- peek errPtr
100- errStr <- peekCString err
101- free err
102- ioError . userError $ errStr
103- else
104- peek eePtr
105-
106- getTheEngine :: IO (Ptr FFI. ExecutionEngine )
107- getTheEngine = do
108- mee <- takeMVar theEngine
109- case mee of
110- Just ee -> do putMVar theEngine mee; return ee
111- Nothing -> do
112- m <- createModule " __empty__"
113- ee <- createExecutionEngine m
114- putMVar theEngine (Just ee)
115- return ee
116-
117- data EAState = EAState {
118- ea_engine :: Ptr FFI. ExecutionEngine ,
119- ea_modules :: [Module ]
120- }
121- deriving (Show , Typeable )
122-
123- newtype EngineAccess a = EA (StateT EAState IO a )
124- deriving (Functor , Applicative , Monad , MonadState EAState , MonadIO )
125-
126- -- | The LLVM execution engine is encapsulated so it cannot be accessed directly.
127- -- The reason is that (currently) there must only ever be one engine,
128- -- so access to it is wrapped in a monad.
129- runEngineAccess :: EngineAccess a -> IO a
130- runEngineAccess (EA body) = do
131- eePtr <- getTheEngine
132- let ea = EAState { ea_engine = eePtr, ea_modules = [] }
133- (a, _ea') <- runStateT body ea
134- -- XXX should remove module providers again
135- return a
136-
137- getExecutionEngineTargetData :: EngineAccess FFI. TargetDataRef
138- getExecutionEngineTargetData = do
139- eePtr <- gets ea_engine
140- liftIO $ FFI. getExecutionEngineTargetData eePtr
141-
14277{- |
14378In contrast to 'generateFunction' this compiles a function once.
14479Thus it is faster for many calls to the same function.
@@ -148,43 +83,40 @@ If the function calls back into Haskell code,
14883you also have to set the function addresses
14984using 'addFunctionValue' or 'addGlobalMappings'.
15085-}
151- getPointerToFunction :: Function f -> EngineAccess (FunPtr f )
152- getPointerToFunction (Value f) = do
153- eePtr <- gets ea_engine
154- liftIO $ FFI. getPointerToGlobal eePtr f
86+ getPointerToFunction :: ExecutionEngine -> Function f -> IO (FunPtr f )
87+ getPointerToFunction ee (Value f) =
88+ withExecutionEngine ee $ \ eePtr ->
89+ FFI. getPointerToGlobal eePtr f
15590
15691{- |
15792Tell LLVM the address of an external function
15893if it cannot resolve a name automatically.
15994Alternatively you may declare the function
16095with 'staticFunction' instead of 'externFunction'.
16196-}
162- addFunctionValue :: Function f -> FunPtr f -> EngineAccess ()
163- addFunctionValue (Value g) f =
164- addFunctionValueCore g (castFunPtrToPtr f)
97+ addFunctionValue :: ExecutionEngine -> Function f -> FunPtr f -> IO ()
98+ addFunctionValue ee (Value g) f =
99+ addFunctionValueCore ee g (castFunPtrToPtr f)
165100
166101{- |
167102Pass a list of global mappings to LLVM
168103that can be obtained from 'LLVM.Core.getGlobalMappings'.
169104-}
170- addGlobalMappings :: GlobalMappings -> EngineAccess ()
171- addGlobalMappings (GlobalMappings gms) =
172- mapM_ (uncurry addFunctionValueCore) gms
173-
174- addFunctionValueCore :: U. Function -> Ptr () -> EngineAccess ()
175- addFunctionValueCore g f = do
176- eePtr <- gets ea_engine
177- liftIO $ FFI. addGlobalMapping eePtr g f
178-
179- addModule :: Module -> EngineAccess ()
180- addModule m = do
181- eePtr <- gets ea_engine
105+ addGlobalMappings :: ExecutionEngine -> GlobalMappings -> IO ()
106+ addGlobalMappings ee (GlobalMappings gms) =
107+ mapM_ (uncurry (addFunctionValueCore ee)) gms
108+
109+ addFunctionValueCore :: ExecutionEngine -> U. Function -> Ptr () -> IO ()
110+ addFunctionValueCore ee g f = withExecutionEngine ee $ \ eePtr ->
111+ FFI. addGlobalMapping eePtr g f
112+
113+ addModule :: ExecutionEngine -> Module -> IO ()
114+ addModule ee m = withExecutionEngine ee $ \ eePtr ->
182115 liftIO $ U. withModule m $ \ mPtr -> do
183116 FFI. addModule eePtr mPtr
184117
185- removeModule :: Module -> EngineAccess ()
186- removeModule m = do
187- eePtr <- gets ea_engine
118+ removeModule :: ExecutionEngine -> Module -> IO ()
119+ removeModule ee m = withExecutionEngine ee $ \ eePtr ->
188120 liftIO $ U. withModule m $ \ mPtr ->
189121 alloca $ \ unused1 ->
190122 alloca $ \ unused2 -> do
@@ -195,10 +127,9 @@ removeModule m = do
195127-- Freeing code might have to be done from a (C) finalizer, so it has to done from C.
196128-- The function c_freeFunctionObject take these pointers as arguments and frees the function.
197129type FreePointers = (Ptr FFI. ExecutionEngine , FFI. ValueRef )
198- getFreePointers :: Function f -> EngineAccess FreePointers
199- getFreePointers (Value f) = do
200- ea <- get
201- return (ea_engine ea, f)
130+ getFreePointers :: ExecutionEngine -> Function f -> IO FreePointers
131+ getFreePointers ee (Value f) = withExecutionEngine ee $ \ eePtr ->
132+ return (eePtr, f)
202133
203134foreign import ccall c_freeFunctionObject :: Ptr FFI. ExecutionEngine -> FFI. ValueRef -> IO ()
204135
@@ -221,15 +152,13 @@ withAll ps a = go [] ps
221152 where go ptrs (x: xs) = withGenericValue x $ \ ptr -> go (ptr: ptrs) xs
222153 go ptrs _ = withArrayLen (reverse ptrs) a
223154
224- runFunction :: U. Function -> [GenericValue ] -> EngineAccess GenericValue
225- runFunction func args = do
226- eePtr <- gets ea_engine
227- liftIO $ withAll args $ \ argLen argPtr ->
228- createGenericValueWith $ FFI. runFunction eePtr func
155+ runFunction :: ExecutionEngine -> U. Function -> [GenericValue ] -> IO GenericValue
156+ runFunction ee func args = withExecutionEngine ee $ \ eePtr ->
157+ withAll args $ \ argLen argPtr ->
158+ createGenericValueWith $ FFI. runFunction eePtr func
229159 (fromIntegral argLen) argPtr
230- getRunFunction :: EngineAccess (U. Function -> [GenericValue ] -> IO GenericValue )
231- getRunFunction = do
232- eePtr <- gets ea_engine
160+ getRunFunction :: ExecutionEngine -> IO (U. Function -> [GenericValue ] -> IO GenericValue )
161+ getRunFunction ee = withExecutionEngine ee $ \ eePtr -> do
233162 return $ \ func args ->
234163 withAll args $ \ argLen argPtr ->
235164 createGenericValueWith $ FFI. runFunction eePtr func
0 commit comments