Skip to content

gmSCOpcodeClass

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.


Prototype

extern int codeStore;

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


Prototype

extern UBYTE* codptr;

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


Prototype

extern int language_nuser;

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


Prototype

extern int lcstate;

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


Prototype

extern int opcLength[];

The opcLength field contains the byte code length of opcodes by opcode type


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.


Prototype

extern UBYTE* userint;

The userint field contains the packed language user interface information.


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:

ParameterDescription
varNameContains the name of the variable to be added.
subRootSpecifies 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.
varTypeSpecifies the binary type of the variable.
afterSpecifies 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.


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.


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:

ParameterDescription
icodeSpecifies the offset in the global code block where the deletion is to begin.
nDeleteSpecifies the number of existing operations to be deleted.

The method itself has no return value.


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:

ParameterDescription
iStartSpecifies the starting offset of the code to be displayed.
iEndSpecifies 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.


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:

ParameterDescription
userCodeSpecifies the code block that contains the argument code.
iStartSpecifies the offset of the start of the argument code.
iEndSpecifies 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.


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:

ParameterDescription
icodeSpecifies the offset of the start of the suspected Lvalue code.
xQuantReceives 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.


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:

ParameterDescription
subRootSpecifies the root offset of the component to which the code belongs.
icodeSpecifies the offset of the start of the code subsegment whose binary type is
needed. This may or may not be an actual argument description.
lcodeSpecifies 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.
xQuantReceives detailed quantity information about the type of the code segment, if
specified.

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


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:

ParameterDescription
subRootSpecifies the root offset of the method performing the call.
lastNewSpecifies the byte code offset of the start of the code for the actual statement
performing the call.
funcCodeSpecifies the offset of the operation that is doing the call.
qeAddrReceives the starting offset of the code for each argument.
qeTypeReceives the quantity type code for each argument.
qeContextReceives any context flags associated with the argument, if not NULL,
qeFlagsReceives any migration status flags associated with the argument, if not NULL.
nArgSpecifies 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.


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.


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:

OffsetDescription of content
OPCODE_LENGTHLength of each opcode entry
OPCODE_NIDENTLength of each opcode identifier
OPCODE_IDENTOffset of identifier
OPCODE_VALUEOffset of value
OPCODE_TYPEOffset of type
OPCODE_ROLEOffset of role
OPCODE_SUBCODESOffset of subcode count
OPCODE_SUBLISTOffset of offset of subcode list
OPCODE_INTERFACEOffset of interface offset

Its parameter is:

ParameterDescription
opcodeSpecifies 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.


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.


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:

ParameterDescription
baseSpecifies the base address in metalanguage storage of the augmented list.
entrySpecifies 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.


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:

ParameterDescription
opcodeSpecifies the index of the opcode controlling the operation.This was the opc
attribute of opcode when it was defined.
subcodeSpecifies 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.


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:

ParameterDescription
opcodeSpecifies the index of the opcode controlling the operation.This was the opc
attribute of opcode when it was defined.
subcodeSpecifies the sequence number of the desired subcode associated the operation.
xQuantReceives 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.


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:

TypeLen Meaning
OPCTYP_ARITHMETIC2 is an arithmetic operation with hierarchy
OPCTYP_SINGLEBYTE1 consists of a single byte operation code
OPCTYP_DOUBLEBYTE2 Consists of a 2-byte operation code
OPCTYP_SHORTVALUE3 Operation code followed by 2-byte value
OPCTYP_SYMBOLADDR5 Operation code followed by 4-byte symbol address
OPCTYP_STRINGADDR5 Operation code followed by 4-byte string address
OPCTYP_OPCODEADDR5 Operation code followed by 4-byte pcode offset
OPCTYP_BINARYTYPE2 2-byte operation specifying binary type
OPCTYP_LIBRARYADR5 Operation code followed by 4-byte library offset
OPCTYP_LIBPATTERN5 Operation code followed by 4-byte pattern offset
OPCTYP_OBJECTTYPE5 Operation code followed by 4-byte object type code

