# Copyright: 2001-2005 The Perl Foundation.  All Rights Reserved.
# $Id: pdd03_calling_conventions.pod 10264 2005-11-30 03:07:41Z chip $

=head1 NAME

docs/pdds/pdd03_calling_conventions.pod - Parrot Calling Conventions

=head1 ABSTRACT

Parrot's inter-routine calling conventions.

=head1 VERSION

$Revision$

=head1 DESCRIPTION

This document describes how to pass arguments from registers to subroutines,
and how subroutines can extract their parameters into registers for use.

Since Parrot's calling conventions are continuation-based, there is arguably
very little difference between a call and a return. Because of this, the
conversion rules are the same regardless of whether code is invoking a
subroutine or a return continuation.

=head2 Common Features of Argument/Return Opcodes

There are four opcodes involved in parameter and return value propagation:

=over 4

=item *

C<set_args>, for passing arguments;

=item *

C<set_returns>, for returning values;

=item *

C<get_params>, for accepting parameters; and

=item *

C<get_results>, for accepting return values.

=back

FAQ: Given Parrot's internal use of continuation-passing style ["CPS"], it
would be possible to use one pair of opcodes for both call and return, since
under CPS returns I<are> calls.  And perhaps someday we will have only two
opcodes.  But for now, certain efficiency hacks are easier with four opcodes.)

The common syntax of these opcodes is:

    <set_opcode> "(flags0, flags1, ..., flagsN)", VAL0, VAL1, ... VALN
    <get_opcode> "(flags0, flags1, ..., flagsN)", REG0, REG1, ... REGN

The flags string is a literal quoted string denoting a list of zero or more
comma-separated integers.  The list as a whole may be surrounded by
parentheses.  Integers may be specified either in decimal, or if prefixed with
"0b"/"0x", in binary/hexadecimal.  There must be exactly one integer for each
value or register given.

For documentation purposes we'll number the bits 0 (low) through 30 (high).
Bit 31 (and higher, where available) will not be used.

=head3 Flag Words; Common Flag Word Bits

Each integer in the flag string controls the processing of the corresponding
value or register.

These bits of each flag word have common meanings for all argument/
return-value opcodes:

    0-1   TYPE
               0b00 = I
               0b01 = S
               0b10 = P
               0b11 = N

You can just set these bits (as well as the I<CONSTANT> bit below) to zero as
the assembler calculates the correct setting depending on the given arguments.

=head2 Passing Arguments, Returning Values

Just before calling a subroutine with C<invokecc> or calling a method with
<call_methodcc>, use the C<set_args> opcode to tell Parrot where the
subroutine's or method's arguments will come from and how they should be
expanded by the target.

Similarly, just before returning from such a subroutine or method, use the
C<set_returns> opcode to tell Parrot where the return values will come from and
how to expand them for the caller's use.

=head3 Flag Word Bits For 'Setting'

These bits of each flag word have these meanings specific to C<set_args> and
C<set_returns>:

    2     CONSTANT
               The value is a literal constant, not a register.
               (Don't set this bit yourself; the assembler sets this bit
               automatically if a constant is given.)

    3     FLAT
               If this bit is set on a PMC value, then the PMC must be an
               aggregate or a scalar containing a reference to an aggregate.
               The contents of the aggregate, rather than the aggregate
               itself, will be passed.

               The meaning of this bit is undefined when applied to integer,
               number, and string values.

    4     MAYBE_FLAT
               If:
                (a) this bit is set on a PMC value; and,
                (b) the PMC is an aggregate or a scalar containing a reference
                    to an aggregate; and,
                (c) the called function has a slurpy flag on the corresponding
                    parameter;
               then, pretend FLAT bit was set.

               XXX - TODO - Determine whether this is really useful.
                            This description is kind of ad-hoc.

    5     (unused)

    6     (unused)

    7     NAMED
               XXX - TODO


=head2 Accepting Parameters, Accepting Return Values

