[m-rev.] for review: il as a foreign language

Tyson Dowd trd at cs.mu.OZ.AU
Mon Jul 16 23:28:18 AEST 2001


Hi,

I have addressed the comments -- instead of fixing the potential problem
with inlining, I have made sure inlining of IL is turned off and
comment ed the problem.

Interdiff still isn't playing nice so here's a manual version:

I added the following comment to ml_code_gen.m:

+
+
+       % XXX in the code to marshall parameters, fjh says:
+       % we need to handle the case where the types in the procedure interface
+       % are polymorphic, but the types of the vars in the `foreign_proc' HLDS
+       % goal are concrete instances of those types, which can happen when the
+       % procedure is inlined or specialized.  The assignment that you
+       % generate here with ml_gen_assign won't be type-correct.  In general
+       % you may need to box/unbox the arguments.

And added:

Index: inlining.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/inlining.m,v
retrieving revision 1.100
diff -u -r1.100 inlining.m
--- inlining.m  2001/04/07 14:04:41     1.100
+++ inlining.m  2001/07/16 13:18:13
@@ -944,6 +944,11 @@
 :- pred ok_to_inline_language(foreign_language::in,
compilation_target::in)
        is semidet.
 ok_to_inline_language(c, c).
+% ok_to_inline_language(il, il). %
+% XXX we need to fix the handling of parameter marhsalling for inlined code
+% before we can enable this -- see the comments in
+% ml_gen_ordinary_pragma_il_proc in ml_code_gen.m.
+%
 % ok_to_inline_language(java, java). % foreign_language = java not implemented
 % ok_to_inline_language(asm, asm).   % foreign_language = asm not implemented
 % We could define a language "C/C++" (c_slash_cplusplus) which was the


I also have some documentation, not yet complete, but a start.
If you can see any areas in the documentation for IL that need to be
expanded, that would be nice.


Hi,


===================================================================


Estimated hours taken: 3
Branches: main

Begin documenting foreign_proc.

doc/reference_manual.texi:
	Add a section for foreign_proc (and other multi-language foreign
	language interfacing pragmas).
	At the moment we have some reasonable documentation for "C" and
	"IL" foreign_proc.


Index: doc/reference_manual.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/reference_manual.texi,v
retrieving revision 1.208
diff -u -r1.208 reference_manual.texi
--- doc/reference_manual.texi	2001/06/13 04:28:17	1.208
+++ doc/reference_manual.texi	2001/07/16 13:23:27
@@ -49,6 +49,7 @@
 @author Peter Schachte
 @author Simon Taylor
 @author Chris Speirs
+ at author Tyson Dowd
 @page
 @vskip 0pt plus 1filll
 Copyright @copyright{} 1995-2001 The University of Melbourne.
@@ -96,6 +97,8 @@
                       collections.
 * Semantics::         Declarative and operational semantics of Mercury
                       programs.
+* Foreign language interface:: The foreign language interface allows
+		      C code to be called from Mercury code.
 * C interface::       The C interface allows C code to be called
                       from Mercury code, and vice versa.
 * Impurity::          Users can write impure Mercury code.
@@ -4672,6 +4675,301 @@
 For example, they may wish to provide semantics in which function
 evaluation is lazy, rather than strict; semantics with a guaranteed
 fair search rule; and so forth.
+
+ at node Foreign language interface
+ at chapter Foreign language interface
+
+ at menu
+* Calling foreign code from Mercury::  How to implement a Mercury predicate
+				       or function as a call to foreign
+				       language code.
+* Language specific bindings       ::  Information specific to each
+  				       foreign language.
+ at end menu
+
+This chapter documents the new foreign language interface.
+This interface is not yet complete, and is not fully supported.
+It is documented here as an aid to the Mercury language developers.
+See the @pxref{C interface} chapter for the existing, supported C
+interface for Mercury.
+
+The syntax, documentation, behaviour and semantics of this chapter are
+subject to change without notice.
+
+ at node Calling foreign code from Mercury
+ at section Calling foreign code from Mercury
+
+Mercury procedures can be implemented using fragments of foreign language
+code using @samp{pragma foreign_proc}.
+
+ at menu
+* pragma foreign_proc::         Defining Mercury procedures using foreign code.
+* Foreign code attributes::   	Describing properties of foreign
+				functions or code.
+ at end menu
+
+ at node pragma foreign_proc
+ at subsection pragma foreign_proc
+
+A declaration of the form
+
+ at example
+:- pragma foreign_proc("@var{Lang}", @var{Pred}(@var{Var1}::@var{Mode1}, @var{Var2}::@var{Mode2}, @dots{}),
+        @var{Attributes}, @var{Foreign_Code}).
+ at end example
+
+ at noindent
+or
+
+ at example
+:- pragma foreign_proc("@var{Lang}", @var{Func}(@var{Var1}::@var{Mode1}, @var{Var2}::@var{Mode2}, @dots{}) = (@var{Var}::@var{Mode}),
+        @var{Attributes}, @var{Foreign_Code}).
+ at end example
+
+ at noindent
+means that any calls to the specified mode of @var{Pred} or @var{Func}
+will result in execution of the foreign code given in @var{Foreign_Code}
+written in language @var{Lang}.
+The foreign code fragment may refer to the specified variables
+(@var{Var1}, @var{Var2}, @dots{}, and @var{Var})
+directly by name.
+It is an error for a variable to occur more than once in the argument list.
+These variables will have foreign language types
+corresponding to their Mercury types, as determined by language and
+implementation specific rules.
+
+Additional restrictions on the foreign language interface code
+depend on the foreign language, the backend target, and the implementation.
+For more information, including the list of supported foreign languages and 
+the strings used to identify them, see the language specific information
+in the rest of this chapter.
+
+If there is a @code{pragma foreign_proc} declaration for any
+mode of a predicate or function, then there must not be either a mode
+specific clause, or a @code{pragma foreign_proc} 
+ at c or @code{pragma import} 
+declaration for every mode of the predicate or function.
+
+For example, the following piece of code defines a Mercury function
+ at samp{sin/1} which calls the C function @samp{sin()} of the same name.
+
+ at example
+:- func sin(float) = float.
+:- pragma foreign_proc("C", sin(X::in) = (Sin::out),
+        [may_call_mercury],
+        "Sin = sin(X);").
+ at end example
+
+If the foreign language code does not recursively invoke Mercury code,
+as in the above example, then you can use @samp{will_not_call_mercury}
+in place of @samp{may_call_mercury} in the declarations above.
+This allows the compiler to use a slightly more efficient calling convention.
+(If you use this form, and the C code @emph{does} invoke Mercury code,
+then the behaviour is undefined --- your program may misbehave or crash.)
+
+
+ at node Foreign code attributes
+ at subsection Foreign code attributes
+
+As described above, @samp{pragma import} and @samp{pragma c_code}
+declarations may include a list of attributes describing properties
+of the given foreign function or code.
+All Mercury implementations must support the attributes listed below.
+They may also support additional attributes.
+
+The attributes which must be supported by all implementations
+are as follows:
+
+ at table @asis
+
+ at item @samp{may_call_mercury}/@samp{will_not_call_mercury}
+This attribute declares whether or not execution inside this C code may
+call back into Mercury or not.  The default, in case neither is specified,
+is @samp{may_call_mercury}.  Specifying @samp{will_not_call_mercury}
+may allow the compiler to generate more efficient code.
+If you specify @samp{will_not_call_mercury},
+but the C code @emph{does} invoke Mercury code, then the behaviour is
+undefined.
+
+ at item @samp{thread_safe}/@samp{not_thread_safe}
+This attribute declares whether or not it is safe for multiple threads
+to execute this C code concurrently.
+The default, in case neither is specified, is @samp{not_thread_safe}.
+If the C code is declared @samp{thread_safe}, then the Mercury implementation
+is permitted to execute the code concurrently from multiple threads without
+taking any special precautions.  If the C code is declared
+ at samp{not_thread_safe},
+then the Mercury implementation must not invoke the code concurrently from
+multiple threads.  If the Mercury implementation does use multithreading,
+then it must take appropriate steps to prevent this.
+(The experimental multithreaded version of the current
+University of Melbourne Mercury implementation protects
+ at samp{not_thread_safe} code using a mutex:
+C code that is not thread-safe has code inserted around it to obtain
+and release a mutex.  All non-thread-safe C code shares a single mutex.)
+ at c XXX this can cause deadlocks if not_thread_safe C code calls
+ at c     Mercury which calls C
+ at end table
+
+Additional attributes which are supported by the Melbourne Mercury
+compiler are as follows:
+
+ at table @asis
+
+ at item @samp{max_stack_size(Size)}
+This attribute declares the maximum stack usage of a particular piece of
+code.  The unit @samp{Size} is measured in depend upon foreign language
+being used.  
+Currently this attribute is only used (and is in fact required) by the 
+ at samp{IL} foreign language interface, and is measured in units of stack
+items.
+
+ at end table
+
+ at c -----------------------------------------------------------------------
+
+ at node Language specific bindings
+ at section Language specific bindings
+
+Note that these bindings are specific to the Melbourne Mercury compiler,
+other compilers may choose to implement a different set of bindings.
+
+ at table @asis
+
+ at item @samp{C}
+Use the string "C" to set the foreign language to C.
+Default foreign language on all backends which compile to C.
+Only available on backends that do compile to C.
+
+ at item @samp{Managed C++}
+Use the string "MC++" to set the foreign language to Managed C++.
+Default foreign language on all backends which compile to IL.
+Only available on backends that compile to IL.
+Requires a Managed Extensions for C++ compiler installed.
+
+ at item @samp{C#}
+Use the string "C#" to set the foreign language to C#.
+Only available on backends that compile to IL.
+Requires a C# compiler installed.
+To use the pass mmc @samp{--use-foreign-language csharp} and
+ at samp{--backend-foreign-language csharp}.
+
+ at item @samp{IL}
+Use the string "IL" to set the foreign language to IL.
+Only available on backends that compile to IL.
+Requires an IL assembler installed.
+To use the pass mmc @samp{--use-foreign-language il} and
+ at samp{--backend-foreign-language il}.
+
+ at end table
+
+ at menu
+* Interfacing with C 		:: How to write code to interface with C
+* Interfacing with Managed C++ 	:: How to write code to interface with
+* Interfacing with C# 		:: How to write code to interface with C#
+* Interfacing with IL 		:: How to write code to interface with IL
+  				   Managed C++
+ at end menu
+
+ at node Interfacing with C
+ at subsection Interfacing with C
+
+The input and output variables will have C types corresponding
+to their Mercury types, as determined by the rules specified in
+ at ref{Passing data to and from C}. 
+
+The C code fragment may declare local variables, but it should not
+declare any labels or static variables unless there is also a Mercury
+ at samp{pragma no_inline} declaration (@pxref{Inlining}) for the procedure.
+The reason for this is that otherwise the Mercury implementation may
+inline the procedure by duplicating the C code fragment for each call.
+If the C code fragment declared a static variable, inlining it in this
+way could result in the program having multiple instances of the static
+variable, rather than a single shared instance.  If the C code fragment
+declared a label, inlining it in this way could result in an error due
+to the same label being defined twice inside a single C function.
+
+C code in a @code{pragma foreign_proc} declaration
+for any procedure whose determinism indicates that it could fail
+must assign a truth value to the macro @samp{SUCCESS_INDICATOR}.
+For example:
+
+ at example
+:- pred string__contains_char(string, character).
+:- mode string__contains_char(in, in) is semidet.
+
+:- pragma foreign_proc("C", string__contains_char(Str::in, Ch::in),
+        [will_not_call_mercury],
+        "SUCCESS_INDICATOR = (strchr(Str, Ch) != NULL);").
+ at end example
+
+ at code{SUCCESS_INDICATOR} should not be used other than as the target of
+an assignment.
+(For example, it may be @code{#define}d to a register, so you should not
+try to take its address.) 
+Procedures whose determinism indicates that that they cannot fail
+should not access @code{SUCCESS_INDICATOR}.
+
+Arguments whose mode is input will have their values set by the
+Mercury implementation on entry to the C code.  If the procedure
+succeeds, the C code must set the values of all output arguments
+before returning.  If the procedure fails, the C code need only
+set @code{SUCCESS_INDICATOR} to false (zero).
+
+ at node Interfacing with C#
+ at subsection Interfacing with C#
+
+Currently undocumented, sorry.
+
+ at node Interfacing with Managed C++
+ at subsection Interfacing with Managed C++
+
+Currently undocumented, sorry.
+
+ at node Interfacing with IL
+ at subsection Interfacing with IL
+
+Variables can be accessed from IL by using ldloc (for input) 
+stloc (for output).  Do not use a ret instruction or tail.call
+instruction within the handwritten IL code.
+
+The IL code in a @code{pragma foreign_proc} declaration
+for any procedure whose determinism indicates that it could fail
+must assign a truth value to the local variable @samp{succeeded}.
+For example:
+
+ at example
+:- pred same(int::in, int::in) is semidet.
+:- pragma foreign_proc("il", same(X::in, Y::in), [max_stack_size(2)], "
+	ldloc X
+	ldloc Y
+	ceq
+	stloc succeeded
+").
+ at end example
+
+ at code{succeeded} should not be used other than as the target of
+an stloc.
+Procedures whose determinism indicates that that they cannot fail
+should not access @code{succeeded}.
+
+Arguments whose mode is input will have their values set by the
+Mercury implementation on entry to the IL code.  If the procedure
+succeeds, the IL code must set the values of all output arguments
+before returning.  If the procedure fails, the IL code need only
+set @code{success} to false (zero).
+
+The Mercury types @code{int}, @code{float}, @code{char},
+and @code{string} are mapped to the Common Language Runtime types 
+ at code{int32}, @code{float64}, @code{char} and @code{System.String}
+respectively.
+
+Mercury variables which are polymorphically typed (e.g. whose type is a 
+type variables) will be passed as @code{System.Object} while all other
+Mercury variables are passed as @code{System.Object[]}.
+This mapping is subject to change and you should try to avoid writing
+code that relies heavily upon a particular representation of Mercury
+terms.
 
 @node C interface
 @chapter C interface





-- 
       Tyson Dowd           # 
                            #  Surreal humour isn't everyone's cup of fur.
     trd at cs.mu.oz.au        # 
http://www.cs.mu.oz.au/~trd #
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list