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