On Sun, 14 Sep 2003, Steve Fink wrote: > I'm not sure how to use the current pdd03's calling conventions to > implement what I want right now. Let's consider Perl6: > > sub f ($a, $b) { ... } > f(1, 2); > &f(1, 2); > > (I'm not sure if that is correct Perl6 code -- what I mean is that I > call f once with a perl-level prototype, and once without. Note that a > perl-level prototype may or may not correspond directly to pdd03's > notion of a prototype, and most probably will not. See below.) > > In the first case, it's easy -- I just do > > I0 = 1 # have prototype > I5 = 1 > I6 = 2
Nope. f is declared as taking two PMCs, so that'd be P5 and P6. > &f([EMAIL PROTECTED], 2); > > Where should I put the value 2? If @x is empty, then it has to go into > P5 in order for the caller to find it. [Snip] > Because we have only up to P15 before we start overflowing into the P3 > aggregate, this is doable. &f([EMAIL PROTECTED], [EMAIL PROTECTED]) isn't even much > worse; it just > means you have to concatenate @x and @y into a single destination > array and then do the same thing. But it's darn ugly and slow. Dunno about slow, but it is a bit ugly. Indirect register access can help there. > Another question for something that will soon be related: why does I1 > contain the number of elements in P3? All of our current aggregates > can report their current size just fine, and that doesn't seem like > it's a difficult restriction on the types of aggregates that may be > used for P3. Unless it's useful to use only a subset of an aggregate > as function arguments? It seemed to make sense at the time. > But that's really just shifting the burden to the receiving end, which > will now have to filter P5..P(5+L1-1), P3[0..] into the appropriate > local variables. So what would be even easier, and probably just as > fast, would be to say that unprototyped functions pass *all* of their > arguments through the overflow array. I considered that. The standard is set up for two common cases: 1) The function is prototyped as taking a list of PMCs, with 10 or fewer named parameters passed in 2) The function is unprototyped but can be found, by static code inspection, to be taking 10 or fewer named parameters. In this case, the scheme, while a pain on the calling end, makes the callee end very simple--the parameters map directly to registers. If you've a declaration: sub foo($bar, $baz) { } or sub foo { my ($bar, $baz) = @_; } two common perl idioms, then the compiler can map $bar to P5 and $baz to P6 directly, without having to do anything. Since the majority of the subs and/or methods behave like this--taking a small number of parameters, it's a win on the callee end. As for the caller... the majority of function/method calls are also made with a fixed list of unflattened parameters, in which case making a call like: foo($xyzzy, $plugh); is a matter of: fetch_lex P5, '$xyzzy' fetch_lex P6, '$plugh' call 'foo' (Yeah, I know, sloppy, but you get the idea) Yes, this does mean that dealing with splatted arrays and hashes is a bigger pain than it ought otherwise to be, but that's supposed to be (and generally is now) an uncommon occurrence. That doesn't mean we can't give engine support to it, however--adding in an op that took a parameter array in P3 and took the first few items out and loaded them into P5-P15 in one go (and a corresponding version that respected the calling conventions and took the elements out of P5-15 and put them onto the beginning of the array in P3, or any other P we might want) Having the parameters in the registers will make things easier for multimethod dispatch as well, which is a not-inconsiderable issue. > I suppose that was a question for the language list. But then I'd have > to read the language list. A fate worse than razor burn, to be sure. Possibly one worse than really bad Mexican food, but either way I'd not wish it on anyone. :) Dan