How to execute a function loaded via GHCI.ObjLink?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

How to execute a function loaded via GHCI.ObjLink?

Saurabh Nanda
Hi,

I'm playing around with https://www.stackage.org/haddock/lts-9.0/ghci-8.0.2/GHCi-ObjLink.html to see if I can come up with some sort of hot-loading/plugin system in Haskell. 

I've managed to load a shared object (compiled from a Haskell source via -rdynamic) with the following code:

    {-# LANGUAGE OverloadedStrings #-}
    {-# LANGUAGE MagicHash, UnboxedTuples #-}
    
    module Main where
    
    import GHC.Exts         ( addrToAny# )
    import GHC.Ptr          ( Ptr(..) )
    import System.Info      ( os, arch )
    import Encoding
    import GHCi.ObjLink
    import Debug.Trace
    
    main :: IO ()
    main = do
      traceM "before initObjLinker"
      initObjLinker
      traceM "before loadObj"
      loadObj "/Users/saurabhnanda/projects/test-plugins/test-plugins/app/PluginMarkup.o"
      traceM "after loadObj"
    
      -- NOTE: I've hardcoded the symbol name that I obtained from running `symbols PluginMarkup.o`
      sym <- lookupSymbol "PluginMarkup_foliage_info"
      traceM "after lookupsymbol"
      traceM (show sym)

I'm getting the following output, which mean that I'm probably getting the Ptr to the function.

    before initObjLinker
    before loadObj
    after loadObj
    after lookupsymbol
    Just 0x0000000104be49a8

Question is, how do I run the function in the same Haskell environment/runtime? The underlying function is actually `foliage :: UtcTime -> Html`


-- Saurabh.

_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to execute a function loaded via GHCI.ObjLink?

Moritz Kiefer
Hi,
I have a blogpost which demonstrates this
https://purelyfunctional.org/posts/2016-05-20-dynamic-loading-haskell-module.html
Basically you need to unwrap the address and then use addrToAny.
Obviously this is not typesafe so use it carefully.

Cheers,
Moritz

On 07/27/2017 04:20 PM, Saurabh Nanda wrote:

> Hi,
>
> I'm playing around
> with https://www.stackage.org/haddock/lts-9.0/ghci-8.0.2/GHCi-ObjLink.html
> to see if I can come up with some sort of hot-loading/plugin system in
> Haskell.
>
> I've managed to load a shared object (compiled from a Haskell source via
> -rdynamic) with the following code:
>
>     {-# LANGUAGE OverloadedStrings #-}
>     {-# LANGUAGE MagicHash, UnboxedTuples #-}
>    
>     module Main where
>    
>     import GHC.Exts         ( addrToAny# )
>     import GHC.Ptr          ( Ptr(..) )
>     import System.Info      ( os, arch )
>     import Encoding
>     import GHCi.ObjLink
>     import Debug.Trace
>    
>     main :: IO ()
>     main = do
>       traceM "before initObjLinker"
>       initObjLinker
>       traceM "before loadObj"
>       loadObj
> "/Users/saurabhnanda/projects/test-plugins/test-plugins/app/PluginMarkup.o"
>       traceM "after loadObj"
>    
>       -- NOTE: I've hardcoded the symbol name that I obtained from
> running `symbols PluginMarkup.o`
>       sym <- lookupSymbol "PluginMarkup_foliage_info"
>       traceM "after lookupsymbol"
>       traceM (show sym)
>
> I'm getting the following output, which mean that I'm probably getting
> the Ptr to the function.
>
>     before initObjLinker
>     before loadObj
>     after loadObj
>     after lookupsymbol
>     Just 0x0000000104be49a8
>
> Question is, how do I run the function in the same Haskell
> environment/runtime? The underlying function is actually `foliage ::
> UtcTime -> Html`
>
> The code is available
> at https://github.com/vacationlabs/hint-test/blob/dll/app/Main.hs and
> the DLL is available
> at https://github.com/vacationlabs/hint-test/blob/dll/app/PluginMarkup.o
>
> -- Saurabh.
>
>
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.
>


_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.

signature.asc (849 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to execute a function loaded via GHCI.ObjLink?

Saurabh Nanda
I have a blogpost which demonstrates this
https://purelyfunctional.org/posts/2016-05-20-dynamic-loading-haskell-module.html

Hey Moritz, I'm not sure if you realised, but my code is based on your blog post itself -- thanks for writing it! It was just that I was trying to avoid using the `mangleSymbol` function by hard-coding the known symbol value. If I use the `mangleSymbol` method, the symbol lookup fails. If I hard-code the symbol name and try executing the function it segfaults.

I'm stuck now and don't know enough about the internals of Ptr, FuncPtr, Any, etc. to figure out how to proceed. I'm on MacOSX if that makes any difference.

-- Saurabh.

_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Loading...