PREVIOUS
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:
- The statements LDEXBL, LDENBL, CALLJUMP, FORKJUMP, and RETJUMP separate the loading of the entry and exit blocks from the actual key invocation, for maximum flexibility.
- The statements KALL, KC, KFORK and KRETURN together with KENTRY specify the passed and returned parameters (exit and entry block information) in the same statement that performs the key invocation.
Both categories of key invocation statements may be freely
intermixed in a program.
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.
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.
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.
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.)
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);
The KFORK statement loads the exit block and performs the KeyKOS
key fork invocation.
KFORK(key,oc) xxxFROM(...) KEYSFROM(pk1,pk2,pk3,pk4);
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);
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);
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();
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);
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