The Emit Service Class
The service class
Emit works with the intermediate language streams. Its methods make
no assumptions about the meaning or underlying structures of the operations in the language.
At this level these streams are referred to as "Emissions".
The field Emit_CodeSize
Prototype
extern int Emit_CodeSize;
The
Emit_CodeSize field contains the total number of bytes that have been allocated
the global emissions vector
codptr. Note this field is global since the manner in
which the size of this vector is specified varies by language processor.
The method Emit_ByteInteger
Prototype
void Emit_ByteInteger(int byteValue,int iValue);
The
Emit_ByteInteger method emits a byte integer sequence. If there is sufficient
room, this method enters a sequence of a byte value followed by an integer value into the
next available locations of the current code storage area and then increments that location
by 5. A byte value is an unsigned integer quantity in the range 0 to 255 -- i.e., 8 bits;
while an integer is signed 4-byte fixed-point quantity. This sequence is typically used to
store operation codes along with offsets into long storage areas. Its parameters are:
Parameter | Description
|
byteValue | specifies a value between 0 and 255 to be emitted into the first location.
|
iValue | Specifies a 4-byte fixed-point quantity to be emitted into locations two through
five.
|
The method has no return value.
The method Emit_ByteShort
Prototype
void Emit_ByteShort(int byteValue,int iValue);
The
Emit_ByteShort method emits a byte short integer sequence. If there is sufficient
room, this method enters a sequence of a byte value followed by a short integer value into
the next available locations of the current code storage area and then increments that
location by 3. A byte value is an unsigned integer quantity in the range 0 to 255 -- i.e.
8 bits; while a short integer is signed 2-byte fixed-point quantity. This sequence is
typically used to store operation codes that introduce simple integer constants. Its
parameters are:
Parameter | Description
|
byteValue | specifies a value between 0 and 255 to be emitted into the first location.
|
iValue | Specifies a 2-byte fixed-point quantity to be emitted into locations two and
three.
|
The method has no return value.
The method Emit_ByteValue
Prototype
void Emit_ByteValue(int byteValue);
The
Emit_ByteValue method emits a byte value. If there is sufficient room, this method
enters a single byte value into the next available location of the current code storage area
and then increments that location by 1. A byte value is an unsigned integer quantity in the
range 0 to 255 -- i.e., 8 bits. Its parameter is:
Parameter | Description
|
byteValue | specifies a value between 0 and 255 to be emitted.
|
The method has no return value.
The method Emit_CheckRoom
Prototype
int Emit_CheckRoom(int size);
The
Emit_CheckRoom method checks for emission room. Before an emission method can
store operations along with their associated subcode information in the current emissions
vector it must check that there is sufficient room for that storage. This method performs
this check. Its parameter is as follows:
Parameter | Description
|
size | Specifies the number of bytes of code storage to be used.
|
If there is sufficient room, this method returns a one. If there is not sufficient room, then
this method issues a message "EMROOM: pcnt = %d codeSize = %d size = %d" and exits to the
operating system -- i.e., it does not return at all.
The method Emit_DeleteCode
Prototype
int Emit_DeleteCode(int iStart,int nCode,int nDelete);
The
Emit_DeleteCode method deletes a byte sequence of code stored in the global code
block. As changes are made in byte code by the language processing services it is often
necessary to delete parts of that code that are no longer needed or are being replaced by a
shorter code. This method performs that operation. By necessity this operation requires
moving all bytes down stream from the starting point of the deletion. The lowest level copy
operation available on the platform is used to do this, so the move is relatively fast. No
attempt is made to partition the global code block. Its parameters are:
Parameter | Description
|
iStart | Specifies the byte offset in the global code block of the last byte that must be
retained to achieve the desired deletion. All bytes in the code block from this
point plus the deletion length forward are moved.
|
nCode | Specifies the total length of the code block that is being shortened. It is
typically the global field pcnt -- the current byte code ending offset.
|
nDelete | Specifies the number of bytes that are to be deleted from the code block.
|
This method returns the new total length of the code block, which in this implementation
always equals the previous length minus the deletion length.
The method Emit_DoubleByte
Prototype
void Emit_DoubleByte(int byteValue1,int byteValue2);
The
Emit_DoubleByte method emits a double byte sequence. If there is sufficient room,
this method enters a sequence of two byte values into the next available locations of the
current code storage area and then increments that location by 2. A byte value is an
unsigned integer quantity in the range 0 to 255 -- i.e., 8 bits. Its parameters are:
Parameter | Description
|
byteValue1 | Specifies a value between 0 and 255 to be emitted into the first location.
|
byteValue2 | Specifies a value between 0 and 255 to be emitted into the second location.
|
The method has no return value.
The method Emit_ExchangeCode
Prototype
void Emit_ExchangeCode(int lc1,int lc2);
The
Emit_ExchangeCode method exchanges code emissions. Though the surface patterns
are able to display code emissions in any order, it is sometimes desirable to switch the
order of emissions immediately after they have been completed to simplify further processing.
An example of this is the assignment statement. It is initially compiled with the
left-hand-side emission preceding the right-hand-side emission; however, it is easier to
work with in the analyser if the right-hand-side emission comes first. This method is used to
exchange the order of two code emissions when one follows the other directly. Its parameters
are:
Parameter | Description
|
lc1 | Specifies the byte offset in the code storage block of the first emission in the
emission pair.
|
lc2 | Specifies the byte offset in the code storage block of the second emission in the
emission pair. It is assumed that the first emission ends in the preceding byte.
|
The method has no return value.
The method Emit_ExpandCode
Prototype
int Emit_ExpandCode(int iStart,int nCode,int nExpand);
The
Emit_ExpandCode method expands a byte sequence stored in the global code block.
As changes are made in byte code sequences by the language processing services it is often
necessary to expand those sequences at a certain point so that additional code can be added.
This method performs that operation. By necessity this operation requires moving all bytes
down stream from the starting point of the expansion. The lowest level copy operation
available on the platform is used to do this, so the move is relatively fast. No attempt is
made to partition the global code block. Note that this method does not first check if
sufficient room exists the perform the expansion. Its parameters are:
Parameter | Description
|
iStart | Specifies the byte offset in the code storage vector of the first byte that must be
moved to achieve the desired expansion. All bytes in the code block from this point
forward are moved.
|
nCode | Specifies the total length of the code emission that is being expanded. It is
typically the global variable pcnt -- the current byte code ending offset.
|
nExpand | Specifies the number of bytes that the emission is to be expanded by.
|
The method returns the new total length of the emissions, which in this implementation is
always equals the previous length plus the expansion length.