Page tree
Skip to end of metadata
Go to start of metadata

The Opcode Service Class

The service class Opcode works with the intermediate language streams. Its methods actively manage and reference the operations of the intermediate language. Their description and use assumes a knowledge of the intermediate language and of its internal structure.

The methods in this class assume the operation code and symbol conventions of the Basic processor. The methods that deal with the non processor specific language stream are contained in the Emit class.

The field codeStore

Prototype


extern int codeStore;
The codeStore field specifies selection handle for the storage area referenced within code operations.

The field codptr

Prototype


extern UBYTE* codptr;
The codptr field is the global code block assumed by most of the methods within this class.

The field language_nuser

Prototype


extern int language_nuser;
The language_nuser field is the currently used amount of the language packed user interface information.

The field lcstate

Prototype


extern int lcstate;
The lcstate field contains the starting offset of the current statement being compiled.

The field opcLength

Prototype


extern int opcLength[];
The opcLength field contains the byte code length of opcodes by opcode type

The field pcnt

Prototype


extern int pcnt;
The pcnt field specifies the current emission ending offset or length of the operation code stored in the global code block.

The field userint

Prototype


extern UBYTE* userint;
The userint field contains the packed language user interface information.

The method Opcode_AddVariable

Prototype


int Opcode_AddVariable(char* varName,int subRoot,int varType,int after);
The Opcode_AddVariable method enters a variable into the symbol table as the child of a subprogram. In addition, it enters a DCL operation for that variable into the currently loaded operation code. Its parameters are:

Parameter Description
varName Contains the name of the variable to be added.
subRoot Specifies the root offset of the subprogram to which the variable is to be added. It is assumed that the currently loaded code belongs to this subprogram.
varType Specifies the binary type of the variable.
after Specifies if zero, that the DCL should be placed first in the code; if not zero, the DCL is placed after any beginning DCL or comment operations in the code.

The method returns the length of the DCL operation code added if the variable add was successful; else it returns zero.

The method Opcode_CommentOut

Prototype


int Opcode_CommentOut(int iStart,int cmtType);
The Opcode_CommentOut method comments out a block of intermediate operations so that they will either not appear in the target translation at all or at least will be commented out in the target translation. Its parameters are:

Parameter Description
iStart is the offset in the global code block of the component whose presence is causing the need to comment out the statement.
cmtType Specifies how the commented out code is to appear, or not appear, in the output:

cmtType Description
Delete Removes the statement from the authored output
CommentOut Precedes the statement with a comment identifying the causing component and then comments the statement out.
Deprecated Precedes the statement with a Deprecated comment identifying the causing component and then does not comment the statement out.
NotImplemented Precedes the statement with a Not Implemented comment identifying the causing component, and then comments the statement out.
MustCorrect Precedes the statement with a Must Correct comment identifying the causing component, and then comments the statement out.


The method returns the offset in the global code block of the inserted CMT operation unless that operation was stored at the back of the code block. In that case, -1 is returned.

The method Opcode_Delete

Prototype


void Opcode_Delete(int icode,int nDelete);
The Opcode_Delete method deletes one or more operations stored in the global code block. From the standpoint of the gmSL this along with Opcode_Replace are the preferred methods for removing and inserting operations into the global code block. Its parameters are:

Parameter Description
icode Specifies the offset in the global code block where the deletion is to begin.
nDelete Specifies the number of existing operations to be deleted.

The method itself has no return value.

The method Opcode_DumpCode

Prototype


void Opcode_DumpCode(int iStart,int iEnd);
The Opcode_DumpCode method gives a code dump display from the global code vector used to contain the compiled code associated with the various components. Its parameters are:

Parameter Description
iStart Specifies the starting offset of the code to be displayed.
iEnd Specifies the ending offset. The method checks that the value of iEnd does not exceed the current length of the code storage area stored in pcnt.

The method has no return value.

The method Opcode_FindArgumentEnd

Prototype


int Opcode_FindArgumentEnd(UBYTE* userCode,int iStart,int iEnd);
The Opcode_FindArgumentEnd method finds the end of the code associated with a given argument within a larger code block. Note that argument code always begins with a LEV operation which specifies the nesting level of the argument code, and ends with a ARG operation which specifies the type of the parameter that is to receive the argument. Its parameters are:

