<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
<p>1. In the Reference manual FFI section, there is no hint as to
how to pass 'univ' values to and from the C FFI.</p>
<p>Looking into 'runtime/mercury_univ.h', I found <span
class="pl-s"> 'MR_unravel_univ' and 'MR_new_univ_on_hp'. <br>
</span></p>
<p><span class="pl-s">These two macros are pretty straightforward to
use so that I think there is no obvious reason not to mention
them in 15.3.1 "C data passing convention".</span></p>
<p><span class="pl-s">All the more so as there seem to be caveats
(like I could not use NULL in the second 'typeinfo' argument,
even if it is actually a pointer). <br>
</span></p>
<p><span class="pl-s">2. It would also be nice to minimally document
how to access say, at least, the 'MR_type_ctor_name' field of
MR_TypeInfo.<br>
</span></p>
<p><span class="pl-s">I've gone through some difficulties retrieving
that knowledge on my own (ok, it is part of the learning
experience). The following code builds all right into an
executable: <br>
</span></p>
<p><br>
<span class="pl-s">%--------------------------------------------------------------------------------------------------------------------------------------%</span></p>
<p><span class="pl-s">:- module
example.
<br>
:-
interface.
<br>
:- import_module
io.
<br>
<br>
:- pred main(io::di, io::uo) is
det.
<br>
<br>
:-
implementation.
<br>
:- import_module
univ.
<br>
:- pragma foreign_decl("C", "#include
""mercury_univ.h""").
<br>
:- pred test(univ::in, float::out, string::out) is
det.
<br>
<br>
:- pragma
foreign_proc("C",
<br>
test(X::in, Y::out,
Ty::out),
<br>
[promise_pure],
<br>
"
<br>
MR_TypeInfo
ti;
<br>
MR_Word
value;
<br>
MR_unravel_univ(X, ti,
value);
<br>
Y =
MR_word_to_float(value);
<br>
MR_ConstString s =
((MR_TypeCtorInfo)(ti->MR_ti_type_ctor_info))->MR_type_ctor_name;
<br>
Ty =
s;
<br>
").
<br>
<br>
main(!IO)
:-
<br>
test(univ(2.0), Y, Ty), write_string(Ty, !IO), write_float(Y,
!IO). <br>
</span></p>
<p>%--------------------------------------------------------------------------------------------------------------------------------------%</p>
<p><span class="pl-s"><span class="pl-s">Yet segfaults at runtime:</span></span></p>
<p><span class="pl-s">"*** Mercury runtime: caught segmentation
violation
***
<br>
cause: address not mapped to
object
<br>
PC at signal: 94533097284735
(55fa33aee47f)
<br>
address involved:
0x28
<br>
This may have been caused by a stack overflow, due to unbounded
recursion.
<br>
exiting from signal handler."<br>
</span></p>
<p><span class="pl-s">I finally found the way out using:</span></p>
<p><span class="pl-s">%--------------------------------------------------------------------------------------------------------------------------------------%</span></p>
<p>(...)</p>
<p><span class="pl-s"> MR_ConstString s =
(MR_TYPEINFO_GET_TYPE_CTOR_INFO(ti))->MR_type_ctor_name; <br>
</span></p>
<p><span class="pl-s">(...)<br>
</span></p>
<p><span class="pl-s">%--------------------------------------------------------------------------------------------------------------------------------------%</span></p>
<p><span class="pl-s">and looking at the code for the macro, one
understands why the above executable segfaults at runtime. <br>
</span></p>
<p><span class="pl-s">Yet this is pretty much implementation
engineering and it would be nice to save users from perusing the
runtime C code to get a clue. <br>
</span></p>
<p><span class="pl-s">Perhaps a handful of explanatory lines on
'MR_unravel_univ', 'MR_new_univ_on_hp', 'MR_TypeInfo' and a
couple of 'MR_INFO_...' macros could be added to an annex?</span></p>
<p><span class="pl-s">Fabrice<br>
</span></p>
</body>
</html>