Importing a known function from an already-compiled binary, using GHC's API or Hint

后端 未结 2 1802
梦如初夏
梦如初夏 2021-01-06 02:10

I have a module Target, with a function Target.accessMe inside it. I compile this module in some way, then get rid of the source code.

Now,

相关标签:
2条回答
  • 2021-01-06 02:37

    The answer to this question has been given to me elsewhere. The GHC API is capable of doing this. Here are two functions, one of which compiles Target.hs, while the other accesses Target.accessMe (and doesn't require the source code of the Target module to be there anymore).

    import GHC
    import DynFlags
    
    compile :: String -> IO SuccessFlag
    compile name = defaultRunGhc $ do
      dynflags <- getSessionDynFlags
      let dynflags' = dynflags -- You can change various options here.
      setSessionDynFlags dynflags'
    
      -- (name) can be "Target.hs", "Target", etc.
      target <- guessTarget name Nothing
      addTarget target
      load LoadAllTargets -- Runs something like "ghc --make".
    

    That's a function that compiles a given module and returns whether compilation succeeded or not. It uses a defaultRunGhc helper function that is defined as:

    import GHC.Paths (libdir)
    
    defaultRunGhc :: Ghc a -> IO a
    defaultRunGhc = defaultErrorHandler defaultDynFlags . runGhc (Just libdir)
    

    And now a function for fetching a value from the compiled module. The module's source code need not be present at this point.

    import Unsafe.Coerce (unsafeCoerce)
    
    fetch :: String -> String -> IO Int -- Assumes we are fetching an Int value.
    fetch name value = defaultRunGhc $ do
      -- Again, you can change various options in dynflags here, as above.
      dynflags <- getSessionDynFlags
      let m = mkModule (thisPackage dynflags) (mkModuleName name)
      setContext [] [(m, Nothing)] -- Use setContext [] [m] for GHC<7.
    
      fetched <- compileExpr (name ++ "." ++ value) -- Fetching "Target.accessMe".
      return (unsafeCoerce fetched :: Int)
    

    And that's it!

    0 讨论(0)
  • 2021-01-06 02:51

    The plugins package is problematic anyway. You might want to look at Hint instead.

    0 讨论(0)
提交回复
热议问题