
On Wed, Feb 8, 2012 at 10:56 AM, Ian Lynagh
That sounds right. It basically means you don't have to write the C stubs yourself, which is nice because (a) doing so is a pain, and (b) when the foreign import is inside 2 or 3 CPP conditionals it's even more of a pain to replicate them correctly in the C stub.
Unfortunately, there are cases where C doesn't get all the type information it needs, e.g.: http://hackage.haskell.org/trac/ghc/ticket/2979#comment:14 but I'm not sure what the best fix is.
I believe jhc's algorithm works in this case. Certain type constructors have C types associated with them, in particular, many newtypes have c types that are different than their contents. So my routine that finds out whether an argument is suitable for FFIing returns both a c type, and the underlying raw type (Int# etc..) that the type maps to. So the algorithm checks if the current type constructor has an associated C type, if it doesn't then it expands the newtype one layer and trys again, however if it does have a c type, it still recurses to get at the underlying raw type, but then replaces the c type with whatever was attached to the newtype. In the case of 'Ptr a' it recursively runs the algorithm on the argument to 'Ptr', then takes that c type and appends a '*' to it. If the argument to 'Ptr' is not an FFIable type, then it just returns HsPtr as the C type. Since CSigSet has "sigset_t" associated with it, 'Ptr CSigSet' ends up turning into 'sigset_t *' in the generated code. (Ptr (Ptr CChar)) turns into char** and so forth. An interesting quirk of this scheme is that it faithfully translates the perhaps unfortunate idiom of newtype Foo_t = Foo_t (Ptr Foo_t) into foo_t************ (an infinite chain of pointers) which is actually what the user specified. :) I added a check for recursive newtypes that chops the recursion to catch this as people seem to utilize it.
I ask because jhc needs such a feature (very hacky method used now, the rts knows some problematic functions and includes hacky wrappers and #defines.) and I'll make it behave just like the ghc one when possible.
Great!
It has now been implemented, shall be in jhc 0.8.1. John