As the I<first opcode> in a subroutine that will be called with C<invokecc> or
a method that will be called with <call_methodcc>, use the C<get_params> opcode
to tell Parrot where the subroutine's or method's arguments should be stored
and how they should be expanded.

Similarly, just I<before> (yes, I<before>) calling such a subroutine or method,
use the C<get_results> opcode to tell Parrot where the return values should be
stored and how to expand them for your use.

NOTE: It should be obvious, but in case it's not: You must name only registers
as targets of these opcodes, not constants.  (You can't store anything into a
constant.  That would make it a variable.)

=head3 Flag Word Bits For 'Getting'

These bits of each flag word have these meanings specific to C<get_params> and
C<get_results>:

    2     (unused)

    3     SLURPY (P only)
               If this bit is set on a P register, then it will be populated
               with an aggregate that will contain all of the remaining values
               that have not already been stored in other registers.

               All such values will be converted to PMCs according to the
               detailed rules below, and those PMCs will be stored into the
               new aggregate.

               XXX - TODO - If NAMED is not set, the aggregate will be an
               Array type (HLL-specific) and the contents will be all
               unassigned positional parameters.

               XXX - TODO - If NAMED is set, the aggregate will be a Hash type
               (HLL-specific) and the contents will be all unassigned named
               parameters.

    4     (unused)

    5     OPTIONAL
               If this bit is set on a register for which no value has been
               passed, no exception will be raised; rather, the register will
               be set to a default value: a Null PMC for P, an empty string
               for S, or zero for N or I.

    6     OPT_FLAG (I only)
               An I register with this bit set is set to one if the
               immediately preceding B<OPTIONAL> register received a value;
               otherwise, it is set to zero.

    6     READONLY (P only)
               XXX - PROPOSED ONLY - XXX
               If this bit is set on a P register that receives a value,
               Parrot will ensure that the final value in the P register
               is read-only (i.e. will not permit modification).  If the
               received value was a mutable PMC, then Parrot will create
               and set the register to a read-only PMC wrapper around the
               original PMC.

               Parrot's algorithm for deciding what is writable may be pretty
               simplistic.  In initial implementations, it may assume that any
               PMC not of a known read-only-wrapper type is mutable.

    7     NAMED
               XXX - TODO


=head3 Overflow

If too many values are provided to fit into the given target registers, Parrot
will throw an exception.  Note that if the final target is a P register with
FLAT set, then this exception can never occur.

XXX - FIXME - which exception?  We really could use an exception subsystem. 
Oh, wait, that's my job.  Never mind.  --Chip

=head3 Underflow

If too few values are provided so that some target registers are left unset,
this too results in an exception.

=head3 Type Conversions

Unlike the C<set_*> opcodes, the C<get_*> opcodes must perform conversion from
one register type to another.  Here are the conversion rules:

=over 4

=item *

When the target is an I, N, or S register, storage will behave like an
C<assign> (standard conversion).

=item *

When the target and source are both P registers, storage will behave like a
C<set> (pass by reference).

=item *

When the target is a P register and the source is an integer, the P will be
set to a new .Integer which has been C<assign>ed the given integer.

=item *

When the target is a P register and the source is a number, the P will be set
to a new .Float which has been C<assign>ed the given number.

=item *

When the target is a P register and the source is a string, the P will be set
to a new .String which has been C<assign>ed the given string.

=back

=head1 BUGS

Required features are missing:

=over 4

=item *

Named parameters (partly done)

=item *

HLL type mapping -- e.g. for HLL "Foo", having an incoming I register map to a
FooInteger.

=item *

Specific exceptions to throw for specific errors.

=back

Also, PIR should have pretty syntactical sugar around the get and set opcodes,
but it doesn't.  This document should specify what that looks like, too.

=head1 ATTACHMENTS

None.

=head1 REFERENCES

None.

=cut

__END__
Local Variables:
  fill-column:78
End:
