
Thinking to take advantage of fortuitous heap layout of some Haskell values for interfacing with C, I've written the following function: addressOf :: a -> Ptr () addressOf x = x `seq` unsafeCoerce# (Box x) data Box x = Box x For example, data A = A {-# UNPACK #-} !(Ptr Word8) {-# UNPACK #-} !CInt main = let a = A nullPtr 12 p = addressOf a `plusPtr` 4 in do x <- peek p :: IO Int y <- peek p :: IO Int print (x, y) prints (0, 12) One thing I don't understand is that this fails if I use Just rather than inventing my box type. I suppose the info table for Just is set up to support a vectored return for pattern matching on Maybe? (the commentary isn't very clear here. The section http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/HaskellExecution#Ret... says, in full: "Return Convention Direct Returns Vectored Returns" ) The reason I'm messing about with this stuff is that I'm pretty sure passing p to C code would give a usable pointer to struct a {char *; int;}; Obviously my plot will be spoiled if the GC comes along and relocates the value while C code is trying to use it. Are there any other pitfalls with this approach? A different and in all likelihood saner approach is building up more tools for manipulating pointers to C data from Haskell, perhaps along the lines of cmucl's support for "Alien Objects". http://www.math.sunysb.edu/~sorin/online-docs/cmucl/aliens.html The main reason to even think about touching the heap representation of Haskell objects is so that the values can be manipulated by pure code, pattern matched, etc. Brandon

I am not sure if you can't use them for some reason, but this sounds like exactly the problem that stable pointers are meant to solve: http://haskell.org/ghc/docs/latest/html/libraries/base/Foreign-StablePtr.htm... John -- John Meacham - ⑆repetae.net⑆john⑈

On Mon, Oct 23, 2006 at 06:43:26PM -0700, Brandon Moore wrote:
A different and in all likelihood saner approach is building up more tools for manipulating pointers to C data from Haskell, perhaps along the lines of cmucl's support for "Alien Objects". http://www.math.sunysb.edu/~sorin/online-docs/cmucl/aliens.html
sorry to respond twice to the same mail, but have you seen hsc2hs? it can let you access arbitrary components of structures defined in C, or have haskell values that map to unknown c integral types in a portable way. hsc2hs is nice. it is the minimum needed to write portable haskell ffi using code. John -- John Meacham - ⑆repetae.net⑆john⑈

John Meacham wrote:
I am not sure if you can't use them for some reason, but this sounds like exactly the problem that stable pointers are meant to solve:
http://haskell.org/ghc/docs/latest/html/libraries/base/Foreign-StablePtr.htm...
Which problem? Mostly, I noticed that evaluated Haskell values greatly resemble a header word plus a C struct, and was thinking this could be (ab)used for working with C code, and might make it easier to manipulate values on the Haskell side. Plus, it was fun figuring out how use unsafeCoerce# and Box to manufacture a Ptr to an ordinary Haskell value. Stable pointers might help with the GC relocating things, except I don't think having a stable pointer guarantees that the object won't be moved around, just that the stable pointer won't be invalidated by GC.
On Mon, Oct 23, 2006 at 06:43:26PM -0700, Brandon Moore wrote:
A different and in all likelihood saner approach is building up more tools for manipulating pointers to C data from Haskell, perhaps along the lines of cmucl's support for "Alien Objects". http://www.math.sunysb.edu/~sorin/online-docs/cmucl/aliens.html
sorry to respond twice to the same mail, but have you seen hsc2hs? it can let you access arbitrary components of structures defined in C, or have haskell values that map to unknown c integral types in a portable way.
hsc2hs is nice. it is the minimum needed to write portable haskell ffi using code. Thanks, I've seen related things in c2hs, but I didn't realize hsc2hs came with GHC.
Brandon

Brandon Moore wrote:
Thinking to take advantage of fortuitous heap layout of some Haskell values for interfacing with C, I've written the following function:
addressOf :: a -> Ptr () addressOf x = x `seq` unsafeCoerce# (Box x) data Box x = Box x
For example,
data A = A {-# UNPACK #-} !(Ptr Word8) {-# UNPACK #-} !CInt
main = let a = A nullPtr 12 p = addressOf a `plusPtr` 4 in do x <- peek p :: IO Int y <- peek p :: IO Int print (x, y) prints (0, 12)
One thing I don't understand is that this fails if I use Just rather than inventing my box type. I suppose the info table for Just is set up to support a vectored return for pattern matching on Maybe?
Yes, exactly right.
(the commentary isn't very clear here. The section http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/HaskellExecution#Ret... says, in full: "Return Convention Direct Returns Vectored Returns" )
Sorry, I haven't got around to writing that section yet!
The reason I'm messing about with this stuff is that I'm pretty sure passing p to C code would give a usable pointer to struct a {char *; int;};
Obviously my plot will be spoiled if the GC comes along and relocates the value while C code is trying to use it.
Yes.
Are there any other pitfalls with this approach?
The GC pitfall not enough for you? :) Well, future GHC versions might change the representation under your feet, since we don't consider the heap object representation to be stable, user-visible stuff. Cheers, Simon
participants (3)
-
Brandon Moore
-
John Meacham
-
Simon Marlow