Parameter Description
userCode Specifies the code block that contains the argument code.
iStart Specifies the offset of the start of the argument code.
iEnd Specifies the offset of the end of the search region. This is normally simply set to the overall length of the code block.

The method returns the end of the argument code which is the offset of the first operation following the ARG operation.

The method Opcode_FindLvalueEnd

Prototype


int Opcode_FindLvalueEnd(int icode,tQuantity* xQuant);
The Opcode_FindLvalueEnd method finds the end of the code associated with a given Lvalue -- variable expression capable of receiving a value -- argument within the global code block. Its parameters are:

Parameter Description
icode Specifies the offset of the start of the suspected Lvalue code.
xQuant Receives the binary type of the Lvalue, if non-NULL.

If the operation code starting at icode does specify an Lvalue, then the method returns the offset of the first byte beyond its end. If not, then a zero is returned.

The method Opcode_GetArgumentType

Prototype


int Opcode_GetArgumentType(int subRoot,int icode,int lcode,tQuantity* xQuant);
The Opcode_GetArgumentType method evaluates the binary type of a code subsegment within the global code vector used to contain the compiled code associated with the various components. Its parameters are:

Parameter Description
subRoot Specifies the root offset of the component to which the code belongs.
icode Specifies the offset of the start of the code subsegment whose binary type is needed. This may or may not be an actual argument description.
lcode Specifies the end of the subsegment. If it is nonzero, then it simply specifies the length of the subsegment. If it is zero, and the opcode at the start is LEV, then the entire argument code is evaluated. This is the typical use of this method. If it is zero and the starting opcode is not LEV, then only that one opcode is evaluated.
xQuant Receives detailed quantity information about the type of the code segment, if specified.

The method returns the binary type code of the code segment.

The method Opcode_GetCallArgs

Prototype


int Opcode_GetCallArgs(int subRoot,int lastNew,int funcCode,int* qeAddr,int* qeType,
                       int* qeContext,int* qeFlags,int nArg);
The Opcode_GetCallArgs method gets the byte code offset and binary type of the actual calling arguments to a method. The method optionally also gets the context and migration status flags of the arguments. Its parameters are:

Parameter Description
subRoot Specifies the root offset of the method performing the call.
lastNew Specifies the byte code offset of the start of the code for the actual statement performing the call.
funcCode Specifies the offset of the operation that is doing the call.
qeAddr Receives the starting offset of the code for each argument.
qeType Receives the quantity type code for each argument.
qeContext Receives any context flags associated with the argument, if not NULL,
qeFlags Receives any migration status flags associated with the argument, if not NULL.
nArg Specifies the number of parameters associated with the method. At this level, all methods have a fixed number of parameters that is determined when they are defined and that must be known when this method is called.

If this method is unable to isolate the calling argument code it returns a zero; else it returns the number of arguments as found and as specified in the parameter nArg.

The method Opcode_GetCode

Prototype


void* Opcode_GetCode(void)
The Opcode_GetCode method returns the value of the global field codptr which Contains the current code block. It is primarily intended for use by gmSL and gmNI which do not have access to the global fields. The method has no parameters.

The method returns the current value of the codptr field.

The method Opcode_GetInfo

Prototype


UBYTE* Opcode_GetInfo(int opcode);
The Opcode_GetInfo method gets information about an opcode in the gmIL given its numeric index. The information itself is stored in packed form and is accessed via a byte pointer. The offsets of the opcode properties as specified as follows:

Offset Description of content
OPCODE_LENGTH Length of each opcode entry
OPCODE_NIDENT Length of each opcode identifier
OPCODE_IDENT Offset of identifier
OPCODE_VALUE Offset of value
OPCODE_TYPE Offset of type
OPCODE_ROLE Offset of role
OPCODE_SUBCODES Offset of subcode count
OPCODE_SUBLIST Offset of offset of subcode list
OPCODE_INTERFACE Offset of interface offset

Its parameter is:

Parameter Description
opcode Specifies the sequence number of the desired opcode. This was the opc attribute of opcode when it was defined. These are normally defined as constants in a language specific header file.

The method returns a byte pointer to the information for the specified opcode. If there is no opcode defined with the specified index, a NULL is returned.

The method Opcode_GetLength

Prototype


int Opcode_GetLength(void);
The Opcode_GetLength method returns the value of the global field pcnt which Contains the current emission ending offset or length of the operation code stored in the global code block. It is primarily intended for use by gmSL and gmNI which do not have access to the global fields. The method has no parameters.

