On IRC, you (JohnMeacham) (what -- there is someone else who reads this list?) said something about region inference and foreign import "wrapper". It just occured to me earlier today that you probably can't do much of that at all. You can basically do as much as you can do for a StablePtr. I remind you that the C functions made by a wrapper stub can be passed to C code and held there indefinately, just like a StablePtr, and can only be deallocated when the Haskell program calls freeHaskellFunPtr on them. We also talked about how a nice way to implement these wrapper stubs, by generating tiny thunks that would redirect calls to an evaluation routine after adding the closure to be called as an additional argument. (Actually, I suppose the evaluation routine would need a wrapper, like a foreign export does...). What I'm not sure about is how to refer to the address of the (wrapper around the) evaluation routine in the code for the "wrapper stub" (the function that is actually declared by the 'foreign import "wrapper"' declaration).
Samuel Bronson wrote:
On IRC, you (JohnMeacham) (what -- there is someone else who reads this list?)
Yes! I find myself a little busy with GoboLinux, other haskell development, and real-life things (if you can call preparing for college "real life"!), but this is the one mailing list for which I have read every message ever posted in it ;-) Isaac
Hello, On Sunday 15 July 2007 21:02, Isaac Dupree wrote:
... this is the one mailing list for which I have read every message ever posted in it ;-) ...
Ditto ... And with this avalanche of messages, I guess we will start discussing how to limit the volume, split into various sub-lists etc. (Just Joking.) Best regards Thorkil
On Sun, Jul 15, 2007 at 01:01:58PM -0400, Samuel Bronson wrote:
On IRC, you (JohnMeacham) (what -- there is someone else who reads this list?) said something about region inference and foreign import "wrapper". It just occured to me earlier today that you probably can't do much of that at all. You can basically do as much as you can do for a StablePtr. I remind you that the C functions made by a wrapper stub can be passed to C code and held there indefinately, just like a StablePtr, and can only be deallocated when the Haskell program calls freeHaskellFunPtr on them.
Yes, the region inference algorithm would have to do an 'escape analysis' to deterime which references escape the current frame. luckily, this is already inherent to the analysis, data stored in stableptrs or foreign wrapper imports will be noticed at this point.
We also talked about how a nice way to implement these wrapper stubs, by generating tiny thunks that would redirect calls to an evaluation routine after adding the closure to be called as an additional argument. (Actually, I suppose the evaluation routine would need a wrapper, like a foreign export does...). What I'm not sure about is how to refer to the address of the (wrapper around the) evaluation routine in the code for the "wrapper stub" (the function that is actually declared by the 'foreign import "wrapper"' declaration).
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. John -- John Meacham - ⑆repetae.net⑆john⑈
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?
participants (4)
-
Isaac Dupree -
John Meacham -
Samuel Bronson -
Thorkil Naur