PREVIOUS

Key Invocation Syntax

The general form of a key invocation statement consists of the invocation name and its arguments, followed by optional keywords with their arguments. For example,

 KALL(key,oc) RCTO(rc); 

is a KALL invocation with two arguments and an optional keyword with one argument. The invocation and keywords must be in upper case. The keywords may be in any order after the invocation, but their arguments must be in the order specified.

There are two categories of key invocation statements:

Both categories of key invocation statements may be freely intermixed in a program.

Data Passing
Key invocation statements may contain a keyword for passing data. These keywords are all of the form xxxFROM, and indicate the variables or locations from which the data are to be taken. They can be specified in any one of the following ways:

CHARFROM(pstr, plen)

STRINGFROM(psstr)

STRUCTFROM(pstruct, plen)

STRUCTFROM(pstruct)

This is equivalent to STRUCTFROM(pstruct, sizeof(pstruct)).

pstr
char [];
Message data to be passed.
plen
long;
Length of data to be passed.
psstr
STRING;
Message data to be passed.
pstruct
struct {};
Structure to be passed.
Data Receiving
Key invocation statements may contain a keyword for receiving data. These keywords are all of the form xxxTO, and indicate the variables or locations into which the data are to be placed. They can be specified in any one of the following ways:

CHARTO(rstr, rlen)

CHARTO(rstr, rlen, actlen)

STRINGTO(rsstr)

STRUCTTO(rstruct, rlen)

STRUCTTO(rstruct, rlen, actlen)

STRUCTTO(rstruct)

This is equivalent to STRUCTTO(rstruct, sizeof(rstruct)) and CHARTO(&rstruct,sizeof(rstruct)).

rstr
char [];
String to receive the message data. This must be an lvalue (a variable).
rlen
long;
Maximum length of message data to receive, that is to say the size of the rstr variable.
rsstr
STRING;
STRING to receive the message data. This must be an lvalue (a variable).
actlen
long;
Optional. Actual length of message data received on the key invocation. This must be an lvalue (a variable). If the actlen argument is not specified and the received data length is shorter than rlen, then the remainder of the receiving data area is filled with binary zeros.
pstruct
struct {};
Structure to receive the data.

Key Invocation Arguments

This section describes the individual arguments provided with the key invocation statements.

key
KEY
Key to be invoked.
oc
uint32
For the KALL and KFORK invocations, this is the order code to be sent to the invoked key. It may be a variable or a constant.For the LDENBL and KENTRY statements, this is the value which is received by the domain when its start key is invoked, and so must be a variable.
rc
uint32
For the KALL invocation, this is the return code received from the invoked key. This must be an lvalue (a variable).For the LDEXBL and KRETURN statements, this is the value which is passed by the domain when a key is invoked, so it may be either a variable or constant.
db
short int
Data byte of the start key to this domain that was invoked. This must be an lvalue (a variable).
pkn
KEY
Key to be passed on the key invocation. Up to three keys may be passed on a call invocation, and up to four keys on a fork or return invocation. All of the key arguments are optional. For example, "(,,pk3,pk4)" and "(pk1,pk2)" are both valid.
rkn
KEY
Key to be received on the key invocation. Up to four keys may be received on an invocation. All of the key arguments are optional.
label
Label assigned to a KENTRY statement. This label is used to match KRETURN statements with their KENTRY statement. If no label is specified, then the null label is assumed.

Key Invocation Statements

In the following statements, "FROM" and "TO" are from the point of view of the invoking domain. FROM specifies passed parameters (i.e., parameters passed from variables in the invoking domain) and TO specifies received parameters (i.e., parameters to be received and stored into variables in the invoking domain.)

KALL and KC
The KALL statement performs the KeyKOS key call invocation. The KC statement is identical to the KALL statement, and is provided for compatibility with other language extensions used on KeyKOS. These statements load the entry and exit blocks before invoking the key.

KALL(key,oc) xxxFROM(...) KEYSFROM(pk1,pk2,pk3) xxxTO(...) 
      KEYSTO(rk1,rk2,rk3,rk4) RCTO(rc);

KC(key,oc) xxxFROM(...) KEYSFROM(pk1,pk2,pk3) xxxTO(...) 
      KEYSTO(rk1,rk2,rk3,rk4) RCTO(rc);

KFORK
The KFORK statement loads the exit block and performs the KeyKOS key fork invocation.

KFORK(key,oc) xxxFROM(...) KEYSFROM(pk1,pk2,pk3,pk4);

KRETURN and KENTRY
The KRETURN and KENTRY statements work together to perform the KeyKOS key return invocation. The KRETURN statement loads the exit block and then branches to its matching KENTRY statement. The KENTRY statement loads the entry block and then invokes the key. The KENTRY statement is not itself executable, so it must never be placed where control will fall through into it. The KRETURN statement will never fall through to the statement following itself, since it always branches to its matching KENTRY statement. A common practice is to place the KENTRY statement immediately following the first KRETURN statement.

A KENTRY statement is matched with any KRETURN statement that specifies the same label. Unlike similar extensions made for PL/I, the KENTRY and the matching KRETURN statement must be in the same function. A null label for a KENTRY statement may be specified as KENTRY(). A null label for a KRETURN statement may be specified as KENTRYID(), or by leaving the KENTRYID keyword off altogether. A KENTRY statement with a null label is matched with any KRETURN statement with a null label.

KENTRY(label) OCTO(oc) xxxTO(...) KEYSTO(rk1,rk2,rk3,rk4) 
     DBTO(db);

KRETURN(key,rc) xxxFROM(...) KEYSFROM(pk1,pk2,pk3,pk4) 
     KENTRYID(label);

LDENBL and LDEXBL
The LDENBL and LDEXBL statements load the entry and exit blocks, respectively.

LDENBL OCTO(oc) xxxTO(...) KEYSTO(rk1,rk2,rk3,rk4) 
     DBTO(db);

LDEXBL(key,rc) xxxFROM(...) KEYSFROM(pk1,pk2,pk3,pk4);

CALLJUMP, FORKJUMP, and RETJUMP
The CALLJUMP, FORKJUMP, and RETJUMP statements perform the KeyKOS key call, fork, and return invocations, respectively. The exit block must have been loaded already by a LDEXBL statement. In the case of the CALLJUMP and RETJUMP statements, the entry block must also have been loaded, by the LDENBL statement.

CALLJUMP();
FORKJUMP();
RETJUMP();

Examples

Create a start key to the domain with a data byte of 3, using the CHARFROM keyword.

char db3 = 0x03;
KC(domkey,Domain_MakeStart) CHARFROM(&db3,1) KEYSTO(start);

Create a start key to the domain with a data byte of 5, using the STRINGFROM keyword.

STRING db5(1) = 0x05;
KC(domkey,Domain_MakeStart) STRINGFROM(db5) KEYSTO(start);

Known limitations

You cannot use the following construct:

void f(KEY a, KEY b);

Instead use:

void f(KEY, KEY);

and:

void f(a, b)
     KEY a;
     KEY b;
{body of function ....}

NEXT