import Data.String
import qualified Data.Map as Map
import qualified Data.Text.Lazy.IO as Text
+import Foreign.Ptr
import LLVM.AST.AddrSpace
import LLVM.AST.Constant
import LLVM.AST.Float
import LLVM.Context
import LLVM.IRBuilder
import LLVM.Module
+import LLVM.OrcJIT
+import LLVM.OrcJIT.CompileLayer
import LLVM.PassManager
import LLVM.Pretty
import LLVM.Target
import System.IO.Error
import Text.Read (readMaybe)
+foreign import ccall "dynamic" mkFun :: FunPtr (IO Double) -> IO Double
+
+data JITEnv = JITEnv
+ { jitEnvContext :: Context
+ , jitEnvCompileLayer :: IRCompileLayer ObjectLinkingLayer
+ , jitEnvModuleKey :: ModuleKey
+ }
+
main :: IO ()
main = do
withContext $ \ctx -> withHostTargetMachine $ \tm -> do
- ast <- runReaderT (buildModuleT "main" repl) ctx
+ withExecutionSession $ \exSession ->
+ withSymbolResolver exSession (SymbolResolver symResolver) $ \symResolverPtr ->
+ withObjectLinkingLayer exSession (const $ pure symResolverPtr) $ \linkingLayer ->
+ withIRCompileLayer linkingLayer tm $ \compLayer -> do
+ withModuleKey exSession $ \mdlKey -> do
+ let env = JITEnv ctx compLayer mdlKey
+ ast <- runReaderT (buildModuleT "main" repl) env
return ()
-repl :: ModuleBuilderT (ReaderT Context IO) ()
+-- This can eventually be used to resolve external functions, e.g. a stdlib call
+symResolver :: MangledSymbol -> IO (Either JITSymbolError JITSymbol)
+symResolver sym = undefined
+
+repl :: ModuleBuilderT (ReaderT JITEnv IO) ()
repl = do
liftIO $ hPutStr stderr "ready> "
mline <- liftIO $ catchIOError (Just <$> getLine) eofHandler
def <- mostRecentDef
ast <- moduleSoFar "main"
- ctx <- lift ask
+ ctx <- lift $ asks jitEnvContext
+ env <- lift ask
liftIO $ withModuleFromAST ctx ast $ \mdl -> do
Text.hPutStrLn stderr $ ppll def
let spec = defaultCuratedPassSetSpec { optLevel = Just 3 }
-- this returns true if the module was modified
withPassManager spec $ flip runPassManager mdl
- Text.hPutStrLn stderr . ("\n" <>) . ppllvm =<< moduleAST mdl
- when anon (jit mdl >>= hPrint stderr)
+ when anon (jit env mdl >>= hPrint stderr)
when anon (removeDef def)
repl
isAnonExpr (ConstantOperand (GlobalReference _ "__anon_expr")) = True
isAnonExpr _ = False
-jit :: Module -> IO Double
-jit _mdl = putStrLn "Working on it!" >> return 0
+jit :: JITEnv -> Module -> IO Double
+jit JITEnv{jitEnvCompileLayer=compLayer, jitEnvModuleKey=mdlKey} mdl =
+ withModule compLayer mdlKey mdl $ do
+ mangled <- mangleSymbol compLayer "__anon_expr"
+ Right (JITSymbol fPtr _) <- findSymbolIn compLayer mdlKey mangled False
+ mkFun (castPtrToFunPtr (wordPtrToPtr fPtr))
type Binds = Map.Map String Operand