Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

calling conventions, variable-length parameter lists

3 views
Skip to first unread message

Togos

unread,
Aug 8, 2003, 2:29:47 PM8/8/03
to perl6-i...@perl.org
I want to be able to have a function with
this kind of signature:

func ($param1, *$otherparams)

AFAIK, there is no way to implement this
with the current calling conventions. You
would have to do something with variable
register IDs, which we don't have and which
would probably be a bad idea, anyway.

Maybe non_prototyped pcc subs should
always have all their parameters shoved
into an array? (and likewise for return
values :-). Hopefully most subroutine calls
will be prototyped, anyway, so it wouldn't
cause too much of an overall speed-hit, and it
would make many things a lot simpler (not
to mention even *possible*).

__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com

Luke Palmer

unread,
Aug 9, 2003, 1:29:14 AM8/9/03
to chumps...@yahoo.com, perl6-i...@perl.org
> I want to be able to have a function with
> this kind of signature:
>
> func ($param1, *$otherparams)

Uh.

What kind of signature? What does that mean?

If it's Perl 6,

sub ($param1, *$otherparams)

Is nothing special: it takes two parameters. Did you mean

sub ($param1, *@otherparams)

In which case, if it's prototyped, we stuff everything besides the
first parameter into a PMC representing @otherparams.

And if you meant something else, can't help ya.

Luke

Michal Wallace

unread,
Aug 9, 2003, 1:54:00 AM8/9/03
to TOGoS, perl6-i...@perl.org
On Fri, 8 Aug 2003, TOGoS wrote:

> I want to be able to have a function with
> this kind of signature:
>
> func ($param1, *$otherparams)
>
> AFAIK, there is no way to implement this
> with the current calling conventions. You
> would have to do something with variable
> register IDs, which we don't have and which
> would probably be a bad idea, anyway.
>
> Maybe non_prototyped pcc subs should
> always have all their parameters shoved
> into an array? (and likewise for return
> values :-). Hopefully most subroutine calls
> will be prototyped, anyway, so it wouldn't
> cause too much of an overall speed-hit, and it
> would make many things a lot simpler (not
> to mention even *possible*).

Why not make $otherparams a PerlArray?
I haven't gotten this far with python, but
I'm not sure I understand why that
wouldn't work?

Maybe there should be a register reserved
for an Array and another for a Hash (for
extra keyword arguments)?

Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-------------------------------------
contact: mic...@sabren.com
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--------------------------------------


Luke Palmer

unread,
Aug 9, 2003, 1:58:34 AM8/9/03
to chumps...@yahoo.com, perl6-i...@perl.org
> Luke said:
> >
> > sub ($param1, *@otherparams)
> >
> > In which case, if it's prototyped, we stuff
> > everything besides the
> > first parameter into a PMC representing
> > @otherparams.
> >
> > And if you meant something else, can't help ya.
> >
> > Luke
>
> Maybe I misunderstand what 'prototyped' means. I
> assume this means that the caller knows exactly what
> function it is calling, and so knows that how the
> callee expects its parameters to be organised (one in
> P5, the rest in an array in P6 or whatever). If you
> don't know exactly what function you're calling (like
> you got a Sub object out of a variable) then you have
> to do a non_prototyped call on it.
>
> now, assuming I got that right:
>
> Are you saying that it will be impossible to implement
> variable-length parameter lists to non-prototyped
> functions? Because that's kind of essential to at
> least a few languages. Ruby's 'print' function, for
> instance, has a signature that looks something like
> this:
>
> print(*stuff_to_print)
>
> Now, you take that method and pass it out to someone,
> and they want to call it. How are they to know that
> they're supposed to shove the parameters into an
> array? Now, if you *always* put all the parameters
> into an array for non_prototyped subs, this wouldn't
> be a problem.

Ahh, you're talking about unprototyped calls. Misunderstood you
there.

Sure that will be possible. You put the first 11 args in P5-P15, and
the rest in P4. You tell the sub that there are I2 parameters in the
registers, and I1 parameters in P4.

And the reasoning behind this, I think, is that for many subs,
interpreting prototyped and non-prototyped calls will need no
distinction: the same code can be used for both.

At first I was a little uneasy about using PMC registers for parameter
passing, lest the bookkeeping code should get in the way of efficiency
(of both code generation and the generated code itself). But, I
realized that this bookkeeping code would probably be there even if we
used an array, and registers are likely to be faster.

Plus, parameters to functions are likely to be used in the code of the
function (and likewise with return values), so we're just skipping
unloading the array into registers.

> But otherwise you can't host Ruby. And I *know* you
> don't plan to miss out on that, so obviously I'm
> missing something :-)

Meh. :-)

Luke

Leopold Toetsch

unread,
Aug 9, 2003, 3:13:09 AM8/9/03
to Luke Palmer, perl6-i...@perl.org
Luke Palmer <fibo...@babylonia.flatirons.org> wrote:

> Sure that will be possible. You put the first 11 args in P5-P15, and
> the rest in P4.

s/P4/P3/g

> Luke

leo

Michal Wallace

unread,
Aug 9, 2003, 4:50:08 AM8/9/03
to TOGoS, perl6-i...@perl.org
On Fri, 8 Aug 2003, TOGoS wrote:

> Unprototyped :-) I guess I didn't make that quite
> clear, enough.

Nah, you did. I just didn't think about it... :)
I think I see the problem now.


> maybe this kind of unprototyped function is expected
> to be uncommon enough that we can put up with having
> to emit code like the above... But unless people are
> really sure this is the way to go, it seems to me that
> we ought to be able to do better :-S Perhaps there
> could be a set of opcodes that allow called functions
> to treat the parameter list as a single array? That
> might be the best of both worlds. Kind of like the
> save_top op saving your code from 16 save operations.
> Except more important :-P
>
> sub print
> load_params P0 # all your parameters are now in $P0
> for p in P0
> print p
> end
> end
>

Hmm. That would be easy if there were an easy way
to loop through the registers...

reg = 5
for x = 1 to numparams:
$P0 = P[reg+x]

Leopold Toetsch

unread,
Aug 9, 2003, 5:35:48 AM8/9/03
to Michal Wallace, perl6-i...@perl.org
Michal Wallace <mic...@sabren.com> wrote:
> On Fri, 8 Aug 2003, TOGoS wrote:

>> Unprototyped :-) I guess I didn't make that quite
>> clear, enough.

Setup a param array, that's all.

> Hmm. That would be easy if there were an easy way
> to loop through the registers...

> reg = 5
> for x = 1 to numparams:
> $P0 = P[reg+x]

... which will never happen, because the register allocator can't track
this kind of reg access.

> Michal J Wallace

leo

Togos

unread,
Aug 9, 2003, 1:47:25 AM8/9/03
to Luke Palmer, perl6-i...@perl.org
Luke said:
>
> sub ($param1, *@otherparams)
>
> In which case, if it's prototyped, we stuff
> everything besides the
> first parameter into a PMC representing
> @otherparams.
>
> And if you meant something else, can't help ya.
>
> Luke

Maybe I misunderstand what 'prototyped' means. I


assume this means that the caller knows exactly what
function it is calling, and so knows that how the
callee expects its parameters to be organised (one in
P5, the rest in an array in P6 or whatever). If you
don't know exactly what function you're calling (like
you got a Sub object out of a variable) then you have
to do a non_prototyped call on it.

now, assuming I got that right:

Are you saying that it will be impossible to implement
variable-length parameter lists to non-prototyped
functions? Because that's kind of essential to at
least a few languages. Ruby's 'print' function, for
instance, has a signature that looks something like
this:

print(*stuff_to_print)

Now, you take that method and pass it out to someone,
and they want to call it. How are they to know that
they're supposed to shove the parameters into an
array? Now, if you *always* put all the parameters
into an array for non_prototyped subs, this wouldn't
be a problem.

But otherwise you can't host Ruby. And I *know* you


don't plan to miss out on that, so obviously I'm
missing something :-)

__________________________________

Togos

unread,
Aug 9, 2003, 2:19:53 AM8/9/03
to Luke Palmer, perl6-i...@perl.org
Luke said:
> Plus, parameters to functions are likely to be used
> in the code of the
> function (and likewise with return values), so we're
> just skipping
> unloading the array into registers.

OK. That makes sense, but my problem is:
in the case that the called function *does* treat its
parameter list as an array, it's going to have to have
some ugly code:

(pretend this is some kinda pseudo-imcc)
sub print
if numparams >= 1
print P5
end
if numparams >= 2
print P6
end
if numparams >= 3
print P7
end
...whole bunch of checks and prints...
if numparams >= 16
for p in P4
print p
end
end
end

maybe this kind of unprototyped function is expected
to be uncommon enough that we can put up with having
to emit code like the above... But unless people are
really sure this is the way to go, it seems to me that
we ought to be able to do better :-S Perhaps there
could be a set of opcodes that allow called functions
to treat the parameter list as a single array? That
might be the best of both worlds. Kind of like the
save_top op saving your code from 16 save operations.
Except more important :-P

sub print
load_params P0 # all your parameters are now in $P0
for p in P0
print p
end
end

Anyway, yeah. My ConfigScript interpreter would like
that. ;-)

TOGoS

unread,
Aug 9, 2003, 10:33:31 PM8/9/03
to
Leopold Toetsch wrote:

> Michal Wallace wrote:
> > On Fri, 8 Aug 2003, TOGoS wrote:
>
> >> Unprototyped :-) I guess I didn't make that quite
> >> clear, enough.
>
> Setup a param array, that's all.

Uhhh... OK. What's that? I've never
heard of such a thing.

test@ing...

Togos

unread,
Aug 10, 2003, 1:08:12 PM8/10/03
to perl6-i...@perl.org
> > Unprototyped :-) I guess I didn't make that quite
> > clear, enough.
>
> Setup a param array, that's all.
>
> leo

Umm... OK. Here's what I've done: I created 2
functions that I can use when dealing
with variable-length parameter lists. One
to turn an array into pcc-compliant parameters,
and one to turn incoming pcc-params into an array.
AFAIK, these would also work for returns, as
(especially with the CPS calling conventions)
returns are almost identical to calls.
Tell me if you think this is reasonable :)

.sub _main # puts params in array, then calls
# _array_to_params to make
# pcc-compliant parameters

# this is eequivalent to Ruby:
# array = ["I", "like", "pickles"]
# printstuff(*array)

newsub P0, .Sub, _printstuff
newsub P1, .Continuation, ret1
$P1 = new PerlArray
push $P1, "I"
push $P1, "like"
push $P1, "pickles"
P16 = $P1
call _array_to_params
# unfortunately we can't use pcc_begin, etc.
# here because we set up the params manually
I3 = -1
I4 = 0
invoke
ret1:
end
.end

.sub _main2 # alternative main that just
# calls printstuff as a pcc_sub
newsub $P0, .Sub, _printstuff
newsub P1, .Continuation, ret1
$P1 = new PerlString
$P1 = "I"
$P2 = new PerlString
$P2 = "like"
$P3 = new PerlString
$P3 = "pickles"
.pcc_begin non_prototyped
.arg $P1
.arg $P2
.arg $P3
.pcc_call $P0, P1
ret1:
.pcc_end
end
.end

.pcc_sub _printstuff non_prototyped
# prints all parameters, separated by space,
# and followed by a newline

# equivalent to Ruby:
# def printstuff(*stuff)
# for t in stuff
# print t, " "
# end
# print "\n"
# end

P16 = new PerlArray
call _params_to_array
$I0 = 0
$I1 = P16
loopstart:
if $I0 == $I1 goto done
$S0 = P16[$I0]
print $S0
print " "
$I0 = $I0 + 1
goto loopstart
done:
print "\n"
.pcc_begin_return
.pcc_end_return
.end

# here are the params <-> array functions

.sub _params_to_array
# called at the beginning of a function if it
# has been passed
# parameters with the calling conventions.
# Assumes all PMCs.
# puts results in existing array in P16

# munges I0, I3, P4. uses them for
# temporary variables

I0 = I1 + I2 # total length of array
assign P16, I0
unless I2 >= 1 goto done
P16[0] = P5
unless I2 >= 2 goto done
P16[1] = P6
unless I2 >= 3 goto done
P16[2] = P7
unless I2 >= 4 goto done
P16[3] = P8
unless I2 >= 5 goto done
P16[4] = P9
unless I2 >= 6 goto done
P16[5] = P10
unless I2 >= 7 goto done
P16[6] = P11
unless I2 >= 8 goto done
P16[7] = P12
unless I2 >= 9 goto done
P16[8] = P13
unless I2 >= 10 goto done
P16[9] = P14
unless I2 >= 11 goto done
P16[10] = P15
unless I1 >= 0 goto done
I0 = 0 # temp
I3 = 11 # temp
loopstart:
P4 = P3[I0]
P16[I3] = P4
I0 = I0 + 1
I3 = I3 + 1
unless I0 == I1 goto loopstart

