accelerate-llvm-native-1.4.0.0: src/Data/Array/Accelerate/LLVM/Native/Link/Runtime.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}
-- |
-- Module : Data.Array.Accelerate.LLVM.Native.Link.Runtime
-- Copyright : [2022] The Accelerate Team
-- License : BSD3
--
-- Maintainer : Trevor L. McDonell <trevor.mcdonell@gmail.com>
-- Stability : experimental
-- Portability : non-portable (GHC extensions)
--
-- Utilities for linking object code to shared objects and loading those
-- generated shared objects on Unix-like systems.
--
module Data.Array.Accelerate.LLVM.Native.Link.Runtime (
loadSharedObject
) where
import Data.Array.Accelerate.Error
import Data.Array.Accelerate.Lifetime
import Data.Array.Accelerate.LLVM.Native.Link.Object
import qualified Data.Array.Accelerate.LLVM.Native.Debug as Debug
import Control.Monad
import Data.ByteString.Short.Char8 ( ShortByteString )
import Formatting
import qualified Data.ByteString.Short.Char8 as B8
#if defined(mingw32_HOST_OS)
import Foreign.Ptr ( castPtrToFunPtr )
import System.Win32.DLL
#else
import System.Posix.DynamicLinker
#endif
-- Dynamic object loading
-- ----------------------
-- Load the shared object file and return pointers to the executable
-- functions defined within
--
loadSharedObject :: HasCallStack => [ShortByteString] -> FilePath -> IO (FunctionTable, ObjectCode)
loadSharedObject nms path = do
#if defined(mingw32_HOST_OS)
-- shims for win32 api compatibility
let dlopen' path' = loadLibrary path'
dlsym dll sym = castPtrToFunPtr <$> getProcAddress dll sym
dlclose dll = freeLibrary dll
#else
let dlopen' path' = dlopen path' [RTLD_LAZY, RTLD_LOCAL]
#endif
--
so <- dlopen' path
fun_tab <- fmap FunctionTable $ forM nms $ \nm -> do
let s = B8.unpack nm
Debug.traceM Debug.dump_ld ("ld: looking up symbol " % string) s
sym <- dlsym so s
return (nm, sym)
object_code <- newLifetime so
addFinalizer object_code $ do
-- XXX: Should we disable unloading objects in tracy mode? Tracy might
-- still need access to e.g. embedded string data
Debug.traceM Debug.dump_gc ("gc: unload module: " % formatFunctionTable) fun_tab
dlclose so
return (fun_tab, object_code)