[PPL-devel] pointer "ownership" in the C API?

Enea Zaffanella zaffanella at cs.unipr.it
Fri Mar 27 12:47:12 CET 2009


Basile Starynkevitch wrote:
[...]
> In particular, detailed explanation of Ocaml binding to PPL is welcome,
> since I happen to know quite well Ocaml (and the C coding rules required by
> its runtime).

Hello Basile.

I am trying to improve our OCaml language interface and it really looks 
like you are the right person I can ask a few simple questions.

First of all, I believe we are currently doing something bad even when 
doing simple things such as interfacing PPL variable indices.

In the C++ world, a variable index has type `dimension_type', which is 
just a typedef for the standard unsigned integer type `size_t'.
As far as I have understood, OCaml uses tagged signed integers (`int').

What is the right way to translate one into the other?

We are currently using
   Int_val / Val_int
but we just discovered that this casts the value to the C native "int" 
datatype. Hence, we should be probably using Long_val / Val_long.
However, there also is Unsigned_long_val ... but it is unclear to me 
if/when I can use it and feel confident that I am not misreading the 
input of the OCaml user.

So, what is the right way to code helper functions such as

   dimension_type caml_value_to_ppl_dimension(value);
   value ppl_dimension_to_caml_value(dimension_type);

taking into account that:
a) we would like to react properly (throwing an exception) when an OCaml 
user wrongly passes in a negative value (or, if possible, a value that 
is too big to fit into a dimension_type);
b) we would like to place assertions warning us whenever we try to 
convert a dimension_type that does not fit into an OCaml integer.
c) we want to strive for maximum portability (i.e., support both 
different computing platforms and, if possible, different OCaml releases).

Second question:
recently we corrected several GC-related issues reported by Kenneth 
MacKenzie. There were several places where our code was not GC safe.
However, there are other places where, IMHO, we are too conservative. 
For instance:

extern "C"
CAMLprim value
ppl_version_major(value unit) try {
   CAMLparam1(unit);
   CAMLreturn(Val_long(version_major()));
}
CATCH_ALL

Is there any need to wrap unit and the return value (an unboxed CAML 
int, afaict) with the calls to CAMLparam1 and CAMLreturn ?

Similarly, in the following example,

extern "C"
CAMLprim value
ppl_set_rounding_for_PPL(value unit) try {
   CAMLparam1(unit);
   set_rounding_for_PPL();
   CAMLreturn(Val_unit);
}
CATCH_ALL

is there any need to wrap Val_unit ?


Thanks in advance,
Enea.



More information about the PPL-devel mailing list