[an error occurred while processing this directive]
HP OpenVMS Systems Documentation |
HP Pascal for OpenVMS
|
Previous | Contents | Index |
When the CLASS_S attribute is used on a formal parameter, the compiler generates a fixed-length scalar descriptor of a variable and passes its address to the called routine. Only ordinal, real, set, pointer, and one-dimensional packed arrays (fixed or conformant) that are of type OF CHAR can have the CLASS_S attribute on the formal parameter.
With the CLASS_S attribute, the type of passing semantics used for the
by descriptor argument depends on the use of the VAR keyword. If the
formal parameter name is preceded by the reserved word VAR, variable
semantics is used; otherwise, value semantics is used.
5.3.3.2 CLASS_A and CLASS_NCA Attributes
When you use the CLASS_A or CLASS_NCA attribute on a formal parameter, the compiler generates an array descriptor and passes its address to the called routine. The type of the CLASS_A and CLASS_NCA parameter must be an array (packed or unpacked, fixed or conformant) of an ordinal or real type.
With the CLASS_A and CLASS_NCA attributes, the type of passing
semantics used for the by descriptor argument depends on the use of the
VAR keyword. If the formal parameter name is preceded by the reserved
word VAR, variable semantics is used; otherwise, value semantics is
used.
5.3.3.3 %STDESCR Mechanism Specifier
When you use the %STDESCR mechanism specifier, the compiler generates a fixed-length descriptor of a character-string variable and passes its address to the called routine. Only items of the following types can have the %STDESCR specifier on the actual parameter: character-string constants, string expressions, packed character arrays with lower bounds of 1, and packed conformant arrays with indexes of an integer or integer subrange type. The passing semantics depend on the variable represented by the actual parameter as follows:
If the actual parameter is not modified by the called external routine, the corresponding formal parameter should be declared READONLY, saving the copy from having to be made.
The following function declaration requires one fixed-length string descriptor as a parameter:
[ASYNCHRONOUS,EXTERNAL(SYS$SETDDIR)] FUNCTION $SETDDIR (%STDESCR New_Dir : PACKED ARRAY [$L1..$U1: INTEGER] OF CHAR; VAR Old_Dir_Len : $UWORD := %IMMED 0; VAR Old_Dir : [CLASS_S]PACKED ARRAY [$L2..$U2 : INTEGER] OF CHAR := %IMMED 0) : INTEGER; EXTERN; . . . Status := $SETDDIR('[HP_Pascal]'); |
The actual parameter '[HP_Pascal]' is passed by string descriptor with
foreign semantics to the formal parameter New_Dir.
5.3.3.4 %DESCR Mechanism Specifier
When you use the %DESCR mechanism specifier, the parameter generates a descriptor for an ordinal, real, or array variable and passes its address to the called routine. The type of %DESCR parameter can be any ordinal or real type, a VARYING OF CHAR string, or an array (packed or unpacked, fixed or conformant) of an ordinal or real type.
The passing semantics depend on the actual parameter's data type as follows:
If the actual parameter is not modified by the called external routine, the corresponding formal parameter should be declared READONLY, saving the copy from having to be made.
The following function declaration requires a varying-length string descriptor as its parameter:
TYPE Vary = VARYING [30] OF CHAR; VAR Obj_String : Vary; Times_Found : INTEGER; [EXTERNAL] FUNCTION Search_String( %DESCR String_Val : Vary ) : BOOLEAN; EXTERNAL; . . . IF Search_String( Obj_String ) THEN Times_Found := Times_Found + 1; |
The actual parameter Obj_String is passed by varying string descriptor with variable semantics to the formal parameter String_Val.
Table 5-4 summarizes the passing semantics used when various mechanisms are specified on either the formal or the actual parameter. For example, if a variable is passed to a formal parameter that was declared without the keyword VAR and either %REF or [REFERENCE] was specified, then variable passing semantics will be used. Likewise, if a variable is passed to a formal parameter which was declared with the keyword VAR and either %REF or [REFERENCE] was specified, then an error will occur.
If an actual parameter is preceded by an %IMMED specifier, regardless of what passing mechanism is used to declare the formal parameter, foreign semantics would be used, because a specifier appearing on the actual parameter always overrides the semantics specified on the formal parameter.
Actual Parameter | ||||
---|---|---|---|---|
Variable | (Variable) or Expression | |||
Passing Mechanism | No VAR on Formal |
VAR on Formal |
No VAR on Formal |
VAR on Formal |
By immediate value
%IMMED or [IMMEDIATE] |
Foreign |
Error |
Foreign |
Error |
By reference
Default for non- conformant or nonschema %REF or [REFERENCE] |
Value Variable |
Variable Error |
Value Foreign |
Value 1 Error |
By descriptor
Default for conformant and schema [CLASS_S] [CLASS_A] [CLASS_NCA] %STDESCR %DESCR |
Value Value Value Value Variable Variable |
Variable Variable Variable Variable Error Error |
Value Value Value Value Foreign Foreign |
Value 1 Value 1 Value 1 Value 1 Error Error |
Passing parameters between HP Pascal and other languages on
OpenVMS systems requires some additional knowledge about the
semantics and mechanisms used by the HP Pascal and the other
compilers involved.
5.4.1 Parameter Mechanisms Versus Parameter Semantics
The Pascal language provides three parameter semantics: "VAR parameters," "value parameters," and "routine parameters." These models define what happens to the parameters, not how the compiler actually implements them. "VAR parameters" are parameters that represent the actual variable passed to the routine. Changes made to the VAR parameter are reflected back to the actual variable passed in to the routine. "Value parameters" are parameters that are local copies of the expression passed into the routine. Changes made to the value parameter are not reflected back to any actual parameter passed in to the routine. "Routine parameters" are parameters that represent entire routines that may be called from inside the called routine.
The HP Pascal compiler provides three parameter mechanisms: "by immediate value," "by reference," and "by descriptor." These forms represent the actual implementation used by the compiler for the parameter. These forms are denoted by the [IMMEDIATE], [CLASS_S], [CLASS_A], and [CLASS_NCA] attributes (note, the [REFERENCE] attribute doesn't just specify a parameter mechanism, but also specifies a parameter semantic model).
HP Pascal also provides a fourth parameter model called "foreign parameters." These parameters become either VAR or value parameters depending on the actual parameter. If the actual parameter is a variable, then the parameter is treated as a VAR parameter. If the actual parameter is an expression, then the parameter is treated as a value parameter. These parameters are denoted by the %REF, %DESCR, and %STDESCR foreign mechanism specifiers and the [REFERENCE] attribute (identical in behavior to the %REF foreign parameter specifier).
Be careful not to confuse the term "value parameter" with the
"by immediate value" mechanism. The "value" in
"value parameter" describes the semantics of the parameter
where changes made to the parameter inside the called routine are not
reflected back to the actual parameter. It is a common misconception
that HP Pascal uses the "by immediate value" mechanism
for "value parameters."
5.4.2 Passing Nonroutine Parameters between HP Pascal and Other Languages
By default, HP Pascal will use the "by reference" mechanism for the following VAR and value parameter types: Ordinal (integer, unsigned, char, Boolean, pointers, subranges, and enumerated types), Real (real, double, quadruple), Record, Array, Set, Varying, and File.
If you want to pass a parameter with the "by immediate value" mechanism, you can place the [IMMEDIATE] attribute on the definition of the formal parameter's definition or use the %IMMED foreign mechanism specifier on the actual parameter to override the default mechanism of the formal parameter. Only ordinal and real types may be passed with the "by immediate value" mechanism. Only value parameters may use the "by immediate value" mechanism.
If you want to accept a value parameter with the "by immediate value," you can place the [IMMEDIATE] attribute on the definition of the formal parameter. Only ordinal and real types may be accepted with the "by immediate value" mechanism.
For example, to pass an integer with the "by immediate value" mechanisn to another routine,
[external] procedure rtn( p : [immediate] integer ); external; begin rtn(3); rtn(some-integer-expression); end; |
If you want to pass a parameter with the "by descriptor" mechanism, you can place the [CLASS_A], [CLASS_S], or [CLASS_NCA] attributes on the formal parameter's definition. You can also use the %DESCR and %STDESCR foreign mechanism specifiers, but be aware that these also imply parameter semantics as well as the parameter-passing mechanism.
When passing values to a subrange parameter in a Pascal routine, the argument must be large enough to hold a value of the subrange's base-type even if the formal parameter contained a size attribute.
When passing Boolean or enumerated-type values to a VAR parameter in a Pascal routine, the calling routine must ensure that the sizes of the Boolean or enumerated-type matches the setting of the /ENUMERATION_SIZE qualifier or [ENUMERATION_SIZE] attribute used in the Pascal routine. For value parameters, you can pass the address of a longword as that will work for either setting.
When passing arrays or records to a Pascal routine, the calling routine must ensure that the array and record has the same layout (including any alignment holes) as chosen by the HP Pascal compiler. You may want to use the /SHOW=STRUCTURE_LAYOUT listing section to help you determine the layout chosen by the HP Pascal compiler.
By default, HP Pascal will use the "by descriptor" mechanism for VAR and value conformant parameters. For conformant-varying parameters, HP Pascal uses a CLASS_VS desciptor. For conformant-array parameters, HP Pascal uses a CLASS_NCA descriptor on OpenVMS I64 and OpenVMS Alpha systems and a CLASS_A descriptor on OpenVMS VAX systems.
Using a conformant-varying parameter or STRING schema parameter with a routine not written in Pascal is not very common since the called routine does not know how to deal with these strings. If you just are passing a string expression to the non-Pascal routine, using a conformant PACKED ARRAY OF CHAR is the right solution.
Since HP Pascal will use either a CLASS_A or CLASS_NCA descriptor for the conformant PACKED ARRAY OF CHAR, but other languages will expect either a CLASS_S descriptor or the string "by reference", you will need to use either the [CLASS_S] attribute or the %REF foreign mechanism specifier.
For example, to pass a string expression to Fortran (which expects a CLASS_S descriptor),
[external] procedure fortrtn( p : [class_s] packed array [l..u:integer] of char); external; begin fortrtn('string'); fortrtn(some-string-expression); end; |
To pass a string expression to C (which expects a "by-reference" parameter and a null-terminated string),
[external] procedure crtn( %ref p : packed array [l..u:integer] of char); external; begin crtn('string'(0)); crtn(some-string-expression+'0'); end; |
HP Pascal on OpenVMS I64 and OpenVMS Alpha systems has additional support to deal with null-terminated strings.
When passing strings to an HP Pascal routine from another language, you must use a descriptor if the Pascal formal parameter is a conformant parameter. HP Pascal cannot accept a conformant parameter with the "by reference" mechanism. For conformant array parameters, you must generate a CLASS_A descriptor on OpenVMS or a CLASS_NCA descriptor on OpenVMS Alpha unless you select another descriptor class using the [CLASS_S], [CLASS_A], or [CLASS_NCA] attributes. For conformant varying parameters, you must generate a CLASS_VS descriptor on both platforms.
If you wish to use the "by reference" mechanism to pass strings into a Pascal routine, you must define a Pascal datatype that represents a fixed-length string (or varying-string with a maximum size) and use that datatype in the formal parameter definition.
The HP Pascal schema type STRING is passed by CLASS_VS descriptor.
Other HP Pascal schema types use private data structures when
passed between routines and cannot be accessed from routines written in
other languages.
5.4.3 Passing Routine Parameters between HP Pascal and Other Languages
By default, HP Pascal on OpenVMS I64 systems passes the address of a function descriptor for PROCEDURE or FUNCTION parameters. The presence of the [UNBOUND] attribute or the %IMMED foreign mechanism specifier has no effect over the generated code since the function descriptors in the OpenVMS Calling Standard allow any combination of bound and unbound routines to be passed around and invoked.
On OpenVMS I64 systems, HP Pascal expects the address of a function descriptor for routine parameters. In all OpenVMS I64 languages, asking for the address of a routine yields the address of its function descriptor, since the actual address of the instructions is not useful by itself.
By default, HP Pascal on OpenVMS Alpha systems passes the address of a procedure descriptor for PROCEDURE or FUNCTION parameters. The presence of the [UNBOUND] attribute or the %IMMED foreign mechanism specifier has no effect over the generated code since the procedure descriptors in the OpenVMS Calling Standard allow any combination of bound and unbound routines to be passed around and invoked.
On OpenVMS Alpha systems, HP Pascal expects the address of a procedure descriptor for routine parameters. In all OpenVMS Alpha languages, asking for the address of a routine yields the address of its procedure descriptor, since the actual address of the instructions is not useful by itself.
By default, HP Pascal on OpenVMS VAX will pass the address of a BPV (Bound Procedure Value) for PROCEDURE or FUNCTION parameters. The BPV is a 2 longword structure with the 1st longword being the address of the entry mask of the routine being passed; the 2nd longword is either a 0 or a frame-pointer for any uplevel references that the called routine may attempt to perform. If you use the [UNBOUND] attribute on the PROCEDURE or FUNCTION parameter, the compiler still passes the address of a BPV, but the 2nd longword will always be zero. If you use the %IMMED foreign mechanism specifier along with the [UNBOUND] attribute, HP Pascal will pass the address of the routine with the "by immediate" mechanism.
For example, if you want to pass a Pascal routine to an external routine that just expects the address of the routine (like a C routine or system service),
[external] procedure crtn( %immed [unbound] procedure p); external; procedure x; begin ... end; begin crtn(x); end; |
Most system routines expect to be called in this fashion. A few routines like EDT$EDIT actually expect BPVs and not just entry point addresses.
On OpenVMS VAX, HP Pascal only accepts a routine parameter by BPV. To pass a routine from a non-Pascal routine to a Pascal routine, you must use the [UNBOUND] attribute on the formal routine parameter and you must pass the address of a longword containing the address of the routine's entry point.
Previous | Next | Contents | Index |