# Copyright: 2001-2005 The Perl Foundation.  All Rights Reserved.
# $Id: calling_conventions.pod 7972 2005-05-04 08:03:15Z leo $

=head1 NAME

PIR - calling conventions

=head1 VERSION

=over 4

=item 0.1 initial proposal

=item 0.2 initial, checked in

=item 0.3 updated parrot calling conventions and invoke

=item 0.4 methods and shortcuts documented

=back

=head1 OVERVIEW

This document describes subroutine and method calling conventions.

=head1 DESCRIPTION

As imcc does register allocation, it has to track the life span of
variables. This includes the (possible) data flow in and out of
subroutines.

=head1 Parrot calling conventions - CPS

=head2 Explicitely Calling PASM Subroutines

  newsub $P0, .Sub, _sub_label
  newsub $P1, .Continuation, ret_addr
  ...
  .pcc_begin prototyped|non_prototyped
  .arg x	# I5
  .arg y	# I6
  .arg z	# I7
  .pcc_call $P0, $P1	# r = _sub_label(x, y, z)
  ret_addr:
  .local int r  # optional - new result var
  .result r
  .pcc_end

=head2 The Short Way

  ...  # variable decls
  r = _sub_label(x, y, z)
  (r1[, r2 ...]) = _sub_label(x, y, z)
  _sub_label(x, y, z)

Instead of the label a Subroutine object can be used too:

   find_global $P0, "_sub_label"
   $P0(args)

=head2 Subroutines

  .sub _sub_label [Subpragma, ...]
   .param int a # I5
   .param int b # I6
   .param int c # I7
  ...
  .pcc_begin_return
   .return xy   # e.g. I5
  .pcc_end_return
  ...
  .end

An alternative syntaxs allow to express a return in one line.
The surrounded parentheses are mandatory . Besides making
sequence break more conspiscuous, this is necessary to
distinguish this syntax from other uses of the .return directive
that will be probably deprecated.

  .return ( a, b )      # return the values of a and b

  .return ()            # return no value

Similarly, one can yield using the .yield directive

  .yield ( a, b )      # yield with the values of a and b

  .yield ()            # yield with no value


=head2 Subpragma

This is a comma separated list of zero or more items with the
following meaning:

=over 4

=item * B<prototyped>, B<non_prototyped>

Specify calling convention

=item * @MAIN

Define "main" entry point to start execution. If multiple subroutines
are marked as B<@MAIN>, the B<last> marked subroutine is entered.

=item * @LOAD

Run this subroutine during the B<load_library> opcode.
B<@LOAD> is ignored, if another subroutine in that file is marked with
B<@MAIN>.

=item * method

Declare subroutine being a method.

=back

Notes:

=over 4

=item * B<prototyped>, B<non_prototyped>

If a subroutine definition has no prototyped specifier, code gets
emitted to receive parameters by both flavors.

=item * B<newsub>

Currently needs the B<.Class> syntax, i.e. a B<dot> in front of the
class name.

=item * B<pcc_call>

Takes either 2 arguments: the sub and the return continuation, or the
sub only. For the latter case an B<invokecc> gets emitted. Providing
an explicit return continuation is more efficient, if its created
outside of a loop and the call is done inside a loop.

=item * Saved Regs:

Only the top half of registers are preserved currently.

=item * B<.args>, B<.param>, B<.result>, and B<.return> are optional.

=item * B<.param>

The B<.param> declarations must be the first statements in the
sub if any. No other statements are allowed between B<.param> -
not even comments currently.

=item * B<pcc_begin_return>, B<pcc_end_return>

If there is no return value and the return should be the last
instruction of the subroutine, this declaration pair can be omitted.
Parrot provides an B<invoke P1> as last instruction automatically.

=back

=head2 Getting the Parameter Count

The reserved words C<argcI>, C<argcS>, C<argcP>, and C<argcN> hold the
count of passed parameters (or return values) according to
F<docs/pdds/pdd03_calling_conventions.pod>. The variable
C<is_prototyped> is an alias for C<I0>.

=head2 Calling Methods

