extended foreign decls
Tyson Dowd
trd at cs.mu.OZ.AU
Wed Dec 6 22:57:02 EST 2000
On 06-Dec-2000, malcolm-ffi at cs.york.ac.uk <malcolm-ffi at cs.york.ac.uk> wrote:
> Fergus writes, triggered by my suggestion of "foreign value":
[ stuff deleted ]
>
> I propose that
> foreign code <language-id> { <code> }
> should simply cause the verbatim copying of the <code> part into a
> file to be compiled by the appropriate foreign compiler. That's all.
> Nothing fancy.
Actually I should point out that sometimes the Mercury FFI does do
something a little bit fancy at this point.
First is that for the Managed C++ backend (an extension of C++ to allow
it to generate garbage collected types and bytecode for the Microsoft
.NET Frameworks), it will automatically create a class and will insert
foreign_decls above the class definition, and foreign_codes inside the
class definition. Any predicate/function implementations are created as
static methods of the class.
> > :- pragma foreign_decls(c, "
> > #define _POSIX_SOURCE 1
> > extern int my_global;
> > ").
>
> Fergus, could you enlighten me some more about the difference between
> the foreign_decls and foreign_code pragmas? I'm afraid I can't
> immediately see why you have both.
There is a difference in the way such code is treated with respect to
optimization. We haven't formalized the exact definition of the
difference just yet -- this is an outstanding bug in our documentation.
The implementation is free to split each foreign_code fragment into (for
example) a separate file for each fragment, or to cross-module inline
such fragments. Mercury can do both of these optimizations.
But such code might need to share a common set of declarations.
So foreign_decls can be viewed as the "common" declarations for all foreign
code in that module. Each output file that uses a foreign_code fragment must
also include (possibly by #include, possibly by textual subsitution) the
foreign_decls part.
The declarations in the foreign_decls must not define any storage.
In C they will correspond very closely to a "header file".
The definitions in foreign_code must not rely upon definitions in any
other foreign_code. They can rely on declarations in the foreign_decls,
however.
> > the Mercury compiler extracts the foreign_decl and
> > foreign_code stuff, wrapping code in the second form of foreign_code
> > up inside appropriate function definitions, and puts them all in a
> > separate file that it then invokes the foreign language compiler on.
>
> And I would expect a Haskell compiler to do something similar. For C,
> Java, and the like, this would be fairly easy for the compiler writer
> to provide. But in the general case, I'd guess that there should be
> some sort of configurable "plugin" interface, by which an ordinary
> user could tell the the Haskell compiler about
> foreign language name: Wibble
> compiler name: wblc
> default options: -fno-flubble-mangling
> extra linking options: -lwibblelib
> and such like, so that they could use the FFI for whatever language
> they pleased.
This would (possibly) be enough to let them use whatever *compiler* they
want, but not necessarily whatever *language*. Different languages have
different calling conventions and marshalling requirements. I would
expect you also need a programmatic interface to allow plugins to be
written to handle these (sort of like writing a little code generator
for each language).
> > I certainly consider the mechanism that Mercury
> > uses to be elegant enough to be the official Mercury FFI,
> > and I hope our standards are not so much lower than yours ;-)
>
> I agree. In fact, I was mighty impressed to see that you'd already
> implemented my proposal in Mercury before I even proposed it. :-)
This is a pretty recent addition to Mercury. We've been thinking about
it for a while.
The need has come up because as we target new backends we need to
re-target the Mercury library, which involves re-writing a lot of C code
into {Java, Managed C++, C#, whatever}.
Also we found that we were doing almost all of this work anyway in the
MCORBA tool, because it interfaced with C++. MCORBA was generating C
code to call C++, and C++ code to talk to the CORBA ORB.
--
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