[m-users.] C foreign language interface question

fabrice nicol fabrnicol at gmail.com
Wed Apr 21 23:17:52 AEST 2021


I'm currently working on an interface library with R for Mercury, using 
the C FFI of both languages as a bridge.

This work in progress implies working with arrays, both in Mercury and 
the C FFI, and preliminary results are encouraging.

There is a couple of features, which I'm not sure are documented in the 
current reference manual, that I would like to make clear before 
proceeding further:

1.  The 'sharing' FFI foreign_proc annotation

In chapter 15.1., this annotation is not documented, perhaps because it 
is not advised to use it. Yet it looks like important in array.m to 
define Mercury arrays, as shown in the excerpt below from array.m:1500, 
foreign_proc init_2:

      sharing(yes(int, T, array(T)), [
                 cel(Item, []) - cel(Array, [T])

Is this annotation necessary to allow Mercury to access C arrays? What 
does it perform? I checked in compiler/parse_tree_out_pragma.m, where 
this annotation is defined, but there is not enough there to make it 
safe use.

2. R has its own GC, which is fired by any call to the C FFI of R. To 
protect recently allocated memory chunks from the R GC, the dedicated C 
FFI has a useful macro named PROTECT, and another one to unprotect the 
said chunks, leaving them open to R garbage collection. A 
quick-and-dirty reference is here: 
https://github.com/hadley/r-internals/blob/master/gc-rc.md

The question is simple. It is either (a) or (b):

(a) if C memory chunks allocated by the R C FFI **are not** protected 
from the Mercury GC, while the R-C FFI code is running:

--> is there a similar Mercury-C FFI macro, or a (possibly not 
documented) Mercury FLI directive, or any other way, to make it so that 
these chunks of C memory are no GC'd in competition with the R GC?

(b) if C memory chunks allocated by the R-C FFI **are** protected from  
the Mercury GC when the R-C FFI code is running:

--> when the R server has been shut down, how to free these chunks 
initially allocated by the R-C FFI code:

- by calling the Mercury GC?

I.E. by calling 'MR_GC_register_finalizer' as  in file cairo.m of the 
mercury_cairo 'extras' library, whose design I overall follow. Is this 
the right way?

If I understand it well, 'MR_GC_register_finalizer' may call a specific 
C memory cleanup procedure for non (Mercury) GC-managed memory chunks 
coming from foreign interfaces?

- or by bluntly calling 'free' in due time with a dedicated Mercury-C 
FFI call, independently of any Mercury GC intervention ?


Perhaps a few words on such issues would be useful in the FLI sections 
of the Reference manual. Incidentally, perhaps this manual could 
document MR_ArrayPtr in 15.3.1 (used in array.m). It may be of interest 
when Mercury arrays are passed along to the C FFI (as in ML_resize_array 
for example).

Thanks in advance for replying,

F. Nicol




More information about the users mailing list