The method returns the current value of the pcnt field.

The method Opcode_GetListEntry

Prototype


UBYTE* Opcode_GetListEntry(int base,int entry);
The Opcode_GetListEntry method looks up a specific entry in a metalanguage list when that list has an entry offset table associated with it -- such as a subcodes table for an opcode. In these cases, the base of the list is known and is passed to this method along with the number of the desired entry. Its parameters are:

Parameter Description
base Specifies the base address in metalanguage storage of the augmented list.
entry Specifies the number of the desired entry from the list.

The method returns a pointer to the actual entry information or NULL if no entry information is available for the desired entry.

The method Opcode_GetMember

Prototype


int Opcode_GetMember(int opcode,int subcode);
The Opcode_GetMember method gets the library member associated with an operation. Those opcodes that have the role CLSREF (class reference) can have a full library component associated with them in language storage. This library component is used to contain additional migration information about the underlying class component. This method retrieves the root address of this component in the subcode information storage area. A zero root address means that there is no class member associated with the opcode-subcode pair. Its parameters are:

Parameter Description
opcode Specifies the index of the opcode controlling the operation.This was the opc attribute of opcode when it was defined.
subcode Specifies the sequence number of the desired subcode associated the operation.

If the operation does not have a library member associated with it then this method returns a zero; else the offset in language storage of the associated member is returned.

The method Opcode_GetMemberType

Prototype


int Opcode_GetMemberType(int opcode,int subcode,tQuantity* xQuant);
The Opcode_GetMemberType method gets the type and context information associated with a specified operation. Its parameters are:

Parameter Description
opcode Specifies the index of the opcode controlling the operation.This was the opc attribute of opcode when it was defined.
subcode Specifies the sequence number of the desired subcode associated the operation.
xQuant Receives the type and context attributes of the information if it is not NULL.

If the specified operation has a library component associated with it then the type of that component is returned; else a TYP_VOID is returned.

The method Opcode_GetNext

Prototype


int Opcode_GetNext(UBYTE* pcode,int opadr,int codeEnd);
The Opcode_GetNext method moves to the next operation in a code block. It uses the opcode type to look up the length of the current opcode. The opcode types and their lengths are as follows:

Type Len Meaning
OPCTYP_ARITHMETIC 2 is an arithmetic operation with hierarchy
OPCTYP_SINGLEBYTE 1 consists of a single byte operation code
OPCTYP_DOUBLEBYTE 2 Consists of a 2-byte operation code
OPCTYP_SHORTVALUE 3 Operation code followed by 2-byte value
OPCTYP_SYMBOLADDR 5 Operation code followed by 4-byte symbol address
OPCTYP_STRINGADDR 5 Operation code followed by 4-byte string address
OPCTYP_OPCODEADDR 5 Operation code followed by 4-byte pcode offset
OPCTYP_BINARYTYPE 2 2-byte operation specifying binary type
OPCTYP_LIBRARYADR 5 Operation code followed by 4-byte library offset
OPCTYP_LIBPATTERN 5 Operation code followed by 4-byte pattern offset
OPCTYP_OBJECTTYPE 5 Operation code followed by 4-byte object type code

Its parameters are:

Parameter Description
pcode Contains the code block being traversed.
opadr Specifies the offset in the code block of the current operation.
codeEnd Specifies the traversal length of the code block.

The method returns the offset of the following operation if there is one. If the current operation is the last one, then a minus one is returned.

The method Opcode_GetOperation

Prototype


int Opcode_GetOperation(UBYTE* pcode,int opadr,int* subcode);
The Opcode_GetOperation method gets the value of the current operation in a code block. Its parameters are:

Parameter Description
pcode Contains the code block whose operations are being examined.
opadr Specifies the offset in the code block of the desired operation.
subcode returns the subcode associated with the operation.

The method returns the opcode of the operation.

The method Opcode_GetPrevious

Prototype


int Opcode_GetPrevious(UBYTE* pcode,int opadr,int codeEnd);
The Opcode_GetPrevious method moves to a previous operation in a code block. This method returns the offset of the start of the operation code that is directly before an operation code offset specified. Since the operation codes are variable-length and are stored sequentially, this operation requires that the code be scanned from the front starting with a known operation offset. Its parameters are:

