Re: [Fwd: [perl6.internals] Re: [PROPOSAL] calling convention abstraction]

2005-04-24 Thread Leopold Toetsch
[ CC'ed to list again ]
Roger Hale wrote:
Leo,

I find myself on the horns of a variant of Warnock's dilemma here:
Sorry about that.
Having done my best to clarify why I think the return context cannot 
helpfully be attached to either @IN_ARGS nor @OUT_ARGS, the thread has 
no further response from you. 
The subject of the thread was calling convention abstraction. My 
proposal was about one possible way to go, and I'd like to thank you for 
the input. But there is much more then the one discussed issue.

I'd like to have HLL folks create a workable scheme for abstract and 
extendible calling conventions that take all the various HLL-specific 
extensions (*args, **kw, default values, Perl context, lisp variable 
argument amount, tail calls...) into account. If each HLL does a 
function or method call in a different way, we can forget any 
interoperbility.

The current scheme is too limit and worse, as defined in terms of PASM, 
not changable at all. This is a serious drawback for future changes and 
optimization of the Parrot VM.

leo


Re: [PROPOSAL] calling convention abstraction

2005-04-13 Thread Roger Hale
Bob Rogers wrote:
So it sounds like we are all saying the same thing now?
Well, two of us at least (with me coming from the peanut gallery)... Leo 
has his own say, and it's his proposal.

regards,
 Roger


Re: [PROPOSAL] calling convention abstraction

2005-04-12 Thread Bob Rogers
   From: Roger Hale [EMAIL PROTECTED]
   Date: Mon, 11 Apr 2005 09:30:32 -0400

   Bob Rogers wrote:
   From: Roger Hale [EMAIL PROTECTED]
   Date: Thu, 07 Apr 2005 04:23:41 -0400

   Leopold Toetsch wrote:
Roger Hale [EMAIL PROTECTED] wrote:

   Leopold Toetsch wrote:
   
   As @ARGS (or @IN_ARGS, @OUT_ARGS) is being stored in the context, and
   that context is defacto the continuation, yes - a tail-call would
   inherit this information.

   But as each tail-call supplies a new @ARGS, how can this be the case?

We would have two parts in the context: @IN_ARGS, @OUT_ARGS. The
Ctailcall opcode can preserve that part with the return context.

   It seems to me that both @IN_ARGS and @OUT_ARGS get used for other 
   things (the tail-calls' arguments) in a chain of tail-calls.

The definition of a tail call is that it returns its callee's results
back to its caller unmodified.

   Agreed, but...

So if @OUT_ARGS is used for other
things, then it's not a tail call.

   I don't understand.  @OUT_ARGS aren't the arguments returned (to my 
   understanding), they're the arguments to the next function in sequence.

My mistake; I had thought @OUT_ARGS meant results.  I see I didn't
read Leo's original proposal carefully enough, and you were just
following his terminology; my apologies.  I agree that information about
return context can't live in @ARGS (in or out) directly.

   . . . but the continuation (I propose) does; and this continues to be
   good for whoever wants to know: the return object holds the return
   context.

   No?

   regards,
 Roger

I believe so, but I think this is what Leo meant by ... that context is
defacto the continuation.  There doesn't need to be a separate return
object because it would be one-to-one with the continuation.

   Sorry, by return object I was only meaning the continuation; you are 
   quite right.  Just using a different term for parallelism with return 
   context, but I see it only introduced confusion.

So it sounds like we are all saying the same thing now?

-- Bob


Re: [PROPOSAL] calling convention abstraction

2005-04-11 Thread Roger Hale
Bob Rogers wrote:
   From: Roger Hale [EMAIL PROTECTED]
   Date: Thu, 07 Apr 2005 04:23:41 -0400
   Leopold Toetsch wrote:
Roger Hale [EMAIL PROTECTED] wrote:

   Leopold Toetsch wrote:
   
   As @ARGS (or @IN_ARGS, @OUT_ARGS) is being stored in the context, and
   that context is defacto the continuation, yes - a tail-call would
   inherit this information.

   But as each tail-call supplies a new @ARGS, how can this be the case?

We would have two parts in the context: @IN_ARGS, @OUT_ARGS. The
Ctailcall opcode can preserve that part with the return context.

   It seems to me that both @IN_ARGS and @OUT_ARGS get used for other 
   things (the tail-calls' arguments) in a chain of tail-calls.

The definition of a tail call is that it returns its callee's results
back to its caller unmodified.  
Agreed, but...
So if @OUT_ARGS is used for other
things, then it's not a tail call.
I don't understand.  @OUT_ARGS aren't the arguments returned (to my 
understanding), they're the arguments to the next function in sequence.

   Consider this chain:
   A calls B(@OUT_ARGS 1)[continuation: A*] in context c
   B(@IN_ARGS 1)[c10n: A*] calls C(@OUT_ARGS 2)[c10n: A*]
   C(@IN_ARGS 2)[c10n: A*] wants to know context c, as it's getting
   ready to return something.  Neither @IN_ARGS (the arguments C
   received from B) nor @OUT_ARGS (the arguments of any call C may make)
   has this information . . .
I don't think this is a real situation.  If B passes C the continuation
it got from A, then the call to C is indeed a tail call [1], 
Yes...
and cannot
have different @OUT_ARGS from the call to B, because B never regains
control when C returns.  
I don't see what this has to do with the continuation passed with the 
call.  A tail call is an arbitrary call with arbitrary arguments, in 
final position before returning.  (If it omitted the tail-call 
optimization and supplied a continuation B* of its own, B* would be the 
identity stub

- @return_args { A* @return_args }
as it were; but these are not B's @OUT_ARGS, but B*'s @IN_ARGS and 
@OUT_ARGS, and A*'s @IN_ARGS, to my understanding.)  B can call C with 
anything it likes, because it still has control before calling C.

Your notation in that case has to be:
B(@IN_ARGS 1)[c10n: A*] calls C(@OUT_ARGS 1)[c10n: A*]
What forces B to call C with the same arguments it was called with?
Or do you mean something different from a tail call?  If so, could you
please express it in a programming language?
   . . . but the continuation (I propose) does; and this continues to be
   good for whoever wants to know: the return object holds the return
   context.
   No?
   regards,
 Roger
I believe so, but I think this is what Leo meant by ... that context is
defacto the continuation.  There doesn't need to be a separate return
object because it would be one-to-one with the continuation.
Sorry, by return object I was only meaning the continuation; you are 
quite right.  Just using a different term for parallelism with return 
context, but I see it only introduced confusion.

-- Bob Rogers
   http://rgrjr.dyndns.org/
[1]  If not implemented via tailcall, it would use an additional stack
 frame, but the semantics would otherwise be identical.
Agreed.
(I apologize for my slow turn-around on replying; I hope to respond 
quicker in the future.)

-- Roger Hale


Re: [PROPOSAL] calling convention abstraction

2005-04-07 Thread Roger Hale
Leopold Toetsch wrote:
Roger Hale [EMAIL PROTECTED] wrote:
Leopold Toetsch wrote:
As @ARGS (or @IN_ARGS, @OUT_ARGS) is being stored in the context, and
that context is defacto the continuation, yes - a tail-call would
inherit this information.

But as each tail-call supplies a new @ARGS, how can this be the case?
We would have two parts in the context: @IN_ARGS, @OUT_ARGS. The
Ctailcall opcode can preserve that part with the return context.
It seems to me that both @IN_ARGS and @OUT_ARGS get used for other 
things (the tail-calls' arguments) in a chain of tail-calls.  Consider 
this chain:

A calls B(@OUT_ARGS 1)[continuation: A*] in context c
B(@IN_ARGS 1)[c10n: A*] calls C(@OUT_ARGS 2)[c10n: A*]
C(@IN_ARGS 2)[c10n: A*] wants to know context c, as it's getting ready 
to return something.  Neither @IN_ARGS (the arguments C received from B) 
nor @OUT_ARGS (the arguments of any call C may make) has this 
information, but the continuation (I propose) does; and this continues 
to be good for whoever wants to know: the return object holds the return 
context.

No?
regards,
 Roger


Re: [PROPOSAL] calling convention abstraction

2005-04-07 Thread Bob Rogers
   From: Roger Hale [EMAIL PROTECTED]
   Date: Thu, 07 Apr 2005 04:23:41 -0400

   Leopold Toetsch wrote:
Roger Hale [EMAIL PROTECTED] wrote:

   Leopold Toetsch wrote:
   
   As @ARGS (or @IN_ARGS, @OUT_ARGS) is being stored in the context, and
   that context is defacto the continuation, yes - a tail-call would
   inherit this information.

   But as each tail-call supplies a new @ARGS, how can this be the case?

We would have two parts in the context: @IN_ARGS, @OUT_ARGS. The
Ctailcall opcode can preserve that part with the return context.

   It seems to me that both @IN_ARGS and @OUT_ARGS get used for other 
   things (the tail-calls' arguments) in a chain of tail-calls.

The definition of a tail call is that it returns its callee's results
back to its caller unmodified.  So if @OUT_ARGS is used for other
things, then it's not a tail call.

   Consider this chain:

   A calls B(@OUT_ARGS 1)[continuation: A*] in context c

   B(@IN_ARGS 1)[c10n: A*] calls C(@OUT_ARGS 2)[c10n: A*]

   C(@IN_ARGS 2)[c10n: A*] wants to know context c, as it's getting
   ready to return something.  Neither @IN_ARGS (the arguments C
   received from B) nor @OUT_ARGS (the arguments of any call C may make)
   has this information . . .

I don't think this is a real situation.  If B passes C the continuation
it got from A, then the call to C is indeed a tail call [1], and cannot
have different @OUT_ARGS from the call to B, because B never regains
control when C returns.  Your notation in that case has to be:

B(@IN_ARGS 1)[c10n: A*] calls C(@OUT_ARGS 1)[c10n: A*]

Or do you mean something different from a tail call?  If so, could you
please express it in a programming language?

   . . . but the continuation (I propose) does; and this continues to be
   good for whoever wants to know: the return object holds the return
   context.

   No?

   regards,
 Roger

I believe so, but I think this is what Leo meant by ... that context is
defacto the continuation.  There doesn't need to be a separate return
object because it would be one-to-one with the continuation.

-- Bob Rogers
   http://rgrjr.dyndns.org/

[1]  If not implemented via tailcall, it would use an additional stack
 frame, but the semantics would otherwise be identical.


Re: [PROPOSAL] calling convention abstraction

2005-04-04 Thread Leopold Toetsch
Roger Hale [EMAIL PROTECTED] wrote:
 Leopold Toetsch wrote:

 As @ARGS (or @IN_ARGS, @OUT_ARGS) is being stored in the context, and
 that context is defacto the continuation, yes - a tail-call would
 inherit this information.

 leo

 But as each tail-call supplies a new @ARGS, how can this be the case?

We would have two parts in the context: @IN_ARGS, @OUT_ARGS. The
Ctailcall opcode can preserve that part with the return context.

 One can also think of {scalar, list, ...} context as the continuation's
 signature...

Yes.

leo


Re: [PROPOSAL] calling convention abstraction

2005-04-03 Thread Roger Hale
Leopold Toetsch wrote:
Below inline attached is a scheme for an abstraction layer around 
calling conventions.

Comments welcome,
leo
 2.5) return context

 Yesterdays conversation on IRC (yes!) has clearly shown that the
 current calling conventions are lacking information about scalar vs
 list vs void context.

   sub foo { want.List ?? (1,2,3) :: 1 }   # or some such

 This information could also be attached to @ARGS. E.g.

   @ARGS.return_list(1)
Would it be possible to attach it to the continuation?  Then in the 
course of tail-calling the information continues to be available just 
where it's needed.


Re: [PROPOSAL] calling convention abstraction

2005-04-03 Thread Leopold Toetsch
Roger Hale [EMAIL PROTECTED] wrote:
 Leopold Toetsch wrote:

sub foo { want.List ?? (1,2,3) :: 1 }   # or some such
 
  This information could also be attached to @ARGS. E.g.
 
@ARGS.return_list(1)

 Would it be possible to attach it to the continuation?  Then in the
 course of tail-calling the information continues to be available just
 where it's needed.

As @ARGS (or @IN_ARGS, @OUT_ARGS) is being stored in the context, and
that context is defacto the continuation, yes - a tail-call would
inherit this information.

leo


Re: [PROPOSAL] calling convention abstraction

2005-04-03 Thread Roger Hale
Leopold Toetsch wrote:
Roger Hale [EMAIL PROTECTED] wrote:
Leopold Toetsch wrote:

 sub foo { want.List ?? (1,2,3) :: 1 }   # or some such
This information could also be attached to @ARGS. E.g.
 @ARGS.return_list(1)

Would it be possible to attach it to the continuation?  Then in the
course of tail-calling the information continues to be available just
where it's needed.

As @ARGS (or @IN_ARGS, @OUT_ARGS) is being stored in the context, and
that context is defacto the continuation, yes - a tail-call would
inherit this information.
leo
But as each tail-call supplies a new @ARGS, how can this be the case?
One can also think of {scalar, list, ...} context as the continuation's 
signature...


[PROPOSAL] calling convention abstraction

2005-03-29 Thread Leopold Toetsch
Below inline attached is a scheme for an abstraction layer around 
calling conventions.

Comments welcome,
leo
Parrot Calling Conventions

1) Rational

Calling conventions and opcodes (and of course the semantics of these)
define the ABI of the Parrot VM. Any change in the ABI creates
incompatibilities and the need to rewrite compilers that target
Parrot.

The current calling conventions as laid in stone in pdd03 [1] are IMHO
limited and suboptimal. I've already shown with the cachegrind
analysis of the fib benchmark[2] that we just can't keep the scheme in
the long run for performance reasons. Further: the current calling
scheme doesn't cope with MMD as argument ordering isn't provided:

  foo(int i, float v)

and

  foo(float v, int i)

end up with the same call signature setup *I2 := I4 := 1,

Finally the current scheme doesn't cope with any of the fancy call
stuff like named arguments, default values, scalar vs list context,
and what not. For HLL interoperbility Parrot should provide a scheme
that has at least some common denominator to support major target
languages.

Some of my arguments are of course related to performance and
optimzation, which we shouldn't consider much until we have a complete
Parrot VM. But changing the ABI can't be done much later as too much
existing code is impacted.

To get around this problem I propose an abstraction layer around the
calling scheme.

2) Proposal

2.1) @ARGS

@ARGS is a pseudo-array (hash, object) that handles call arguments and
return values.  It allows indexed and named access to arguments in a
straight forward manner:

   $I0 = @ARGS[0] # get 1st argument as plain int
   set I16, @ARGS[0]  # same, PASM
   $P0 = @ARGS[1] # get 2nd arg as PMC

This replaces the current scheme of addressing arguments:

   $I0 = I5   # 1st arg in I5
   $P0 = P5   # 2nd arg in P5

This should work of course the other way too:

  @ARGS[0] = 42   # set first return value
  # or sub param to pass in

or

  push @ARGS, 42

We probably need two of these: one for the current incoming arguments
and one for outgoing arguments per call. Return values can arrive in
the @ARGS of the call. So it's more likely called @IN_ARGS and
@OUT_ARGS or some such.

2.2) named access of arguments:

  $P0 = @ARGS['a']# get argument named 'a'

2.3) @ARGS methods and attributes

