[m-dev.] completing the new foreign language interface

Julien Fischer juliensf at csse.unimelb.edu.au
Fri Jul 7 16:40:19 AEST 2006


Currently the reasons given in the reference manual for not deprecating the
old C interface are that the new foreign language interface has no equivalent
for `pragma import' and `pragma export'.  (It also says that the new one isn't
as well tested as the old one but for the most part that's not really valid
anymore.)

In order to "complete" the new foreign language interface (at least to a point
where we can start to get rid of the old one), I am proposing the following:

(1) that the new interface does not need an equivalent for `pragma import'.

(2) that we introduce `pragma foreign_export' declarations to the new
    interface.  These carry out the function of `pragma export' in the old
    interface but are intended to work with backends other than the C
    backends.

(3) that the reference manual section on trailing be moved from
    section 14 (C Interface) to section 17 (Implementation-dependent
    extensions).

(4) other misc. documentation changes.
    The C pointer/Memory management documentation moved to section 13 of the
    reference manual.

In more detail:

(1)  `pragma import' is just syntactic sugar for a foreign proc that calls
     the named procedure.  I don't think we would lose anything from not
     supporting this.

(2)  Unlike (1) we definitely need this.  I'm proposing that in introducing
     `pragma foreign_export' we make a fairly minimal change and just require
     that a language be specified in addition to the other information that
     is already in export pragmas.

     foreign_export pragmas would work in a similar fashion to the other
     `foreign_*' pragmas. i.e they would only be considered by the compiler
     when compiling to a compatible backend, so that
     `:- pragma foreign_export("C", ...)' would only apply for the C backends,
     `:- pragma foreign_export("Java", ...) for the Java backend etc.

     For the .NET backend, where we support several possible foreign languages,
     we would use the same technique that we do with foreign_procs.
     C# and MC++ exports would be hoisted into separate C# and MC++ files
     and compiled separately.

(3) and (4) should follow from the above.

