NAME

docs/pdds/pdd05_opfunc.pod - Opcode Function specs

ABSTRACT

This PDD specifies how the opcode functions should behave and how they are called by the Parrot interpreter.

{{ NOTE: this PDD is only loosely connected to the current state of Parrot. }}

DESCRIPTION

The opcode functions are the workhorse of the Parrot engine. They control program flow and do most of the work in a program. (The rest being done by the variable vtable functions)

Opcode functions have very few limitations or restrictions on them. In particular, opcode functions:

  • Can assume a working interpreter

  • Must leave all interpreter registers the way they were found, unless the opcode signature indicates otherwise

Each opcode has two separate functions. The first function takes two parameters, the current interpreter pointer and current interpreter PC, and returns the address of the next opcode to execute. The second function takes zero or more parameters as addresses, register numbers, integers, or floating point numbers and optionally returns either the address of the next opcode or the register number holding the address of the next opcode. These are referred to as the wrapping function and the inner function, respectively.

The wrapping function is required, as this is the code that the interpreter will call. Normally this is automatically generated.

The inner function is the code that gets directly executed when parrot gets TIL-ified. If there is no inner function for some reason, then your opcode will likely run slower (as the interpreter would need to set up the registers and other stuff that would normally get stripped away for speed)

The wrapping function

This is the function that the interpreter actually executes. It has all the intimate knowledge of its parameters embedded in it, and is responsible for figuring out what register data it needs and from where.

This function is generally created automatically by opcode_process.pl, so the programmer doesn't have to create it. If, for some reason, you do need or want to write it (for example if you have no inner function) that's fine.

The inner function

The inner function is the code that actually does the work. This is generally a chunk of C code, though the interpreter will be able to call perl code soon.

IMPLEMENTATION

Prototype declaration of inner function

RETURN function(INPUT[, INPUT[, INPUT...]])

The RETURN type may be one of:

void

Indicates the function returns nothing. The wrapping function will automagically figure out what address to return based on the size of the current opcode.

void *

Indicates the function returns the address of the next opcode to execute.

I

Indicates the function returns the number of the PMC register that holds address of the next opcode to be execute.

The ITEM may be one of:

IV

Indicates the item is an integer

IV *

Indicates the item is a pointer to an integer

NV

Indicates the item is a float

NV *

Indicates the item is a pointer to a float

STRING

Indicates the item is a parrot string pointer

PMC

Indicates the item is a pointer to a PMC

INT

Indicates the item is a pointer to an bigint structure

NUM

Indicates the item is a pointer to a bignum structure

Ix

Indicates the item is an integer register number.

Nx

Indicates the item is a float register number.

Sx

Indicates the item is a string register number.

Px

Indicates the item is a PMC register number.

The function starts with the first open brace, which should generally be on the first non-empty line.

For example:

void addI(Ix out, Ix in1, Ix in2)
{
  INTREG(out) = INTREG(in1) + INTREG(in2);
}

is a simple opcode function that corresponds to the addI opcode.

TODO

write opcode_process.pl

REFERENCES

Oploop PDD, PDD 4 (Internal types)

FOOTNOTES

None.

VERSION

1.0

CURRENT

Maintainer: Dan Sugalski <dan@sidhe.org>
Class: Internals
PDD Number: 5
Version: 1.0
Status: Developing
Last Modified: 16 Jul 2001
PDD Format: 1
Language: English

HISTORY

None. First version

CHANGES

None. First version