Its parameters are:

ParameterDescription
pcodeContains the code block being traversed.
opadrSpecifies the offset in the code block of the current operation.
codeEndSpecifies 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.


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:

ParameterDescription
pcodeContains the code block whose operations are being examined.
opadrSpecifies the offset in the code block of the desired operation.
subcodereturns the subcode associated with the operation.

The method returns the opcode of the operation.


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:

ParameterDescription
pcodeContains the code block being traversed.
opadrSpecifies the offset of an operation in the code block that is known to precede the
current one.
codeEndSpecifies 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.


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:

ParameterDescription
opcodeSpecifies the index of the opcode controlling the operation. This was the
opc attribute of opcode when it was defined.
subcodeSpecifies the sequence number of the desired subcode associated the operation.
statusreturns the status code of the operation if not NULL.

The method returns the role code of the operation.


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:

ParameterDescription
iStartSpecifies the offset of the first operation defining the value.
iEndSpecifies the offset immediately beyond the last operation for the value.
sValueReceives the computed string.

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


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:

ParameterDescription
opcodeSpecifies the index of the opcode controlling the operation. This was the opc
attribute of opcode when it was defined.
subcodeSpecifies 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.


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:

ParameterDescription
iDestSpecifies the offset in the global code block of the destination of the move.
iStartSpecifies the offset of the source of the move.
nCodeSpecifies the overall length of the byte code.
nMoveSpecifies the number of byte codes to move.

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


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:

ByteDescription of content
0Length of opcode information always 11 here
1-4Opcode identifier terminated by a null byte—all have 3 chars
5Value to be assigned for that opcode
6Opcode type code
7Opcode role code
8Number of subcodes
9-12Offset in storage of subcode list (set to zero here)
13-16Offset 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:

ByteDescription of content
0Length of symbol information
1+Actual symbol terminated by a null
2The integer identifier for the symbol
3-6The 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:

ParameterDescription
commandContains 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.
nCommandSpecifies the size of the command buffer. It is needed since that buffer is used
within this method to contain its subcommands.


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:

ParameterDescription
icodeSpecifies the offset in the global code block where the replacement is to begin.
opcodeSpecifies the index of the opcode of the operation to be inserted.
subcodeContains the sequence number of the desired subcode associated the operation.
nReplaceSpecifies 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.


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:

ParameterDescription
ptrSpecifies a new value for the codptr field.

The method has no return value.


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:

ParameterDescription
iValueSpecifies a new value for the pcnt field.

The method has no return value.


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:

ParameterDescription
pcodeContains the code block to receive the operation.
opadrSpecifies the offset in the code block where the operation is to be stored.
opcSpecifies the index of the opcode of the operation to be inserted.
subcodeSpecifies the value of the desired subcode associated the operation.

The method has no return value.


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:

ParameterDescription
opcodeSpecifies 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.
subcodeSpecifies 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.
RootSpecifies 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.


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:

ParameterDescription
opcSpecifies the index of the opcode whose operation length is needed.

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


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:

MemberDescription of use
nTempInitialized at the value of nTemp parameter as passed in and not used beyond
that here.
lastNewCode offset of operation following the last encountered NEW opcode.
lastTmpCode 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.
argRootRoot offset of current argument being called
argTypeInitialized at zero, not used within this method
objRootInitialized at zero, not used within this method
argBase[]Root offset of current argument being called at each call nesting level.
nLevCurrent call nesting level
deltaInitialized at zero and is the value finally returned by this method
iCallInitialized at the value of iCall parameter as passed in and not used beyond
that here.
iStartCurrent code offset of the ARG operation for the current argument.

The parameters of this method are:

ParameterDescription
subRootSpecifies the root offset of the subprogram whose code is currently loaded in
the global code block.
iCallSpecifies a unique call identifier which can be used for debugging purposes.
nTempSpecifies the sequence number to be assigned to any temporary that has to be
created. The use of this value has been deprecated.
VisitArgumentspecifies 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.