Parrot Calling Conventions
Maintainer: Dan Sugalski Class: Internals PDD Number: 03 Version: 1.1 Status: Developing Last Modified: 11 March 2003 PDD Format: 1 Language: English
- Version 1.2
Dropped the number of registers passed in and out of subs.
- Version 1.1
We now call with a frame, rather than pushing on the stack, and we return frames, rather than returning a stack. We also pass in context information for the return.
- Version 1.0
None. First version
This PDD describes Parrot's inter-routine calling conventions.
Please note that the following conventions are only necessary when exposing subs and methods via the generic parrot routine exposure mechanism. What does this mean?
It means the caller needs to follow these conventions only when calling into subs and methods that it has looked up symbolically via parrot's default lookup system. If a language has a lighter-weight calling mechanism that's safe to use in some circumstances, it's perfectly fine to use them.
This means that if you write a C compiler that targets Parrot, for example, you don't need to use parrot's caller-save, full-on calling conventions when one C function calls another if the compiler knows at compile (or possibly link) time what parameters are being passed into the function.
This can potentially save a significant amount of time when dealing with languages that are fully, or nearly fully, bound at compile time, and especially when dealing with languages, such as Forth, that would otherwise spend an inordinate amount of time calling small functions.
If a function isn't exposed at all, it doesn't need to have any way to call into it with the standard calling conventions. It's also perfectly acceptable for there to be two ways to call into a function--one with a language's private calling method, and another that follows the standard conventions.
The caller is responsible for preserving any environment it is interested in keeping. This includes any and all registers, lexical scoping and scratchpads, opcode libraries, and so forth.
Use of the
saveall opcode is recommended if the caller wishes to save everything, and the
restoreall opcode to restore everything
The following registers are used in calling all subs and methods
Holds the object representing the subroutine.
Holds the continuation for the caller, assuming this sub was called with callcc. Otherwise NULL.
Holds the object the sub was called on. (For method calls)
The fully qualified name of the method or sub being called
True if the sub is being called with prototyped parameters.
The number of items pushed onto the stack.
The number of parameters in PMC registers.
The return type expected. This is the identifier number for the class. A return type of 0 is void context, -1 is unknown, and -2 and down are the number of expected return variables, negated, minus one. (So -2 means we expect 1 variable, -3 means we expect 2, -4 means we expect 3, and so forth)
The following registers, with the exception of P registers, are used only when calling a subroutine for which there is a compile-time prototype. The first 27 PMC parameters may be passed in registers P5 through P31.
- I5 through I15
The first 11 integer parameters.
- S5 through S15
The first 11 string parameters.
- N5 through N15
The first 11 numeric parameters.
- P5 through P15
The first 11 PMC parameters.
All overflow parameters are pushed on the stack in reverse order--that is the topmost entry on the stack is the first entry in the parameter list, and the bottom entry the last entry in the parameter list.
The PMC for a hash, array, or list is passed if one of the entries in the parameter list is a hash, array, or list. The aggregate is not flattened. (Though when accessing the parameters it may be)
Parameters are passed in S, I, and N registers only if the sub's prototype specifically indicates it takes parameters of that type.
Note that it doesn't matter what the order of the integer, string, numeric, and PMC parameters are in the parameter list up until overflow occurs.
On return from a function, the following registers are set. Return values are placed in registers only if the function is prototyped to do so. All values on the stack are in reverse order, such that the top value on the stack is the first value returned.
Holds the number of return values on the stack.
Holds the number of return values in integer registers.
Holds the number of return values in string registers.
Holds the number of return values in PMC registers.
Holds the number of return values in numeric registers.
PMC return values
Integer return values
String return values
Numeric return values
Overflow values, or values for functions that don't have a return prototype.