FW: H/Direct
Simon Peyton-Jones
simonpj at microsoft.com
Wed Dec 6 10:10:26 EST 2000
Here's a question from Koen that bears on the FFI.
Simon
-----Original Message-----
From: Koen Claessen [mailto:koen at cs.chalmers.se]
Sent: 04 December 2000 12:55
To: Erik Meijer; Simon Peyton-Jones; Sigbjorn Finne
Subject: H/Direct
Hi H/Direct team,
I have been using H/Direct for quite a while now, and I am a
happy user (apart from the massive amount of work involved
in getting the system to run for both Hugs and GHC -- there
seems to be a circular import which Hugs complains about and
which can be skillfully removed, but which GHC depends on or
something.)
I have a question about marshalling arguments which are
expensive to marshall in H/Direct. Often you want this
result to be shared between calls of the functions.
Currently, I have applied the following technique a couple
of times and I wonder if it can be made more general and
added to H/Direct.
For example, I have a BDD package with the following
operation (I have simplified this type a bit):
[pure]Bdd *BddReplace
( [size_is(n),in] int *xs
, int n
, [in] Bdd *bdd
);
(The argument "xs" encodes a variable mapping, which is used
to construct a new BDD from the argument.) I want this to be
a function in Haskell with the type:
replace :: [Int] -> Bdd -> Bdd
The way I often use replace is by defining:
prime :: Bdd -> Bdd
prime = replace [ extremely-long-list ]
Here, I want the marshalling of the list to happen once, and
to be shared between calls to prime.
So I wrote my own version of replace in Haskell. Here it is:
replace :: [Int] -> (Bdd -> Bdd)
replace xs =
unsafePerformIO $
do array <- newCArray (length n)
sequence [ setCArray array i x
| (i,x) <- [0..] `zip` xs
]
return (\bdd -> primBddReplace bdd array)
Note the brackets in the type to indicate I am returning a
function. Now, the CArray interface must look like this:
[finaliser("free")]
interface CArray {};
CArray *newCArray( int n );
void setCArray( CArray *arr, int i, int n );
int readCArray( CArray *arr, int i );
This is because "replace" should not free the C-array until
it looses track of the returned function.
It works great! The question is: can this be done by
inventing some new annotation for the IDL code? One problem
is maybe that the sharing of these things can only be done
in a certain order.
Regards,
Koen.
--
Koen Claessen http://www.cs.chalmers.se/~koen
phone:+46-31-772 5424 mailto:koen at cs.chalmers.se
-----------------------------------------------------
Chalmers University of Technology, Gothenburg, Sweden
More information about the FFI
mailing list