[m-dev.] for review: add MC++ implementation of library and runtime

Tyson Dowd trd at cs.mu.OZ.AU
Thu Dec 21 08:44:06 AEDT 2000


On 18-Dec-2000, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> Tyse, Tyse, you sound very defeatist.
> All this working on Microsoft products must be getting you down ;-)

This got me down, but what pissed me off was the GNU Make has
undocumented limitations in pattern substitutions.

> You don't have to put commas in the "text" portion of foreach.
> You could use e.g. the following
> 
> 	ALL_DLLS_BASE  = $(ALLDLLS:%.dll=%)
> 	EMBED_ALL_DLLS = $(foreach dll_name,$(ALL_DLLS_BASE),$(EMBED_ONE_DLL))
> 	EMBED_ONE_DLL  = /embed:$(dll_name).dll,$(dll_name),Y
> 
> which puts the commas in a separate variable.
> This technique is even recommended by the GNU Make manual:
> 
> |  When TEXT is complicated, you can improve readability by giving it a
> |  name, with an additional variable:

This is a little more readable, I'll use it instead.

> Or you could use $(shell) and sed.  Or you could even write a C
> program to generate that part of the Makefile.  There's lots of
> possibilities.

But they would all generate raised eyebrows at review time...

> > I only bothered with ILASM to find out the SDK path, so I wasn't going
> > to bother with al just yet.
> 
> OK.  But it might be good to just define
> 
> 	AL = al
> 
> and then use $(AL) rather than hard-coding `al'.  It probably doesn't
> make much difference in this case, but in general it's good style to
> avoid hard-coding such names whenever possible.

Done.

> > > The numbering of the generic_res_call functions is odd;
> > > why is it called `call3', rather than `call0'?
> > 
> > Because it implements a generic call of an arity 3 procedure with a
> > result.  It's a little like call/3.
> 
> call/3 has three arguments, but generic_res_call3 has *four*
> arguments.  Isn't it more like call/4?

Yes.

To keep you happy, I've renamed them generic_result_call_[4-9]
and generic_call_[4-9].

> 
> > > > +:- pragma foreign_code("MC++", copy(_X::in, _Y::uo),
> > > > +	[may_call_mercury], "
> > > > +	MR_Runtime::SORRY(""foreign code for this function"");
> > > > +").
> > > 
> > > I tried to refrain from commenting on calls to SORRY(), but this one
> > > looks fairly simple to implement: isn't there a Clone() function or
> > > something like that in System.Object?
> > 
> > Yes, but it does shallow copies.  There are some Clone() methods that do
> > 
> 
> That do what?
> That do shallow copies?

shallow copies, and some of them do deep copies.  Clone() looks pretty
much useless.

> 
> If so, please add an XXX comment mentioning that.
> 
> > I've fixed mr_convert and MR_Runtime.  They are now
> > mercury::runtime::convert and mercury::runtime::errors.
> > 
> > I've also replaced the mercury__builtin__ with mercury::builtin::
> 
> Fantastic, thanks.

There are still things called mercury::builtin::__Unify__<whatever>
but that's not so bad.

Compiler generated Unify and Compare still use the old naming
techniques.

> > Sounds like a great idea.  The MC++ compiler won't accept it thought.
> > I can get it to give an internal compiler error, or it complains that
> > mercury::MR_BoxedFloat isn't a class/struct/union.
> 
> How about a #define?

That works.

> > > > +:- pragma foreign_code("MC++", "
> > > > +	static MR_Word ML_io_stream_names;
> > > > +	static MR_Word ML_io_user_globals;
> > > > +	static int next_id;
> > > > +").
> > > 
> > > Hmm...  you're relying here on foreign "MC++" code not being inlined
> > > into different translation units (like we do with foreign "C" code).
> > > 
> > > I think at least it is worth a comment explaining why the MC++
> > > version is different from the C version.
> > 
> > Either I don't understand this comment, or you are confusing
> > foreign_code with foreign_decls.
> >
> > foreign_code cannot be inlined into multiple different translation units.
> > It can only appear once.  It has to be put into a single
> > translation unit.  No other foreign_code can rely on it being put into
> > it's own translation unit (and it could be said that I'm breaking this
> > rule because I don't write a separate decl).
> > 
> > foreign_*decls* can be inlined into multiple different translation units.
> 
> I was worried about the foreign_code/4 (i.e. foreign_proc) procedures
> that reference that definition being inlined into other translation
> units in which the definition is not visible, not about that
> definition itself being inlined.  Don't you need a separate
> foreign_decl of some kind to handle that case?

Yes.

But that case doesn't occur in the .NET backend.

I'm not sure if it ever will for managed C++ -- it doesn't make any
sense to "inline" a foreign_proc if you are just going to have to put
the body of it into a separate file and compile it separately anyway
(e.g. take a foreign_proc from foo.m, inline it into bar.m, which puts
the body of it into a method in bar__c_code.cpp).
Where is the "inlining" in that?

The only time you can really inline is when your foreign code language
matches your backend language.

So the upshot is that I'm not sure whether we should require separate
decls for this case.

The problem isn't such an issue for C++ -- you can just add the decls
and off you go.  But in Java there are no decls.  So the rule about
whether you need to have decls will almost certainly be language
dependent.

> Are those those declarations declaring static class members,
> or are they static variables at namespace scope?

In this implementation, static class members.

A real C++ backend might do it differently, though.

> > It's not currently defined because I'm deliberatley not using the
> > "standard" system libraries (just in case they drag in more non .NET
> > stuff).
> 
> Could you explain that rationale in a bit more detail?
> What would be wrong with dragging in more non .NET stuff?
> (I don't disagree with you, I'd just like to understand
> the issue better.)

I'm a lazy coward and I don't want to face the music if I don't have to.

The MC++ compiler has a tendency to try to drag in libraries when you
use things (e.g. the special things you have to add to stop it dragging
in the float library).

> <stddef.h> should be pretty safe in that respect.
> In ANSI/ISO C and POSIX, it only defines the following:
> 
> 	macro     NULL
> 	macro     offsetof()
> 	typedef   ptrdiff_t
> 	typedef   size_t
> 	typedef   wchar_t
> 
> ANSI/ISO C requires that system headers like <stddef.h> do not
> drag in stuff from other header files into the user's namespace.

Ok, this looks like it is working ok.

-- 
       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-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