[m-dev.] foreign type syntax

Fergus Henderson fjh at cs.mu.OZ.AU
Tue Oct 30 01:20:03 AEDT 2001


On 30-Oct-2001, Tyson Dowd <trd at cs.mu.OZ.AU> wrote:
> On 29-Oct-2001, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> > On 29-Oct-2001, Tyson Dowd <trd at cs.mu.OZ.AU> wrote:
> > > If you specify the types using C syntax, you are going to have a bit of
> > > a hard time marshalling them to and from asm (you won't know how to
> > > generate type specifications in gcc's tree representation without
> > > parsing the type specifications).
> > 
> > What's wrong with just using `gcc__ptr_type_node' for all such types, and
> > handling the marshalling needed by generating appropriate C code in the
> > C wrapper function that we generate for C `pragma foreign_proc' procedures?
> 
> As I said:
> 
> > > I wouldn't be shocked if you could hack around this by using lots of
> > > hacky casts and some sneaky interfacing code, but it might be nice if
> > > you don't have to...
> 
> I think this solution falls into the hacky casts category.

What exactly do you think is "hacky" or "sneaky" about it?

> The problems are that it forces the user to box non-word sized values,

Who said the *user* has to do it?

I was thinking about having the Mercury compiler do it,
by generating appropriate C code to box non-word sized values
in the C wrapper function that we generate for C
`pragma foreign_proc' and `pragma export' procedures.

E.g. for

	:- type foo.
	:- pragma foreign_type(foo, c("Bar")).

	:- func example(foo) = foo.
	:- pragma export(example/1, "my_example").

then as well as compiling the code for example/1 to assembler,
it could generate some C wrapper code like the following:

	extern MR_Box example_2_f_0(MR_Box); /* defined in asm */
	template <class T> MR_Box MR_MAYBE_BOX(T); /* see below */
	template <class T> T MR_MAYBE_UNBOX(MR_Box); /* see below */

	/* C wrapper function for pragma export procedure */
	Bar my_example(Bar x) {
		MR_Box boxed_x = MR_MAYBE_BOX<Bar>(x);
		MR_Box y;
		y = example_2_f_0(x);
		return MR_MAYBE_UNBOX<Bar>(y);
	}

This is very similar to the C wrapper code that we already generate
when handling foreign language imports/exports for the asm backend.
The only difference is that I'm using slightly different boxing/unboxing
functions.  Here MR_MAYBE_BOX and MR_MAYBE_UNBOX are function templates,
which in C++ could be defined like this:

	template <class T>
	MR_Box
	MR_MAYBE_BOX(T value) {
		if (sizeof(T) > sizeof(MR_Box)) {
			T *p = MR_new_object(T, sizeof(T), name_of_T);
			*p = value;
			return p;
		} else {
			MR_Box b = 0;
			memcpy(&b, &value, sizeof(T));
			return b;
		}
	}
			
	template <class T>
	T
	MR_MAYBE_UNBOX(MR_Box b) {
		if (sizeof(T) > sizeof(MR_Word)) {
			return *(T *)b;
		} else {
			T value;
			memcpy(&value, &b, sizeof(T));
			return value;
		}
	}

Of course since we're generating C rather than C++, we'd couldn't use
templates; instead, we could have to have the Mercury compiler expand
out calls to these when generating the C code, or we could just use
macros rather than templates.  But you get the idea...

> and constrains the implementation such that it cannot carry the exact
> type, even if it otherwise would be able to.

Well, I don't think that is a problem for the asm backend,
or for untyped backends in general. 

> For the C backend it isn't such a big deal because everybody does hacky
> casts all the time, it often costs you nothing, and having the exact
> type around doesn't often help the compiler at all.

Hang on, I thought we were talking about the asm backend.  For the C
backend, the issue needn't arise at all, because you could just use the
C type name directly.

(Well, I guess you might want to use the same approach as in the asm
backend, just to preserve binary compatibility between the C and asm
backends.  But that would work too.)

> But for other
> backends (.NET, Java) it does, because casts are checked.

For the strongly-typed backends, the user can specify the appropriate type
name for the target language in the `pragma foreign_type' declaration,
and the Mercury compiler can just emit that type name in the generated
target code.

My suggestion about how to make things work for the asm backend
only applies to untyped backends.

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  | "... it seems to me that 15 years of
The University of Melbourne         | email is plenty for one lifetime."
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- Prof. Donald E. Knuth
--------------------------------------------------------------------------
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