Leo,

Consider this (as I'm sure you already have)...

    class ClassA;
    method meth($i is int)   { ... }

    class ClassB;
    method meth($f is float) { ... }

    module main;
    my $obj = (rand(1.0) < 0.5? ClassA : ClassB)->new;
    $obj->meth(1);

Perl's going not going to be able to bind to a HLL prototype, much less
a low-level one. Even if it could bind to the HLL prototype, it has to
protect against mutation of the method. Either perl6 recompiles the
caller when a new version of the sub is linked in, or perl6 uses a
calling convention that always works: Unprototyped.

Prediction: perl6 winds up using One True Parrot Unprototype for ALL of
its method and sub calls.

The parrot calling conventions thus become rather academic to Perl. The
target languages under consideration just aren't going to get little
mileage out of them.


Leo and Dan,

As for encoding varargs in the parrot calling conventions, parameter
counts are very much useless--they're might as well be a very poor
one-way hash of the prototype. Have you considered using 4 bitfields to
indicate what register parameters are what? E.g.

    prototype: int    in In+0,
               float  in Nn+1,
               string in Sn+2,
               string in Sn+3,
               float  in Nn+4,
               int    in In+5,
               PMC    in Pn+6
    
    Iregs = (1 << n+0) + (1 << n+5) = 0b...0100001...
    Fregs = (1 << n+1) + (1 << n+4) = 0b...0010010...
    Sregs = (1 << n+2) + (1 << n+3) = 0b...0001100...
    Pregs = (1 << n+6)              = 0b...1000000...

This burns no more space in the register file than the 4 parameter
counts, and it doesn't throw away ordering data. Downside: Counting
total number of arguments is harder.

Four 32-bit bitfields match the 4 sets of 32 registers, so even if the
set of registers used for passing parameters grow, this convention is
safe. Overflow parameters... Well, figure something out; there's plenty
of space in the overflow array. (4 binary Sregs with likewise bitfields?
Or just use the PMC type.)

But imposing the overhead of 4 Ireg assignments on the caller and 4 Ireg
compares and branches on the callee at the beginning of every routine,
just to check that the register conventions are right? Don't think
that's a good idea. What's the recovery scenario going to be, anyhow? To
blow up... What a waste of cycles: It's a needless toll for 99.999999%
of calls. Check that the prototype is right when the sub is loaded into
the runtime: In effect, throw the exception at link time. Then this
vararg cruft can be cut out of the common case. That is, support 3
parrot calling conventions:

  - unprototyped ("your parameters are in an array")
  - prototyped ("what you want in the register file is there")
  - vararg ("I've documented what I put in the register file")


But, honestly, a vararg prototype string in an Sreg probably makes more
sense than either 4 register counts or 4 register masks. It avoids
burning integer registers--the most useful part of the register file for
the sort of low-level code which will actually USE parrot prototypes. It
can be set up by the caller with a single string constant load. It can
be checked by the callee with a single string compare instruction (if
the vararg list is actually static). It's easy to reflect, too.

--
 
Gordon Henriksen
IT Manager
ICLUBcentral Inc.
[EMAIL PROTECTED]


> -----Original Message-----
> From: Dan Sugalski [mailto:[EMAIL PROTECTED] 
> Sent: Friday, November 14, 2003 10:34 AM
> To: Leopold Toetsch
> Cc: [EMAIL PROTECTED]
> Subject: Re: Calling conventions. Again
> 
> 
> On Fri, 14 Nov 2003, Leopold Toetsch wrote:
> 
> > Dan Sugalski <[EMAIL PROTECTED]> wrote:
> >
> > > I've seen it with some depressing regularity over the 
> years. It generally
> > > takes the form of an upgrade to a library that breaks existing
> > > executables, something we're going to have to deal with 
> as we're looking
> > > to encourage long-term use of bytecode-compiled programs.
> >
> > This seems to me the same, as that strcpy(3) should be 
> guarded against
> > wrong argument count at runtime. But swapped 
> destination/source can't be
> > detected anyway ;)
> 
> We can't detect bugs like that, true. But we can detect when 
> someone calls
> us with two arguments and someone has, in the mean time, 
> "helpfully" added
> an optional length arg to strcpy.
> 
> > > ... But there are
> > > several issues here:
> >
> > > 1) vararg calls with non-pmc registers involved
> >
> > I already did propose the syntax:
> [Snip]
> > at least, so that runtime checks can be omitted for certain cases.
> 
> No IMCC syntax that's purely compile-time is of any help 
> here. The code
> doing the calling
> 
> > > 2) Runtime modification of sub definitions
> >
> > are evil, forbidden, disallowed. This just can't work.
> 
> True, false, false. It happens, in some cases a *lot*. This is perl,
> python, and ruby we're talking about, where changing the 
> definition of a
> sub is as trivial as a reference assignment into a global 
> hash. It's easy,
> people do it. Often, in some cases. (Heck, I've done it)
> 
> Methods also cause significant headaches, since there are 
> *no* signatures
> available to the calling code, as there's no way for it to look up the
> signature. (And yeah, that's a reasonable argument for all 
> method calls to
> be unprototyped, but I'm not sure I want to place that restriction in
> right now)
> 
> > > 3) Drift in interface definitions
> >
> > needs code adaption and recompiling.
> 
> To operate properly, yes. To fail properly, no.
> 
> > > ... Because of that we have to pass in sufficient information to
> > > validate things at the interface, which means at least arg counts.
> >
> > If someone changes libc behind the curtain in an incompatible way,
> > existing programs probably just segfault.
> 
> Yes, they do. For us that's unacceptable--we have to be able 
> to let code
> provide at least some boundary guarantees with safe failure modes.
> 
> > > If someone wants to propose we have an alternate, more 
> static convention
> > > that lends itself better to one-off static linking with link-time
> > > signature checking for verification, which is what the 
> complaints all seem
> > > to allde to, well... go ahead and if you do we'll see 
> where we go from
> > > there.
> >
> > e.g. version checking at program load.
> 
> Which doesn't solve the problem. Ask for version 1.20 or higher, get
> version 1.33, and find the interface has changed. (An 
> interface that was
> fine in versions 1.20 through 1.32) This happens, with some frequency.
> 
>                                       Dan
> 
> --------------------------------------"it's like 
> this"-------------------
> Dan Sugalski                          even samurai
> [EMAIL PROTECTED]                         have teddy bears and even
>                                       teddy bears get drunk
> 
> 


Reply via email to