"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;
rc=rts_evalIO(rts_apply(rts_apply((StgClosure*)&Test_zdfmkCallback_closure,
rts_mkStablePtr(a0)),rts_mkInt(a1)),&ret);
rts_checkSchedStatus("Test_dvD",rc);
return(rts_getInt(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