A haskell IRC bot because who doesn't need one
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

53 lignes
1.5KB

  1. {-# LANGUAGE MagicHash #-}
  2. {-# LANGUAGE UnboxedTuples #-}
  3. module IRC.Plugins.Loader ( load ) where
  4. import qualified Data.HashMap.Lazy as M
  5. import IRC.Plugins.Plugin
  6. import Control.Exception ( catch, ErrorCall )
  7. import GHC.Exts ( addrToAny# )
  8. import GHC.Ptr ( Ptr(..) )
  9. import System.Info ( os, arch )
  10. import GHCi.ObjLink
  11. import Encoding
  12. load :: PluginSet -> String -> IO (Either String PluginSet)
  13. load set path = do
  14. initObjLinker RetainCAFs
  15. loadObj "Plugin.o"
  16. _ret <- resolveObjs
  17. ptr <- lookupSymbol (mangleSymbol Nothing "Plugin" "f")
  18. case ptr of
  19. Nothing -> return $ Left "Couldn’t load symbol"
  20. Just (Ptr addr) -> case addrToAny# addr of
  21. (# f #) -> return $ Right f
  22. unload :: PluginSet -> String -> IO PluginSet
  23. unload set plugin = catch unloadPlugin exceptionHandler
  24. where exceptionHandler :: ErrorCall -> IO PluginSet
  25. exceptionHandler _ = return set
  26. unloadPlugin :: IO PluginSet
  27. unloadPlugin = do
  28. unloadObj $ plugin <> ".o"
  29. return $ M.delete plugin set
  30. mangleSymbol :: Maybe String -> String -> String -> String
  31. mangleSymbol pkg module' valsym =
  32. prefixUnderscore <>
  33. maybe "" (\p -> zEncodeString p <> "_") pkg <>
  34. zEncodeString module' <> "_" <> zEncodeString valsym <> "_closure"
  35. prefixUnderscore :: String
  36. prefixUnderscore =
  37. case (os,arch) of
  38. ("mingw32","x86_64") -> ""
  39. ("cygwin","x86_64") -> ""
  40. ("mingw32",_) -> "_"
  41. ("darwin",_) -> "_"
  42. ("cygwin",_) -> "_"
  43. _ -> ""