On 7/16/07, John Meacham
here is what I am thinking
foreign import wrapper mkFoo :: (Int -> Int) -> IO (FunPtr (Int -> Int))
will create the following:
-- this just translates a haskell function into an unboxed version. -- nothing tricky here. unboxMkFoo :: (Int -> Int) -> (Int__ -> Int__) unboxMkFoo fn = \x -> unbox (fn (box x))
-- psuedo-import of real C function, note we take a function as -- an argument, which is not legal haskell, but is fine, we will -- just expect the C function to take a pointer to a haskell heap -- object.
foreign import ccall c_mkFoo :: (Int__ -> Int__) -> IO Addr__
-- this is the final user visible mkFoo function mkFoo fn = c_mkFoo (unboxMkFoo fn)
-- and generate a c_mkFoo as follows
HsFunPtr c_mkFoo(node_t *n) { char *code = asm ("push n; call apply_int_int"); return (HsFunPtr)code; }
I hope this is clear, I used some constructs in ways that arn't legal haskell, but are expressible in core and grin so the meaning should be clear. you should call the appropriate 'apply' routine, but these are already generated, if you need to use a special calling convention (like passing the node in a register) then another stub might be needed rather than calling apply directly.
And apply_* is okay with having a return address between it's first and second arguments? Also... how am I supposed to name the C function safely? Just underscore-encode "c_"++show n (where n is the name being imported to)? and ... the all-important issue of where to *put* the C function, keeping in mind that cDecl returns a list of triples that represents toplevel bindings in the E program?