The syntax is very similar to subroutine calls. The call is done with
C<meth_call> which must immediately be preceded by the C<.invocant>:

   .local pmc class
   .local pmc obj
   newclass class, "Foo"
   find_type $I0, "Foo"
   new obj, $I0
  .pcc_begin prototyped|non_prototyped
  .arg x	# I5
  .arg y	# I6
  .arg z	# I7
  .invocant obj
  .meth_call "_method" [, $P1 ]	# r = obj."_method"(x, y, z)
  .local int r  # optional - new result var
  .result r
  .pcc_end

The return continuation is optional. The method can be a string
constant or a string variable.

=head2 Shortcuts

  r = obj."_method"(args)
  (r1, r2) = obj."_method"(args)
  obj."_method"(args)

=head2 Methods

  .namespace [ "Foo" ]

  .sub _sub_label method [,Subpragma, ...]
   .param int a # I5
   .param int b # I6
   .param int c # I7
   ...
   self."_other_meth"()
  ...
  .pcc_begin_return
   .return xy   # e.g. I5
  .pcc_end_return
  ...
  .end

The variable "self" automatically refers to the invocating object, if the
subroutine declaration contains "method".

Restore namespace to the global namespace:

  .namespace [ "" ]

=head2 NCI

Proposed syntax:

  load_lib $P0, "libname"
  dlfunc $P1, $P0, "funcname", "signature"
  ...
  .pcc_begin prototyped
  .arg x	# I5
  .arg y	# I6
  .arg z	# I7
  .nci_call $P1	# r = funcname(x, y, z)
  .local int r  # optional - new result var
  .result r
  .pcc_end

This prepares parameters as described in
F<pdd03_calling_conventions.pod>, saves the registers and invokes the
function.  The B<.arg> pseudo ops put the given argument into
increasing registers of the appropriate type.


=head1 Exception handlers

TBD.

=head1 Stack calling conventions

Arguments are B<save>d in reverse order onto the user stack:

   .arg y	# save args in reversed order
   .arg x
   call _foo	#(r, s) = _foo(x,y)
   .local int r
   .local int s
   .result r	# restore results in order
   .result s	#

and return values are B<restore>d in argument order from there.

The subroutine is responsible for preserving registers.

 .sub _foo		# sub foo(int a, int b)
   saveall
   .param int a         # receive arguments from left to right
   .param int b
   ...

   .return mi		# return (pl, mi), push results
   .return pl		# in reverse order
   restoreall
   ret
 .end

=head2 Rational

Pushing arguments in reversed order on the user stack makes the left
most argument the top of stack entry. This allows for a variable
number of function arguments (and return values), where the left most
argument before a variable number of following arguments is the
argument count.

=head2 Status

Implemented. When the subroutine is in the same compilation unit, the
callee can B<saveall> registers; when the subroutine is in a different
compilation unit, the callee must preserve all used registers.

=head1 Invoking subroutines

IMCC tries to keep track of the address where the B<invoke> will branch
to, but can only succeed to do so when the B<set_addr> and the
B<invoke> opcodes are located together.

  $P10 = new Sub
  $I1 = addr _the_sub
  $P10 = $I1
  invoke $P10   # ok

But not:

    bsr get_addr
    invoke $P10 # error
    ...
  get_addr:
    $P10 = new Sub
    $I1 = addr _the_sub
    $P10 = $I1
    ret

The latter example will very likely lead to an incorrect CFG and thus to
incorrect register allocation.

=head2 Status

Implemented. When the subroutine does B<saveall>/B<restoreall>, the
branch from the B<ret> statement back is ignored in the CFG.

=head1 Namespaces and lexicals

 - Should imcc keep track of pad opcodes?
 - Should imcc even emit such opcodes from e.g. .local directives?

=head1 FILES

F<imcc/imcc.y>, F<imcc/t/syn/bsr.t>, F<imcc/t/syn/pcc.t>,
F<imcc/t/syn/objects.t>, F<docs/pdds/pdd03_calling_conventions.pod>

=head1 AUTHOR

Leopold Toetsch <lt@toetsch.at>

=cut

# vim: expandtab shiftwidth=4 tw=70:

