Kednos PL/I for OpenVMS Systems
User Manual


Previous Contents Index

The following notes are keyed to Example 10-8:

  1. The procedure includes the module $CHFDEF from the default system library.
  2. The ONARGSLIST built-in function assigns a value to the pointer CHF$ARGPTR, declared in $CHFDEF.
  3. Using the CHF$SIG_ARGS field in the signal array, the procedure prints the number of arguments in the signal array.
  4. It displays the contents of the first argument, that is, the condition value.
  5. Because the number of arguments is variable, the procedure uses the DIM built-in function to determine the number of elements in the array CHF$SIG_ARG (this array always contains three fewer members than arguments in the array, because the condition name, PC, and PSL arguments are always present).
  6. After displaying the signal arguments, the procedure displays the contents of R0 and R1 from the mechanism array.

For more detailed information on the argument lists passed to a condition handler and for descriptions of the values in the signal array and mechanism array, see the OpenVMS System Services Reference Manual. Note that the PL/I run-time system signals conditions using the conventions for specifying signal arguments. Specifically, it passes arguments following the requirements described for the SYS$PUTMSG procedure. This procedure is described in the Introduction to the VMS Run-Time Library.

10.7.2 ONCODE Built-In Function

You can use the built-in function ONCODE to obtain the specific 32-bit status value that describes any condition that is signaled. The low-order three bits of this value contain the severity of the condition (success, warning, error, or fatal). The severity of a condition is important only when no ON-unit exists for a condition, and default condition handling is performed by either PL/I or the system (see Section 10.4).

All OpenVMS-defined conditions have symbolic names associated with them. Table 10-2 lists the PL/I keyword condition names and the global symbol names for the OpenVMS condition values associated with them. If the ONCODE built-in function is invoked in an ON-unit for the related PL/I condition name, it returns the value of the indicated global symbol.

Table 10-2 ONCODE Values for PL/I ON Conditions
PL/I Condition VMS Global Symbol Name1
AREA See the Kednos PL/I for OpenVMS Systems Reference Manual and Chapter 15 of this manual for a discussion of allocation in areas.
CONDITION PLI$_CONDITION
CONVERSION PLI$_CONVERSION if a SIGNAL CONVERSION statement was executed, otherwise PLI$_ONCNVPOS (PLI$_ONCNVPOS could change in a future release of PL/I)
ENDFILE PLI$_ENDFILE
ENDPAGE PLI$_ENDPAGE
ERROR A specific status value associated with the error that caused the condition to be signaled 2
FINISH PLI$_FINISH
FIXEDOVERFLOW SS$_DECOVF or SS$_INTOVF
KEY RMS$_ name, where name is one of the following specific RMS condition names that describe a key error: RMS$_RNF, RMS$_DUP, RMS$_KEY, RMS$_MRN, RMS$_REX; or, PLI$_ name, where name describes a PL/I run-time error, for example PLI$_CNVERR 2
OVERFLOW SS$_FLTOVF or SS$_FLTOVF_F
STORAGE The value returned by LIB$GET_VM
STRINGRANGE PLI$_STRRANGE, or PLI$_SUBSTRn (where n is 2 or 3, indicating the 2nd or 3rd argument of the SUBSTR built-in function), or PLI$_BIFSTAPOS (indicating an out-of-range starting position for an INDEX, SEARCH, or VERIFY built-in function)
SUBSCRIPTRANGE PLI$_SUBRANGE or PLI$_SUBRANGEn (where n is a number in the range 1 through 8 indicating the subscript number)
UNDEFINEDFILE RMS$_ name, where name indicates a specific status value associated with an RMS error; or, PLI$_ name, where name describes a PL/I run-time error 2
UNDERFLOW SS$_FLTUND or SS$_FLTUND_F
VAXCONDITION Any user-defined condition value that was signaled
ZERODIVIDE SS$_FLTDIV, SS$_INTDIV, or SS$_FLTDIV_F


1If a PL/I condition is explicitly specified in a SIGNAL statement, the ONCODE value corresponds to the condition message associated with the condition, for example, PLI$_UNDFILE, PLI$_KEY, and so on.
2These names correspond to the identification fields in the run-time messages. The RMS messages are listed in the OpenVMS Record Management Services Reference Manual. PL/I messages are listed in Appendix A.

When you write an ON-unit to handle one or more conditions, you can refer specifically to the values returned by the ONCODE built-in function using system global symbol names. Table 10-2 lists, where appropriate, the specific system global symbol for a condition name.

All symbolic names associated with OpenVMS condition values are defined as system global symbols. Thus, you can declare the names for these values in a PL/I program using the GLOBALREF and VALUE attributes, and refer to them symbolically. The linker will automatically locate the definitions of the symbols in the default system libraries when the procedure is linked.

For example, the FIXEDOVERFLOW condition can be signaled for either of two conditions. An ON-unit can determine which condition was actually signaled by testing the value of ONCODE as follows:


DECLARE SS$_DECOVF GLOBALREF VALUE FIXED BINARY(31); 
ON FIXEDOVERFLOW BEGIN; 
     IF ONCODE() = SS$_DECOVF THEN 
            PUT LIST ('Decimal overflow'); 
         ELSE 
            PUT LIST ('Integer overflow'); 
     END; 

In this example, the global symbol SS$_DECOVF is declared with the GLOBALREF and VALUE attributes. The ON-unit established for the FIXEDOVERFLOW condition determines, from the value returned by ONCODE, whether the condition was specifically a decimal overflow or an integer overflow.

10.7.3 ONFILE Built-In Function

The ONFILE built-in function returns the name of the file constant for which the current file-related condition was signaled. Its format is given in the Kednos PL/I for OpenVMS Systems Reference Manual.

This built-in function can be used in any of the following ON-units:

The returned value is a varying-length character string. If referenced outside an ON-unit or within an ON-unit that is executed as a result of a SIGNAL statement, the ONFILE function returns a null string.

10.7.4 ONKEY Built-In Function

The ONKEY built-in function returns the key value that caused the KEY condition to be signaled during an I/O operation to a file that is being accessed by key. Its format is given in the Kednos PL/I for OpenVMS Systems Reference Manual.

This built-in function can be used in an ON-unit established for these conditions:

The returned key value is a varying-length character string. If referenced outside an ON-unit, or within an ON-unit executed as a result of the SIGNAL statement, the ONKEY built-in function returns a null string.


Chapter 11
Using PL/I in the Common Language Environment

The Kednos PL/I for OpenVMS VAX and Kednos PL/I for OpenVMS Alpha compilers are part of the OpenVMS common language environment. This environment defines certain calling procedures and guidelines that allow you to call routines written in different languages or prewritten system routines from PL/I. You can call any of the following routine types from PL/I:

Note

The definitions of routine, procedure, and function used throughout this chapter are somewhat different from standard PL/I terminology. These definitions are consistent with the OpenVMS system routines documentation and apply only throughout this chapter.

A routine is a closed, ordered set of instructions that performs one or more specific tasks. Every routine has an entry point (the routine name), and optionally an argument list. Procedures and functions are specific types of routines: a procedure is a routine that does not return a value, whereas a function is a routine that returns a value by assigning that value to the function's identifier.

System routines are prewritten OpenVMS routines that perform common tasks, such as finding the square root of a number or allocating virtual memory. You can call any system routine from your program, provided that PL/I supports the data structures required to call the routine. The system routines used most often are OpenVMS Run-Time Library routines, utility routines, and system services. System routines, which are discussed later in this chapter, are documented in detail in the VMS Run-Time Library Routines Volume, the OpenVMS Utility Routines Manual, and the OpenVMS System Services Reference Manual.

11.1 OpenVMS Calling Standard

The OpenVMS Calling Standard describes the concepts used by OpenVMS languages for invoking routines and passing data between them. It also describes the differences between the OpenVMS VAX and OpenVMS Alpha parameter passing mechanisms. The OpenVMS Calling Standard specifies the following attributes:

The following sections discuss these attributes in more detail. The OpenVMS Calling Standard also defines such attributes as the calling sequence, the argument data types and descriptor formats, condition handling, and stack unwinding. These attributes are discussed in detail in the Introduction to VMS System Routines.

11.1.1 Register and Stack Usage

The OpenVMS Calling Standard defines registers and their uses, as listed in Table 11-1 and Table 11-2.

Table 11-1 VAX Register Usage
Register Use
PC Program counter
SP Stack pointer
FP Current stack frame pointer
AP Argument pointer (when necessary)
R1 Environment value (when necessary)
R0, R1 Function value return registers

Table 11-2 AXP Register Usage
Register Use
PC Program counter
SP Stack pointer
FP Frame pointer for current procedure
R25 Argument information register
R16 to R21,
F16 to F21
Argument list registers
R0 Function value return register

By definition, any called routine can use registers R2 through R11 for computation, and the AP register as a temporary register.

Figure 11-1 The Call Stack ( OpenVMS VAX)


In the OpenVMS Calling Standard, a stack is defined as a LIFO (last-in/first-out) temporary storage area that the system allocates for every user process. The system keeps information about each routine call in the current image on the call stack. Then, each time you call a routine, the system creates a structure on this call stack, known as the call frame. The call frame for each active procedure contains the following:

Figure 11-1 illustrates the call stack and several call frames. Procedure A calls procedure B, which calls procedure C.

When a routine completes execution, the system uses the frame pointer in the call frame of the current routine to locate the frame of the previous routine. The system then removes the call frame of the current routine from the stack.

11.1.2 Return of the Function Value

A function is a routine that returns a single value to the calling routine. The function value is the value returned to the caller. According to the calling standard, a function value may be returned as either an actual value or a condition value that indicates success or failure.

11.1.3 The Argument List

The OpenVMS Calling Standard also defines a data structure called the argument list. You use an argument list to pass information to a routine and receive results.

On OpenVMS Alpha systems, an argument list is formed using registers R16 to R21 or F16 to F21 and a collection of quadwords in memory (depending on the number and type of the arguments.

On VAX systems, an argument list is a collection of longwords in memory that represents a routine parameter list and possibly includes information for the return of a function value, if a function returns a value that is not suitable for return in R0 or R0/R1. Figure 11-2 shows the structure of a typical OpenVMS VAX argument list.

Figure 11-2 Structure of an OpenVMS VAX Argument List


The first longword must be present; this longword stores the number of arguments (the argument count: n) as an unsigned integer value in the low byte of the longword. The remaining 24 bits of the first longword are reserved for use by Hewlett Packard and should be zero. The longwords labeled arg1 through argn are the actual parameters, which can be any of the following:

The argument list contains the parameters that are passed to the routine. Depending on the passing mechanisms for these parameters, the forms of the arguments contained in the argument list vary. For example, if you pass three arguments, the first by value, the second by reference, and the third by descriptor, the argument list contains the value of the first argument, the address of the second, and the address of the descriptor of the third. Figure 11-3 shows this argument list.

Figure 11-3 Example of an OpenVMS VAX Argument List


11.2 Parameter-Passing Mechanisms

To pass data between routines that are not written in the same OpenVMS language, you must specify how you want that data to be represented and interpreted. You do this by specifying a parameter-passing mechanism. The three general parameter-passing mechanisms and their keywords and abbreviations in PL/I are as follows:

The parameter-passing mechanisms are intended for use only in calling non-PL/I routines. External routines written in PL/I should be called with the default mechanisms.

The following sections describe the arguments in terms of PL/I data types, dummy arguments created (if any), parameter-passing mechanism conventions, and attributes to define the manner in which parameters are to be passed. Remember that when PL/I creates a dummy argument, modifications, if any, that the called procedure makes to the dummy argument are not accessible to the caller.

11.2.1 Passing Parameters by Reference

When you pass a parameter by reference, the PL/I compiler passes the address at which the actual parameter value is stored. In other words, your routine has access to the parameter's storage address. Therefore, when you manipulate and change the value of this parameter, the changed value overwrites the previous value of the parameter. Thus, when you pass a parameter by reference, any changes that you make to the value of the parameter in your routine are reflected in the calling routine as well, provided a dummy argument is not created.

You can pass an argument of any data type by reference. This mechanism is the default used by PL/I for all arguments except character strings or arrays with nonconstant extents, and unaligned bit strings. Note that bit-string variables must have the ALIGNED attribute to be passed by reference. In general, the parameter descriptor for an argument to be passed by reference need specify only the data type of the parameter.

For example, the Read Event Flags (SYS$READEF) system service requires its first argument to be passed by value and its second argument to be passed by reference. This PL/I procedure can be declared as follows:


DECLARE SYS$READEF ENTRY (FIXED BINARY(31) VALUE, 
                          BIT(32) ALIGNED); 

Note

Most OpenVMS routines have declarations in PLI$STARLET; it is therefore not normally necessary to declare them yourself.

When this procedure is invoked, the second argument must be a variable declared as BIT(32) ALIGNED. PL/I passes the argument by reference. The following PL/I code example with Figure 11-4 illustrates argument passing by reference.


DECLARE FLAGS BIT(32) ALIGNED; 
DECLARE SYS$READEF ENTRY ( 
        FIXED BINARY(31) VALUE, 
        BIT(32) ALIGNED; 
     .
     .
     .
CALL SYS$READEF(4, FLAGS); 

Figure 11-4 Argument Passing by Reference


The data types in the parameter descriptors of all output arguments must match the data types of the written arguments.

11.2.1.1 Using the ANY Attribute

When you write a parameter descriptor for a non-PL/I procedure, you can specify the ANY attribute without the VALUE attribute to describe an argument that is to be passed by reference. The argument can be of any addressable data type known to PL/I. For example, the SYS$READEF service can be specified as follows:


DECLARE SYS$READEF ENTRY (FIXED BINARY(31) VALUE, ANY); 

The second parameter descriptor in the ENTRY attribute indicates that the second argument is to be passed by reference to the procedure SYS$READEF and that it can have any data type. When you specify ANY for an argument to be passed by reference, you cannot specify data type attributes. Note that if you specify the VALUE attribute in conjunction with the ANY attribute, PL/I passes the argument by value.

The ANY attribute is especially useful when you must specify a data structure as an argument. You need not declare the structure within the parameter descriptor, only the ANY attribute.


Previous Next Contents Index