Parameter Description
pcode Contains the code block being traversed.
opadr Specifies the offset of an operation in the code block that is known to precede the current one.
codeEnd Specifies the offset in the code block of the current operation.

The operation offset returned by this method will be between these two offsets or will simply be set equal to the starting offset.

The method Opcode_GetRoleStatus

Prototype


int Opcode_GetRoleStatus(int opcode,int subcode,int* status);
The Opcode_GetRoleStatus method returns the role code of a specified operation. It optionally also returns the status code. In this case the role code is a member of the LIBROLE enumeration and the status code is a member of the LIBSTATUS enumeration. Its parameters are:

Parameter Description
opcode Specifies the index of the opcode controlling the operation. This was the opc attribute of opcode when it was defined.
subcode Specifies the sequence number of the desired subcode associated the operation.
status returns the status code of the operation if not NULL.

The method returns the role code of the operation.

The method Opcode_GetString

Prototype


int Opcode_GetString(int iStart,int iEnd,char* sValue);
The Opcode_GetString method computes the string value represented by a sequence of operations in the global code block. The computation itself is performed by the same engine that executes the gmSL procedures. Its parameters are:

Parameter Description
iStart Specifies the offset of the first operation defining the value.
iEnd Specifies the offset immediately beyond the last operation for the value.
sValue Receives the computed string.

The method returns one if the computation was successful, else it returns zero.

The method Opcode_GetSubcodeLabel

Prototype


char* Opcode_GetSubcodeLabel(int opcode,int subcode);
The Opcode_GetSubcodeLabel gets the label for a subcode of an opcode. This is the label entered in the language description under the subcodes specification for the opcode. Its parameters are:

Parameter Description
opcode Specifies the index of the opcode controlling the operation. This was the opc attribute of opcode when it was defined.
subcode Specifies the sequence number of the desired subcode associated the operation.

The method returns a character pointer to the label for the subcode in null-terminated form. If the subcode has no label defined, then a NULL is returned.

The method Opcode_MoveCode

Prototype


int Opcode_MoveCode(int iDest,int iStart,int nCode,int nMove);
The Opcode_MoveCode method moves byte code from one location in the global code block to a different location in that block. This is a move operation so the byte code is removed from its original location. The parameters of the method are:

Parameter Description
iDest Specifies the offset in the global code block of the destination of the move.
iStart Specifies the offset of the source of the move.
nCode Specifies the overall length of the byte code.
nMove Specifies the number of byte codes to move.

The method returns the offset of the code destination once the move has been completed.

The method Opcode_ReadOpcodes

Prototype


int Opcode_ReadOpcodes(char* command,int nCommand);
The Opcode_ReadOpcodes method reads the opcode information into the language user interface storage as specified via the Opcodes statement. Each opcode is stored as follows:

Byte Description of content
0 Length of opcode information always 11 here
1-4 Opcode identifier terminated by a null byte--all have 3 chars
5 Value to be assigned for that opcode
6 Opcode type code
7 Opcode role code
8 Number of subcodes
9-12 Offset in storage of subcode list (set to zero here)
13-16 Offset of interface class root offset

Within each opcode statement there are a series of subcode statements stored as a standard list. Each entry has the following structure:

Byte Description of content
0 Length of symbol information
1+ Actual symbol terminated by a null
2 The integer identifier for the symbol
3-6 The offset of the supporting class member

The start of the assembled opcode information is storage in the LNGINF_OPCODES location in boot record of user interface storage.

The parameters of this method are:

Parameter Description
command Contains the actual Opcodes command as entered in a Language definition script. As this method processes the opcode and subcode subcommands introduced by this command, it uses this buffer to contain them.
nCommand Specifies the size of the command buffer. It is needed since that buffer is used within this method to contain its subcommands.


The method Opcode_Replace

Prototype


void Opcode_Replace(int icode,int opcode,int subcode,int nReplace);
The Opcode_Replace method replaces zero or more operations stored in the global code block with a new operation. Its parameters are:

Parameter Description
icode Specifies the offset in the global code block where the replacement is to begin.
opcode Specifies the index of the opcode of the operation to be inserted.
subcode Contains the sequence number of the desired subcode associated the operation.
nReplace Specifies the number of existing operations to be replaced. A value of zero indicates that the new operation should simply be inserted.

The method has no return value.

The method Opcode_SetCode

