ForeignObj Finalizer in Hugs

Alastair David Reid reid@cs.utah.edu
27 Jun 2001 12:33:27 -0600


>>>>> "KAKIHARA" == KAKIHARA Norihiro <YIU04646@nifty.com> writes:

> I want to use ForeignObj for large transient data, but Hugs
> ForeignObj implementation is quite mysterious...

I wonder if you're being confused by the corresponding feature in GHC
(also called ForeignObj) which goes a long way beyond what Hugs
provides (and is a good deal harder to implement)?

>     primitive makeForeignObj :: Addr{-x-} -> Addr{-free-} -> IO
> The latter argument of makeForeignObj is a mystery.

> 1.  I thought it is a pointer of function (with type of [void
> (*)(void *);] ?).

That's what it is.

>     foreign import "foo" "newFO" newFO :: IO Addr 
>     foreign import "foo" "delFO" delFO :: Addr -> IO ()

>     newFO >>= (\fo -> makeForeignObj fo (unsafeCoerce delFO))

> This code causes an unexpected signal (probably the implementation
> of Addr -> IO () is different from C form).

You bet it will.  It's meant to be a pointer to a C function but
foreign import generates Haskell functions.  Their calling conventions
are incredibly different in Hugs: different address space, different
argument passing mechanism, different representation of every data type.

The clue here is that you have to use unsafeCoerce.  If we meant you
to pass something with Haskell type:

   Addr -> IO ()

then that would be the type.

(It is almost impossible to write a correct Haskell program that uses
unsafeCoerce.  Anyone using it is almost certainly doing something
very wrong.)

> 2.  `foreign label' is valid?

>     foreign import "foo" "newFO" newFO :: IO Addr 
>     foreign label "foo" "delFO" delFO :: Addr

>     newFO >>= (\fo -> makeForeignObj fo delFO)

> No, it isn't.

That ought to work but foreign label hasn't been tested very
thoroughly.  I'll try to get round to it sometime soon (but no
promises).

> 3.  Then I try to get the pointer of delFO directly (Fortunately
> lcc-win32 3.1 allows internal global variables viewable, however, I
> suppose other C compilers do not...).

>     foreign import "foo" "newFO" newFO :: IO Addr 
>     foreign import "foo" "delFO" delFO :: Addr -> IO ()
>     foreign import "foo" "getDelFO" getDelFO :: IO Addr

>     getDelFO >>= (\del -> newFO >>= (\fo -> makeForeignObj fo del))

> It works as expected.

Sounds like foreign label may be broken.

-- 
Alastair Reid        reid@cs.utah.edu        http://www.cs.utah.edu/~reid/