extended foreign decls

Tyson Dowd trd at cs.mu.OZ.AU
Wed Dec 6 20:54:26 EST 2000

On 06-Dec-2000, Marcin 'Qrczak' Kowalczyk <qrczak at knm.org.pl> wrote:
> > As people have pointed out, we need to avoid being totally C-centric,
> > which is why there needs to be a language identifier attached.
> hsc2hs is of course C centric, but for another language simply
> a different preprocessor would be used.
> Anyone wants to design hsc++2hs? :-)  But currently you would have
> to write extern "C" wrappers for all native C++ functions, methods,
> constructors, destructors, conversions, casts through virtual
> inheritance...

Perhaps should talk about that the approach I intend to take to allow
Mercury's FFI to interface to multiple languages.  This is intended
to avoid having to write extern "C" wrappers by hand.

Each backend (e.g. gcc C code, Java, MS IL) will have a "preferred"
foreign language.  If the compiler actually compiles to this language
it could be possible to inline foreign language code snippets
(this happens with the C backend, and could happen with IL assembler
or Java foreign code too).  The compiler knows how to interface Mercury
code to this preferred foreign language.

For ("preferred" language, foreign language) pair, you define an
"extrusion".  This defines how to generate the appropriate code to 
interface with one foreign language in another.  For example, for
predicate/function `foo' with an implementation written in C++ code,
with a C code backend:
	- put the `foo' foreign code snippet inside a C++ function
	  `foo_cpp' with C linkage (e.g. use extern "C" wrappers around the
	- generate a foreign code snipped `foo_c' that calls C++ function
	  `foo_cpp' (so you need to be able to generate a call in C)
	- use `foo_c' as the implementation of `foo'.

After extrusion, all remaining C++ code gets shoved into a
.cpp file, which will be compiled and linked.  The trick of
automatically putting the code into a separate file, generating the
correct linkage and calling it should work fine for most compiled
languages if C is available as a backend.  Note that each C++ fragment
gets translated into a new C++ fragment plus a C fragment.

Say you wanted to do the same with Python:
	- generate a foreign_decl("C", "#include <Python.h>")
	- generate a C fragment that looks something like:

		PyObject *locals, *globals, *result;
		char * pythoncode = 
			"... code for foo, using local variables as parameters ...";
		locals = ... code for marshalling parameters into locals ...
		globals = ... any useful globals ...
		result = PyRun(pythoncode, 0, globals, locals);
		... marshall result if necessary ...	
	- use this C fragment as the implementation 

There are of course different ways of doing this that have different
trade-offs, but this approach will work pretty well for any interpreter
with a C API.  Note that each Python fragment gets translated into a single
C fragment -- the python code disappears into a C string.  After
extrusion the Mercury compiler will never see any python code, just C

The build environment would define compilers, flags, link options, etc.
The exact supported languages and combinations is implementation
specific (and installation specific -- if you don't have the compilers,
obviously it's not going to work).

The compiler needs to know how to interface Mercury to a single
"preferred" foreign language (probably one per backend).

The compiler (or external tool or plugin) also needs to know how to 
generate enough of this "preferred" foreign language to call each
supported non-preferred language.  Finally it needs to know
what to do with any "left-over" non-preferred code after extrusion
(e.g. put it into a separate file).

The neat thing is that you should be able to chain the extrusions.
E.g. if we write code to let the Mercury compiler extrude C into Java
(so we can use C code in the Java backend), then we can extrude Python
to C and hence we can call Python from Java.  Getting the compile flags and
link options right for all of this could be quite tricky, of course,
because build and link tools are rarely orthogonal enough to handle
this nicely.

We also need to handle which language to prefer if there are multiple
workable implementations available.

This is a research proposal that is half implemented at the moment
(the extrusion is still not quite finished).

       Tyson Dowd           # 
                            #  Surreal humour isn't everyone's cup of fur.
     trd at cs.mu.oz.au        # 
http://www.cs.mu.oz.au/~trd #

More information about the FFI mailing list