[m-users.] Documenting univ data passing to and from the C FFI

fabrice nicol fabrnicol at gmail.com
Thu May 20 05:08:43 AEST 2021


1. In the Reference manual FFI section, there is no hint as to how to 
pass 'univ' values to and from the C FFI.

Looking into 'runtime/mercury_univ.h', I found 'MR_unravel_univ' and 
'MR_new_univ_on_hp'.

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".

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).

2. It would also be nice to minimally document how to access say, at 
least, the 'MR_type_ctor_name' field of MR_TypeInfo.

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:


%--------------------------------------------------------------------------------------------------------------------------------------%

:- module example.
:- interface.
:- import_module io.

:- pred main(io::di, io::uo) is det.

:- implementation.
:- import_module univ.
:- pragma foreign_decl("C", "#include ""mercury_univ.h""").
:- pred test(univ::in, float::out, string::out) is det.

:- pragma foreign_proc("C",
     test(X::in, Y::out, Ty::out),
[promise_pure],
"
     MR_TypeInfo ti;
     MR_Word value;
     MR_unravel_univ(X, ti, value);
     Y = MR_word_to_float(value);
     MR_ConstString s = 
((MR_TypeCtorInfo)(ti->MR_ti_type_ctor_info))->MR_type_ctor_name;
     Ty = s;
").

main(!IO) :-
    test(univ(2.0), Y, Ty), write_string(Ty, !IO), write_float(Y, !IO).

%--------------------------------------------------------------------------------------------------------------------------------------%

Yet segfaults at runtime:

"*** Mercury runtime: caught segmentation violation ***
cause: address not mapped to object
PC at signal: 94533097284735 (55fa33aee47f)
address involved: 0x28
This may have been caused by a stack overflow, due to unbounded recursion.
exiting from signal handler."

I finally found the way out using:

%--------------------------------------------------------------------------------------------------------------------------------------%

(...)

  MR_ConstString s = 
(MR_TYPEINFO_GET_TYPE_CTOR_INFO(ti))->MR_type_ctor_name;

(...)

%--------------------------------------------------------------------------------------------------------------------------------------%

and looking at the code for the macro, one understands why the above 
executable segfaults at runtime.

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.

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?

Fabrice

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurylang.org/archives/users/attachments/20210519/2ce84d7b/attachment.html>


More information about the users mailing list