[m-dev.] for discussion: pragma foreign_import

Peter Ross peter.ross at miscrit.be
Tue Dec 4 03:58:53 AEDT 2001


Here is a diff to the reference manual for the new foreign_import
declaration.

At a later date it would be nice "s/foreign_import/import/".  However
for the moment I think it would be easier to talk about it as a new
declaration.

Following fjh's previous suggestion here is what the syntax will look
like for the IL backend.

:- func cos(float) = float.
:- pragma foreign_import(il, cos(in) = out,
		".method public static float64 Cos(float64)"

The only problem that I see with this syntax is that nowhere do we mention
the assembly which Cos() is contained in.  This information is not needed
to generate a call to the Cos method, but is needed so that we make sure
that we generate a .assembly directive in the IL file.

Any suggestions about how we avoid that problem?

My initial plan was to place that information in the il term, but fjh doesn't
like that idea.

Anyway thoughts welcome.

diff -u reference_manual.texi reference_manual.texi
--- reference_manual.texi
+++ reference_manual.texi
@@ -4843,10 +4843,107 @@
 code using @samp{pragma foreign_proc}.
 
 @menu
+* pragma foreign_import::       Importing foreign functions.
 * pragma foreign_proc::         Defining Mercury procedures using foreign code.
 * Foreign code attributes::   	Describing properties of foreign
 				functions or code.
 @end menu
+
+ at node pragma foreign_import
+ at subsection pragma foreign_import
+
+ at example
+:- pragma foreign_import(@var{Lang},
+		@var{Pred}(@var{Mode1}, @var{Mode2}, @dots{}),
+                @var{Attributes}, "@var{Name}").
+ at end example
+
+or
+
+ at example
+:- pragma import(@var{Lang},
+		@var{Func}(@var{Mode1}, @var{Mode2}, @dots{}) = @var{Mode},
+		@var{Attributes}, "@var{Name}").
+ at end example
+
+ at noindent
+imports a function in the foreign language specified by @var{Lang}
+for use by Mercury.
+ at var{Pred} or @var{Func} must specify the name of a previously declared
+Mercury predicate or function, and @var{Mode1}, @var{Mode2}, @dots{},
+and (for functions) @var{Mode} must specify one of the
+modes of that predicate or function.
+There must be no clauses for the specified Mercury procedure;
+instead, any calls to that procedure will be executed by calling
+the function specified by @var{Name}.
+The @var{Attributes} argument is optional; if present,
+it specifies properties of the given function
+(@pxref{Foreign code attributes}).
+
+The interface to the function for a given Mercury procedure is
+determined as follows.
+Mercury types are converted to foreign types according to the rules in
+ at ref{Data passing conventions}.
+Mercury arguments declared with input modes
+are passed by value to the function.
+Mercury arguments declared with output modes
+are passed by reference.
+ at c XXX I think we make this a bool on the IL backend.
+If the Mercury procedure can fail, then its imported function should return
+a Mercury integer indicating success or failure:
+non-zero indicates success, and zero indicates failure.
+If the Mercury procedure is a Mercury function that cannot fail, and
+the function result has an output mode, then the foreign function should
+return the Mercury function result value.
+Otherwise the function result is appended as an extra argument.
+Arguments of type @samp{io__state} or @samp{store__store(_)} are not
+passed at all; that's because these types represent mutable state, and
+in foreign functions modifications to mutable state are done via side effects,
+rather than argument passing.
+
+If you use @samp{pragma foreign_import} for a polymorphically typed
+Mercury procedure,
+the compiler will prepend one @samp{type_info} argument to the parameters
+passed to the C function for each polymorphic type variable in the
+Mercury procedure's type signature.  The values passed in these arguments
+will be the same as the values that would be obtained using the Mercury
+ at samp{type_of} function in the Mercury standard library module @samp{std_util}.
+These values may be useful in case the C function wishes to in turn call
+another polymorphic Mercury procedure (@pxref{Calling Mercury code from C}).
+ at c XXX we need a calling Mercury code from the outside world section.
+
+You may not give a @samp{pragma foreign_import} declaration for a procedure
+with determinism @samp{nondet} or @samp{multi}.
+
+ at subsubsection pragma foreign_import for C
+
+To import a C function on the C backend
+use @code{c} for @var{Lang},
+and @var{Name} is the C function name.
+
+For example, the following code imports the C function @samp{cos()}
+as the Mercury function @samp{cos/1}:
+
+ at example
+:- func cos(float) = float.
+:- pragma import(cos(in) = out, [will_not_call_mercury], "cos").
+ at end example
+
+ at subsubsection pragma foreign_import for IL
+
+To import an IL function on the IL backend
+use @code{il} for @var{Lang},
+ at c XXX suggestions on how to say this better
+and @var{Name} is the IL declaration for the IL function.
+
+For example, the following code imports the IL function @samp{Cos()}
+as the Mercury function @samp{cos/1}:
+
+ at example
+:- func cos(float) = float.
+:- pragma foreign_import(il, cos(in) = out,
+		".method public static float64 Cos(float64)"
+ at end example
 
 @node pragma foreign_proc
 @subsection pragma foreign_proc
--------------------------------------------------------------------------
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