The following is a (very preliminary) draft change to the reference manual
that describes the new foreign_export decls.  (Actually it's mostly just
the old `pragma export' description shifted into section 13 with a
bit of search and replace.)

Index: reference_manual.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/reference_manual.texi,v
retrieving revision 1.357
diff -u -r1.357 reference_manual.texi
--- reference_manual.texi	5 Jul 2006 08:45:37 -0000	1.357
+++ reference_manual.texi	7 Jul 2006 06:02:19 -0000
@@ -6071,6 +6071,9 @@
 				       or function as a call to code
 				       written in a different
 				       programming language.
+* Calling Mercury from foreign code::  How to call a Mercury predicate
+                                       or function from a different
+                                       programming language.
 * Using foreign types from Mercury::   How to use a type defined in
 				       a different programming language
 				       in Mercury code.
@@ -6388,6 +6391,36 @@

 @c -----------------------------------------------------------------------

+ at node Calling Mercury from foreign code
+ at section Calling Mercury from foreign code
+
+Mercury procedures can be exported to foreign languages so that you
+can call those Mercury procedures from code written in a foreign language.
+
+A declaration of the form
+
+ at example
+:- pragma foreign_export("@var{Lang}",
+        @var{Pred}(@var{Mode1}, @var{Mode2}, @dots{}), "@var{ForeignName}").
+ at end example
+
+ at noindent
+or
+
+ at example
+:- pragma foreign_export("@var{Lang}",
+        @var{Func}(@var{Mode1}, @var{Mode2}, @dots{}) = @var{Mode},
+        "@var{ForeignName}").
+ at end example
+
+ at noindent
+exports a procedure for use by foreign language @var{Lang}.  It is an error
+to export Mercury procedures that have a determinism of multi or nondet
+to a foreign language.  For further details see the language specific
+information below.
+
+ at c -----------------------------------------------------------------------
+
 @node Data passing conventions
 @section Data passing conventions

@@ -6765,6 +6798,7 @@
 @menu
 * Using pragma foreign_type for C 	:: Declaring C types in Mercury
 * Using pragma foreign_proc for C 	:: Calling C code from Mercury
+* Using pragma foreign_export for C     :: Calling Mercury code from C
 * Using pragma foreign_decl for C 	:: Including C declarations in Mercury
 * Using pragma foreign_code for C 	:: Including C code in Mercury
 @end menu
@@ -6862,6 +6896,62 @@
 If the procedure fails, the C code need only
 set @code{SUCCESS_INDICATOR} to false (zero).

+ at node Using pragma foreign_export for C
+ at subsubsection Using pragma foreign_export for C
+
+A C @samp{pragma foreign_export} declaration has the form:
+
+ at example
+:- pragma foreign_export("C", @var{MercuryMode}, "@var{C_Name}").
+ at end example
+
+For example,
+
+ at example
+:- pragma foreign_export("C", foo(in, in, out), "FOO").
+ at end example
+
+For each Mercury module containing @samp{pragma foreign_export} declarations,
+the Mercury implementation will automatically create a header file
+for that module which declares a C function @var{C_Name}() for each of the
+ at samp{pragma foreign_export} declarations.
+Each such C function is the C interface to the specified mode of the
+specified Mercury predicate or function.
+
+The interface to a Mercury procedure is determined as follows.
+Mercury types are converted to C types according to the rules in
+ at ref{Passing data to and from C}.
+Input arguments are passed by value.  For output arguments, the
+caller must pass the address in which to store the result.
+If the Mercury procedure can fail, then its C interface function
+returns a truth value indicating success or failure.
+If the Mercury procedure is a Mercury function that cannot fail, and
+the function result has an output mode, then the C interface
+function will return the Mercury function result value.
+Otherwise the function result is appended as an extra argument.
+ at c XXX We need to update this for dummy unit types.
+Arguments of type @samp{io.state} or @samp{store.store(_)}
+are not passed at all.  (The reason for this is that these types
+represent mutable state, and in C modifications to mutable state
+are done via side effects, rather than argument passing.)
+
+Calling polymorphically typed Mercury procedures from C is a little bit
+more difficult than calling ordinary (monomorphically typed) Mercury procedures.
+The simplest method is to just create monomorphic forwarding
+procedures that call the polymorphic procedures, and export them,
+rather than exporting the polymorphic procedures.
+
+If you do export a polymorphically typed Mercury procedure, the compiler
+will prepend one @samp{type_info} argument to the parameter list of
+the C interface function for each polymorphic type variable in the
+Mercury procedure's type signature.  The caller must arrange to pass
+in appropriate @samp{type_info} values corresponding to the types
+of the other arguments passed.  These @samp{type_info} arguments can
+be obtained using the Mercury @samp{type_of} function in the Mercury
+standard library module @samp{type_desc}.
+
+To use the C declarations produced see @ref{Using pragma foreign_decl for C}.
+
 @node Using pragma foreign_decl for C
 @subsubsection Using pragma foreign_decl for C

@@ -6908,7 +6998,8 @@
 automatically includes is subject to change.

 If a Mercury predicate or function exported using
-a @samp{pragma export} declaration is to be used within a
+a @samp{pragma export} or @samp{pramga foreign_export} declaration
+is to be used within a
 @samp{:- pragma foreign_code} or @samp{:- pragma foreign_proc}
 declaration the header file for the module containing the
 @samp{pragma export} declaration should be included using a
@@ -6947,6 +7038,7 @@
 @menu
 * Using pragma foreign_type for C#	:: Declaring C# types in Mercury
 * Using pragma foreign_proc for C# 	:: Calling C# code from Mercury
+* Using pragma foreign_export for C#    :: Calling Mercury code from C#
 * Using pragma foreign_decl for C# 	:: Including C# declarations in Mercury
 * Using pragma foreign_code for C# 	:: Including C# code in Mercury
 @end menu
@@ -7000,6 +7092,11 @@
 If the procedure fails, the C# code need only
 set @code{SUCCESS_INDICATOR} to false.

+ at node Using pragma foreign_export for C#
+ at subsubsection Using pragma foreign_export for C#
+
+ at samp{pragma foreign_export} is not currently supported for C#.
+
 @node Using pragma foreign_decl for C#
 @subsubsection Using pragma foreign_decl for C#

@@ -7024,6 +7121,7 @@
 ").
 @end example

+
 @node Using pragma foreign_code for C#
 @subsubsection Using pragma foreign_code for C#

@@ -7060,6 +7158,7 @@
 @menu
 * Using pragma foreign_type for IL	:: Declaring IL types in Mercury
 * Using pragma foreign_proc for IL 	:: Calling IL code from Mercury
+* Using pragma foreign_export for IL    :: Calling Mercury code from IL
 * Using pragma foreign_decl for IL 	:: Including IL declarations in Mercury
 * Using pragma foreign_code for IL 	:: Including IL code in Mercury
 @end menu
@@ -7177,6 +7276,11 @@
 Each of the head variables will be represented by the Common Language
 Runtime types as specified in @ref{IL and C# data passing conventions}.

+ at node Using pragma foreign_export for IL
+ at subsubsection Using pragma foreign_export for IL
+
+ at samp{pragma foreign_export} is currently not supported for IL.
+
 @node Using pragma foreign_decl for IL
 @subsubsection Using pragma foreign_decl for IL

@@ -7197,6 +7301,7 @@
 @menu
 * Using pragma foreign_type for Java :: Declaring Java types in Mercury
 * Using pragma foreign_proc for Java :: Calling Java code from Mercury
+* Using pragma foreign_export for Java :: Calling Mercury from Java code
 * Using pragma foreign_decl for Java :: Including Java declarations in Mercury
 * Using pragma foreign_code for Java :: Including Java code in Mercury
 @end menu
@@ -7265,6 +7370,11 @@
 @c If the procedure fails, the Java code need only
 @c set the @code{succeeded} variable to false.

+ at node Using pragma foreign_export for Java
+ at subsubsection Using pragma foreign_export for Java
+
+ at samp{pragma foreign_export} not currently supported for Java.
+
 @node Using pragma foreign_decl for Java
 @subsubsection Using pragma foreign_decl for Java

@@ -7332,10 +7442,11 @@
 @subsection Interfacing with Managed C++

 @menu
-* Using pragma foreign_type for MC++::  Declaring MC++ types in Mercury
-* Using pragma foreign_proc for MC++::  Calling MC++ code from Mercury
-* Using pragma foreign_decl for MC++::  Including MC++ declarations in Mercury
-* Using pragma foreign_code for MC++::  Including MC++ code in Mercury
+* Using pragma foreign_type for MC++::   Declaring MC++ types in Mercury
+* Using pragma foreign_proc for MC++::   Calling MC++ code from Mercury
+* Using pragma foreign_export for MC++:: Calling Mercury from MC++ code
+* Using pragma foreign_decl for MC++::   Including MC++ declarations in Mercury
+* Using pragma foreign_code for MC++::   Including MC++ code in Mercury
 @end menu

 @node Using pragma foreign_type for MC++
@@ -7387,6 +7498,11 @@
 If the procedure fails, the MC++ code need only
 set @code{SUCCESS_INDICATOR} to false.

+ at node Using pragma foreign_export for MC++
+ at subsubsection Using pragma foreign_export for MC++
+
+ at samp{pragma foreign_export} is not currently supported for MC++.
+
 @node Using pragma foreign_decl for MC++
 @subsubsection Using pragma foreign_decl for MC++

Julien.
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list