"foreign export dynamic" in GHC

Ashley Yakeley ashley@semantic.org
Fri, 3 Aug 2001 00:41:45 -0700

When I make a function generator with "foreign export dynamic", GHC spits 
out stub files which it apparently then needs for the link. What are 
these for?

For instance:

foreign export dynamic mkCallback :: (Int -> IO Int) -> IO Addr

foreign import registerCallback :: Addr -> IO ()

exportCallback :: (Int -> IO Int) -> IO ()
exportCallback f = do
  fx <- mkCallback f
  registerCallback fx

And then I expect the C side of things to look like this:

typedef HsInt (*mkCallback_FunPtr) (HsInt arg1);

void registerCallback (HsAddr f)
mkCallback_FunPtr callBack = reinterpret_cast<mkCallback_FunPtr>(f);
// actually call the callback
HsInt arg = 3;
HsInt result = (*callBack)(arg);

Is this correct? When I compile the Haskell Test.hs I get these strange 
stub files, "Test_stub.h", "Test_stub.c" and  "Test_stub.o". The _stub.h 
one looks like this:

#include "HsFFI.h"
extern HsInt Test_dvD(HsStablePtr a0, HsAddr a_, HsInt a1);

...while the _stub.c looks like this:

#include "Stg.h"
#include "HsStd.h"
#include "HsLang.h"
#include "RtsAPI.h"
extern HaskellObj Test_zdfmkCallback_closure;
HsInt Test_dvD(HsStablePtr a0, HsAddr a_, HsInt a1)
SchedulerStatus rc;
HaskellObj ret;

What are the stubs for? The GHC manual, sec. 8.4.1 says this:

# An FFI implementation is encouraged to generate the C 
# typedef corresponding to a foreign export dynamic 
# declaration, but isn't required to do so.

It doesn't say anything about funny little stub functions. And curiously, 
it doesn't say exactly how GHC's FFI implementation responds to that 
non-requirement encouragement. There were no typedefs in the stub files.

Ashley Yakeley, Seattle WA