[Haskell-cafe] GHC 6.6.1 and SELinux issues

Bertram Felgenhauer bertram.felgenhauer at googlemail.com
Sun Sep 2 20:56:52 EDT 2007


Alexander Vodomerov wrote:
> On Wed, Aug 29, 2007 at 01:03:56PM -0700, Stefan O'Rear wrote:
[snip]
> What is so special about wrapper and dynamic functions?
> 
> Can you please give some ideas how self-modifying code can be used in
> FFI implementation?

It's not self-modifying code really, it's dynamically generated code.

Here is a small complete example for illustration:

>>> V.hs >>>
import Foreign
import Foreign.C

foreign import ccall "wrapper"
  mkCallback :: (CInt -> CInt) -> IO (FunPtr (CInt -> CInt))

foreign import ccall "v.h foo" c_foo :: FunPtr (CInt -> CInt) -> IO CInt

main = do
    add_21 <- mkCallback (+21)
    c_foo add_21 >>= print
<<<

>>> v.c >>>
#include "v.h"
int foo(callback_t fun)
{
    return fun(fun(0));
}
<<<

>>> v.h >>>
typedef int (* callback_t)(int);
int foo(callback_t fun);
<<<

(compile with ghc -ffi V.hs v.c)

This program takes a function that adds 21 to a CInt, wraps it into
a C function pointer of type callback_t, and then calls this function
from the C side two times; it prints 42.

In particular, the wrapper mkCallback takes any *Haskell* function
of type CInt -> CInt and returns a *C* function pointer that represents
the same function.

Note that this function receives no additional context in its arguments.
This is convenient but it means that each call to mkCallback has to
return a different function pointer, so it is necessary to generate a
small piece of code dynamically to implement it.

HTH,

Bertram


More information about the Haskell-Cafe mailing list