55-- https://developers.google.com/open-source/licenses/bsd
66
77{-# LANGUAGE RecordWildCards #-}
8+ {-# LANGUAGE FlexibleInstances #-}
89{-# OPTIONS_GHC -Wno-orphans #-}
910
1011module Dex.Foreign.JIT (
11- JIT , NativeFunction , ExportedSignature ,
12+ JIT , NativeFunction , ClosedExportedSignature ,
1213 dexCreateJIT , dexDestroyJIT ,
1314 dexGetFunctionSignature , dexFreeFunctionSignature ,
1415 dexCompile , dexUnload
@@ -32,96 +33,95 @@ import qualified LLVM.CodeGenOpt as CGO
3233import qualified LLVM.JIT
3334import qualified LLVM.Shims
3435
36+ import Name
3537import Logging
38+ import Builder
3639import LLVMExec
3740import TopLevel
3841import JIT
42+ import Export
3943import Syntax hiding (sizeOf )
4044
4145import Dex.Foreign.Util
4246import Dex.Foreign.Context
4347
44- -- TODO: Update Export to safer names
45- -- import Export
46- newtype ExportedSignature = ExportedSignature ()
47- exportedSignatureDesc :: ExportedSignature -> (String , String , String )
48- exportedSignatureDesc = undefined
49-
48+ type ClosedExportedSignature = ExportedSignature 'VoidS
5049data NativeFunction =
5150 NativeFunction { nativeModule :: LLVM.JIT. NativeModule
52- , nativeSignature :: ExportedSignature }
51+ , nativeSignature :: ExportedSignature 'VoidS }
5352type NativeFunctionAddr = Ptr NativeFunction
5453
5554data JIT = ForeignJIT { jit :: LLVM.JIT. JIT
5655 , jitTargetMachine :: TargetMachine
5756 , addrTableRef :: IORef (M. Map NativeFunctionAddr NativeFunction )
5857 }
5958
60- instance Storable ExportedSignature where
59+ instance Storable ( ExportedSignature 'VoidS) where
6160 sizeOf _ = 3 * sizeOf (undefined :: Ptr () )
6261 alignment _ = alignment (undefined :: Ptr () )
6362 peek _ = error " peek not implemented for ExportedSignature"
6463 poke addr sig = do
65- let strAddr = castPtr @ ExportedSignature @ CString addr
64+ let strAddr = castPtr @ ( ExportedSignature 'VoidS) @ CString addr
6665 let (arg, res, ccall) = exportedSignatureDesc sig
6766 pokeElemOff strAddr 0 =<< newCString arg
6867 pokeElemOff strAddr 1 =<< newCString res
6968 pokeElemOff strAddr 2 =<< newCString ccall
7069
7170dexCreateJIT :: IO (Ptr JIT )
7271dexCreateJIT = do
73- setError " currently disabled" $> nullPtr
74- -- jitTargetMachine <- LLVM.Shims.newHostTargetMachine R.PIC CM.Large CGO.Aggressive
75- -- jit <- LLVM.JIT.createJIT jitTargetMachine
76- -- addrTableRef <- newIORef mempty
77- -- toStablePtr ForeignJIT{..}
72+ jitTargetMachine <- LLVM.Shims. newHostTargetMachine R. PIC CM. Large CGO. Aggressive
73+ jit <- LLVM.JIT. createJIT jitTargetMachine
74+ addrTableRef <- newIORef mempty
75+ toStablePtr ForeignJIT {.. }
7876
7977dexDestroyJIT :: Ptr JIT -> IO ()
8078dexDestroyJIT jitPtr = do
81- return ()
82- -- ForeignJIT{..} <- fromStablePtr jitPtr
83- -- addrTable <- readIORef addrTableRef
84- -- forM_ (M.toList addrTable) $ \(_, m) -> LLVM.JIT.unloadNativeModule $ nativeModule m
85- -- LLVM.JIT.destroyJIT jit
86- -- LLVM.Shims.disposeTargetMachine jitTargetMachine
79+ ForeignJIT {.. } <- fromStablePtr jitPtr
80+ addrTable <- readIORef addrTableRef
81+ forM_ (M. toList addrTable) $ \ (_, m) -> LLVM.JIT. unloadNativeModule $ nativeModule m
82+ LLVM.JIT. destroyJIT jit
83+ LLVM.Shims. disposeTargetMachine jitTargetMachine
8784
8885dexCompile :: Ptr JIT -> Ptr Context -> Ptr AtomEx -> IO NativeFunctionAddr
89- dexCompile jitPtr ctxPtr funcAtomPtr = do
90- setError " currently disabled" $> nullPtr
91- -- ForeignJIT{..} <- fromStablePtr jitPtr
92- -- Context _ (TopStateEx env) <- fromStablePtr ctxPtr
93- -- funcAtom <- fromStablePtr funcAtomPtr
94- -- let (impMod, nativeSignature) = prepareFunctionForExport
95- -- (topBindings $ topStateD env) "userFunc" funcAtom
96- -- nativeModule <- execLogger Nothing $ \logger -> do
97- -- llvmAST <- impToLLVM logger impMod
98- -- LLVM.JIT.compileModule jit llvmAST
99- -- (standardCompilationPipeline logger ["userFunc"] jitTargetMachine)
100- -- funcPtr <- castFunPtrToPtr <$> LLVM.JIT.getFunctionPtr nativeModule "userFunc"
101- -- modifyIORef addrTableRef $ M.insert funcPtr NativeFunction{..}
102- -- return $ funcPtr
103-
104- dexGetFunctionSignature :: Ptr JIT -> NativeFunctionAddr -> IO (Ptr ExportedSignature )
86+ dexCompile jitPtr ctxPtr funcAtomPtr = catchErrors $ do
87+ ForeignJIT {.. } <- fromStablePtr jitPtr
88+ Context evalConfig initEnv <- fromStablePtr ctxPtr
89+ AtomEx funcAtom <- fromStablePtr funcAtomPtr
90+ fst <$> runTopperM evalConfig initEnv do
91+ -- TODO: Check if atom is compatible with context! Use module name?
92+ (impFunc, nativeSignature) <- prepareFunctionForExport (unsafeCoerceE funcAtom)
93+ (_, llvmAST) <- impToLLVM " userFunc" impFunc
94+ logger <- getLogger
95+ objFileNames <- getAllRequiredObjectFiles
96+ objFiles <- forM objFileNames \ objFileName -> do
97+ ObjectFileBinding (ObjectFile bytes _ _) <- lookupEnv objFileName
98+ return bytes
99+ liftIO do
100+ nativeModule <- LLVM.JIT. compileModule jit objFiles llvmAST
101+ (standardCompilationPipeline logger [" userFunc" ] jitTargetMachine)
102+ funcPtr <- castFunPtrToPtr <$> LLVM.JIT. getFunctionPtr nativeModule " userFunc"
103+ modifyIORef addrTableRef $ M. insert funcPtr NativeFunction {.. }
104+ return $ funcPtr
105+
106+ dexGetFunctionSignature :: Ptr JIT -> NativeFunctionAddr -> IO (Ptr (ExportedSignature 'VoidS))
105107dexGetFunctionSignature jitPtr funcPtr = do
106- setError " currently disabled" $> nullPtr
107- -- ForeignJIT{..} <- fromStablePtr jitPtr
108- -- addrTable <- readIORef addrTableRef
109- -- case M.lookup funcPtr addrTable of
110- -- Nothing -> setError "Invalid function address" $> nullPtr
111- -- Just NativeFunction{..} -> putOnHeap nativeSignature
112-
113- dexFreeFunctionSignature :: Ptr ExportedSignature -> IO ()
108+ ForeignJIT {.. } <- fromStablePtr jitPtr
109+ addrTable <- readIORef addrTableRef
110+ case M. lookup funcPtr addrTable of
111+ Nothing -> setError " Invalid function address" $> nullPtr
112+ Just NativeFunction {.. } -> putOnHeap nativeSignature
113+
114+ dexFreeFunctionSignature :: Ptr (ExportedSignature 'VoidS) -> IO ()
114115dexFreeFunctionSignature sigPtr = do
115- let strPtr = castPtr @ ExportedSignature @ CString sigPtr
116+ let strPtr = castPtr @ ( ExportedSignature 'VoidS) @ CString sigPtr
116117 free =<< peekElemOff strPtr 0
117118 free =<< peekElemOff strPtr 1
118119 free =<< peekElemOff strPtr 2
119120 free sigPtr
120121
121122dexUnload :: Ptr JIT -> NativeFunctionAddr -> IO ()
122123dexUnload jitPtr funcPtr = do
123- return ()
124- -- ForeignJIT{..} <- fromStablePtr jitPtr
125- -- addrTable <- readIORef addrTableRef
126- -- LLVM.JIT.unloadNativeModule $ nativeModule $ addrTable M.! funcPtr
127- -- modifyIORef addrTableRef $ M.delete funcPtr
124+ ForeignJIT {.. } <- fromStablePtr jitPtr
125+ addrTable <- readIORef addrTableRef
126+ LLVM.JIT. unloadNativeModule $ nativeModule $ addrTable M. ! funcPtr
127+ modifyIORef addrTableRef $ M. delete funcPtr
0 commit comments