done:
ret
.end

.sub _array_to_params
# turn the array of PMCs in P16 into a
# set of parameters

# only sets I1 (num overflow)
# and I2 (num pmc regs)
# and I3 (overflow params)
# munges I0, I3, P4. uses them for
# temporary variables

I0 = P16 # get length of incoming array

unless I0 >= 1 goto nooverflow
P5 = P16[0]
unless I0 >= 2 goto nooverflow
P6 = P16[1]
unless I0 >= 3 goto nooverflow
P7 = P16[2]
unless I0 >= 4 goto nooverflow
P8 = P16[3]
unless I0 >= 5 goto nooverflow
P9 = P16[4]
unless I0 >= 6 goto nooverflow
P10 = P16[5]
unless I0 >= 7 goto nooverflow
P11 = P16[6]
unless I0 >= 8 goto nooverflow
P12 = P16[7]
unless I0 >= 9 goto nooverflow
P13 = P16[8]
unless I0 >= 10 goto nooverflow
P14 = P16[9]
unless I0 >= 11 goto nooverflow
P15 = P16[10]
unless I0 >= 12 goto nooverflow

overflow:
I2 = 11 # num PMC regs
I1 = I0 - 11 # num overflow
P3 = new PerlArray
assign P3, I1
I0 = 0 # temp
I3 = 11 # temp
loopstart:
P4 = P16[I3]
P3[I0] = P4
I0 = I0 + 1
I3 = I3 + 1
unless I0 == I1 goto loopstart

nooverflow:
I2 = I0 # num PMC regs
I1 = 0 # num overflow

done:
ret
.end

Togos

unread,
Aug 11, 2003, 1:11:23 PM8/11/03
to perl6-i...@perl.org

Leopold Toetsch wrote:

> TOGoS wrote:
>>>> Unprototyped :-) I guess I didn't make that
>>>> quite clear, enough.
>>>
>>> Setup a param array, that's all.
>>>
>>> leo
>> Umm... OK. Here's what I've done: I created 2
>> functions that I can use when dealing
>> with variable-length parameter lists. One
>> to turn an array into pcc-compliant parameters,
>
> Wrong approach AFAIK. Just pass the array as one
> param. Its like the
> slurpy *@_ in Perl6. In printstuff you then iterate
> over this array and
> print items.
>
> leo

But how is the caller supposed to know to do that?
Remember, I plan to get the 'printstuff' function by
saying:

find_lex P0, "printstuff"

As far as the caller knows, the function it's calling
could have a signature like

func (thing1, thing2, *morethings)

or like

func (*lotsofparamshere)

That's the problem with being unprototyped :-)

How will Perl6 deal with anonymous subs with
slurpy params? And while we're at it, how will
it deal with anonymous subs with named params?
That one's even harder ;-)

Togos

unread,
Aug 11, 2003, 1:35:04 PM8/11/03
to perl6-i...@perl.org

--- TOGoS <chumps...@yahoo.com> wrote:
>
> Leopold Toetsch wrote:
> > TOGoS wrote:
> >>>> Unprototyped :-) I guess I didn't make that
> >>>> quite clear, enough.
> >>>
> >>> Setup a param array, that's all.
> >>>
> >>> leo
> >> Umm... OK. Here's what I've done: I created 2
> >> functions that I can use when dealing
> >> with variable-length parameter lists. One
> >> to turn an array into pcc-compliant parameters,
> >
> > Wrong approach AFAIK. Just pass the array as one
> > param. Its like the
> > slurpy *@_ in Perl6. In printstuff you then
> iterate
> > over this array and
> > print items.
> >
> > leo
>
> But how is the caller supposed to know to do that?
> Remember, I plan to get the 'printstuff' function by
> saying:

Oh. Nevermind. I see what you mean, now. Don't do

printstuff(*params)

, but just do

printstuff(params)

instead. I can't think of an example off the
top of my head where this wouldn't work, but
it will happen that people'll want to use
variable-length parameter lists on unprototyped
functions (like the anonymous perl6 slurpy
function). Also, Ruby's 'print' works
like this. So it will have to be dealt with.

0 new messages