on master help sign in
Find foreign funcs in libs
commit054c04e88ff1166fa8cc186b3447371a204363dd authorDavid Christiansen <david@davidchristiansen.dk> dateFri 15 Mar 2013, 17:16 (14 years ago) parent3a80954
2 files changed+39−7
src/Core/Execute.hs+28−5 src/Util/DynamicLinker.hs+11−2
src/Core/Execute.hs+28−5
@@ -10,6 +10,10 @@ import Debug.Trace
1010
1111import Util.DynamicLinker
1212
13+import Control.Monad.Trans
14+import Control.Monad
15+import Data.Maybe
16+
1317
1418-- | Attempt to perform a side effect. Return either Just the next step in
1519-- evaluation (after performing the side effect through IO), or Nothing if no
@@ -41,8 +45,7 @@ call (FFun name argTypes retType) args = undefined
4145foreignFromTT :: TT Name -> Maybe Foreign
4246foreignFromTT t = case (unApply t) of
4347 (_, [(Constant (Str name)), args, ret]) ->
44− do trace (show $ unList args) $ return ()
45− argTy <- unList args
48+ do argTy <- unList args
4649 argFTy <- sequence $ map getFTy argTy
4750 retFTy <- getFTy ret
4851 return $ FFun name argFTy retFTy
@@ -67,9 +70,29 @@ unList tm = case unApply tm of
6770 return $ x:rest
6871 (f, args) -> Nothing
6972
73+toConst :: TT Name -> Maybe Const
74+toConst (Constant c) = Just c
75+toConst _ = Nothing
76+
7077stepForeign :: [TT Name] -> Idris (TT Name)
71−stepForeign (ty:fn:args) = do iputStrLn $ "FOREIGN CALL " ++ show (ty:fn:args)
72− iputStrLn $ show $ foreignFromTT fn
78+stepForeign (ty:fn:args) = do iputStrLn $ show $ foreignFromTT fn
79+ iputStrLn $ show $ sequence $ map toConst args
7380 iputStrLn ""
7481 return $ mkApp (P Bound (UN "mkForeign") Erased) args
75−stepForeign _ = fail "Tried to call foreign function that wasn't mkForeign"
82+stepForeign _ = fail "Tried to call foreign function that wasn't mkForeign"
83+
84+mapMaybeM :: Monad m => (a -> m (Maybe b)) -> [a] -> m [b]
85+mapMaybeM f [] = return []
86+mapMaybeM f (x:xs) = do rest <- mapMaybeM f xs
87+ x' <- f x
88+ case x' of
89+ Just x'' -> return (x'':rest)
90+ Nothing -> return rest
91+
92+findForeign :: String -> Idris (Maybe ForeignFun)
93+findForeign fn = do i <- getIState
94+ let libs = idris_dynamic_libs i
95+ fns <- mapMaybeM (lift . tryLoadFn fn) libs
96+ case fns of
97+ [f] -> return (Just f)
98+ _ -> return Nothing
src/Util/DynamicLinker.hs+11−2
@@ -1,10 +1,10 @@
11-- | Platform-specific dynamic linking support. Add new platforms to this file
22-- through conditional compilation.
3−
3+{-# LANGUAGE ExistentialQuantification #-}
44module Util.DynamicLinker where
55
66import Foreign.LibFFI
7−import Foreign.Ptr (nullPtr)
7+import Foreign.Ptr (nullPtr, FunPtr, nullFunPtr)
88import System.Posix.DynamicLinker
99
1010data DynamicLib = Lib { lib_name :: String
@@ -17,3 +17,12 @@ tryLoadLib lib = do handle <- dlopen lib [RTLD_NOW]
1717 then return Nothing
1818 else return . Just $ Lib lib handle
1919
20+data ForeignFun = forall a. Fun { fun_name :: String
21+ , fun_handle :: FunPtr a
22+ }
23+
24+tryLoadFn :: String -> DynamicLib -> IO (Maybe ForeignFun)
25+tryLoadFn fn (Lib _ h) = do cFn <- dlsym h fn
26+ if cFn == nullFunPtr
27+ then return Nothing
28+ else return . Just $ Fun fn cFn