On Tue, Apr 14, 2015 at 05:14:50PM +0100, Richard W.M. Jones wrote:
As a result of this I'm always suspicious of code that calls
String_val, stashes the result in a variable, and then uses the result
over long stretches of code. It's safer to call String_val() multiple
times whenever it is needed (String_val is a no-op because
value == char * for OCaml strings).
And another thing to say is if you want to pass a 'value' into other
private functions, in order to avoid having to call String_val() until
the last moment, then you usually need to surround those private
functions with:
static value internal_fn (value a)
{
CAMLparam1 (a);
// maybe also CAMLlocal (..);
...
CAMLreturn (Val_unit);
// or CAMLreturnT if returning a non-value
// or CAMLreturn0 if returning void
}
These are only needed for functions that may allocate on the OCaml
stack, eg. calling caml_alloc*, caml_copy*, etc (perhaps indirectly).
What these macros actually do is to set up a struct on the stack which
is linked to a global list of stack frames. If the GC moves an object
around, then it follows this list of stack frames, finding if a value
exists anywhere on the C stack pointing to that object, and adjusting
the value pointer to point to wherever the object moved to.
(It's helpful to examine the macro definition in the header files to
really see what's going on.)
Rich.
--
Richard Jones, Virtualization Group, Red Hat
http://people.redhat.com/~rjones
Read my programming and virtualization blog:
http://rwmj.wordpress.com
libguestfs lets you edit virtual machines. Supports shell scripting,
bindings from many languages.
http://libguestfs.org