@ARGS provides all array-ish access methods:

  argv = elements @ARGS # get argument count
  @ARGS = 4 # want to pass 4 args to sub

All necessary introspection and functionality can be implemented with
existing opcodes or syntax:

  $I0 = typeof @ARGS[2] # get type ID of 3rd argument
  $P0 = @ARGS.__ro(3) # get 4th argument as read-only (COW) copy

  @ARGS.__push($P0)   # set next call arg
  @ARGS.__push_flatten(a)  # flatten a and add to outgoing args

  @ARGS.__set_default(a, $P0) # set default value for arg named a

and so on.

2.4.) variadic arguments (perl @_, Python *a)

The @ARGS array can directly map to an @_ array:

  @ARGS = argv

or:

  @ARGS[2] = argv   # ($a, $b, [EMAIL PROTECTED])

2.5) return context

Yesterdays conversation on IRC (yes!) has clearly shown that the
current calling conventions are lacking information about scalar vs
list vs void context.

  sub foo { want.List ?? (1,2,3) :: 1 }   # or some such

This information could also be attached to @ARGS. E.g.

  @ARGS.return_list(1)

3) implementation idea

For each call we've to allocate a context structure with a new
register frame. As shown in [3] this can be done effectively with a
sliding register window and variable sized call frames. An overall
layout of a call frame could look like:

   +-+---+---+---+
   | context | in @ARGS  | registers | out @ARGS |
   +-+---+---+---+

But actually it doesn't really matter now. With the abstraction we can
do it as we like and optimize it like hell later.

4) Conclusion

The @ARGS abstraction hides all the nasty call stuff inside a
consistent interface, which is easily extensible and not as limited as
the current layout in pdd03. Changing the ABI later isn't really a
good idea, an abstraction like this should be defined ASAP to provide
all freedom for the implementaion.

The attributes, methods, and semantics of @ARGS (or a similar
abstraction) should be consolidated by the various HLL folks, so that
we eventually have a consistent usable cross-language call interface
that just works.

leo

[1] docs/pdds/pdd03_calling_conventions.pod

[2] Subject: Why is the fib benchmark still slow - part 1

NB: part 2 would have been the argument/return value copying
between register frames (src/sub.c:copy_regs())

[3] Subject: [Summary] Register stacks again
Subject: [PROPOSAL] for a new calling scheme