Prototype


void Opcode_SetCode(void* ptr);
The Opcode_SetCode method sets the value of the global field codptr which Contains the current code block. It is primarily intended for use by gmSL and gmNI which do not have access to the global fields. Its parameter is:

Parameter Description
ptr Specifies a new value for the codptr field.

The method has no return value.

The method Opcode_SetLength

Prototype


void Opcode_SetLength(int iValue);
The Opcode_SetLength method sets the value of the global field pcnt which Contains the current emission ending offset or length of the operation code stored in the global code block. It is primarily intended for use by gmSL and gmNI which do not have access to the global fields. Its parameter is:

Parameter Description
iValue Specifies a new value for the pcnt field.

The method has no return value.

The method Opcode_SetOperation

Prototype


void Opcode_SetOperation(UBYTE* pcode,int opadr,int opc,int subcode);
The Opcode_SetOperation method stores an operation at a particular location in a code block. It is a low level method and assumes that space has been allocated for the storage. Its parameters are:

Parameter Description
pcode Contains the code block to receive the operation.
opadr Specifies the offset in the code block where the operation is to be stored.
opc Specifies the index of the opcode of the operation to be inserted.
subcode Specifies the value of the desired subcode associated the operation.

The method has no return value.

The method Opcode_SetSubcodeMember

Prototype


int Opcode_SetSubcodeMember(int opcode,int subcode,int iRoot);
The Opcode_SetSubcodeMember method sets the member root for a subcode. Each operation, opcode, subcode pair) can have a full library component associated with them in language storage. This library component is used to contain additional migration information about the underlying component being referenced by the operation. This method stores the root address of this component in the subcode standard list storage. Its parameters are:

Parameter Description
opcode Specifies the sequence number of the desired opcode. This was the opc attribute of the opcode when it was defined. These are normally defined as constants in a language specific header file.
subcode Specifies the sequence number of the desired subcode of the opcode. This was the subcode attribute when it was defined in the metalanguage. These codes will also normally be defined as constants in the language specific header file using a symbol like OPC_subcodelabel. A subcode of -1 means that the overall class member is being defined for the opcode.
Root Specifies the root address of the class member in the language storage area.

If the opcode is does not have subcodes then a one is returned and the root is not stored. If the opcode-subcode combination already has a member root associated with it, then a two is returned and the root is not stored. If there is no root yet associated with the pair, then the root is stored in the table and a zero is returned.

The method Opcode_Sizeof

Prototype


int Opcode_Sizeof(int opc);
The Opcode_Sizeof method returns the length in bytes of an operation associated with the opcode. Its parameter is:

Parameter Description
opc Specifies the index of the opcode whose operation length is needed.

The method returns the length in bytes of the associated operation.

The method Opcode_TraverseArgs

Prototype


int Opcode_TraverseArgs(int subRoot,int iCall,int nTemp,VisitArgument_ptr VisitArgument);
The Opcode_TraverseArgs method is a traversal method that finds all argument code and its associated parameter root and calls a method that performs an actual argument code check of some sort. The method communicates with its service method via a tArgumentCode structure which has the following members:

Member Description of use
nTemp Initialized at the value of nTemp parameter as passed in and not used beyond that here.
lastNew Code offset of operation following the last encountered NEW opcode.
lastTmp Code offset of operation following the last encountered TMP opcode.
lastLev[] Code offset of operation following the last encountered LEV opcode at each call nesting level.
argRoot Root offset of current argument being called
argType Initialized at zero, not used within this method
objRoot Initialized at zero, not used within this method
argBase[] Root offset of current argument being called at each call nesting level.
nLev Current call nesting level
delta Initialized at zero and is the value finally returned by this method
iCall Initialized at the value of iCall parameter as passed in and not used beyond that here.
iStart Current code offset of the ARG operation for the current argument.

The parameters of this method are:

Parameter Description
subRoot Specifies the root offset of the subprogram whose code is currently loaded in the global code block.
iCall Specifies a unique call identifier which can be used for debugging purposes.
nTemp Specifies the sequence number to be assigned to any temporary that has to be created. The use of this value has been deprecated.
VisitArgument specifies the service handle of the method that is to perform the actual argument code check

The method returns the final value of the delta member of the communication structure. If non-zero that the content of the global code block was changed as a result of the traversal.
Table of Contents

  • No labels