A Structure Block Type Declaration occupies 2 Stack Cells. A Structure Block Type PCW is pushed onto the Stack followed by a Structure Block Type Descriptor, represented by a special Binding Token until touched.
0019 (02,0003) 5 320000 000002 T_STRUCTUREBLOCK (Structure block type) Untouched, structure block template 0018 (02,0002) 7 400008 301DDB T_STRUCTUREBLOCK.PCW (Structure/Connection block PCW) ASD=00EEDA, LL=3, Segment @ 0003:0000:2, Normal state
A Structure Block Type Declaration is an Activation Record which contains Methods (Procedures and Functions) and Properties (Declarations).
Begin
Type Structure Block T_StructureBlock;
Begin
Integer Property;
PROCEDURE Method;
;
End;
End.
It is created by executing the Stack Building Code referenced by the Structure Block PCW, which creates the Methods and Properties within an Activation Record. The MCP Function STRUCTURE_FREEZER is then called to extract the Activation Record and save it as a Structure Block Type Descriptor, replacing the special Binding Token.
Type Structure Block T_StructureBlock;
(02,0002) = STRUCTURE BLOCK PCW
(02,0003) = T_STRUCTUREBLOCK
Begin
(03,0002) = T_STRUCTUREBLOCK SELF DESCRIPTOR
Integer Property;
(03,0003) = PROPERTY
PROCEDURE Method;
(03,0004) = METHOD
;
End;
************************************** STACK BUILDING CODE FOR LEVEL 03 **********************
0003:0000:2 ZERO B0
0003:0000:3 ZERO B0
(03,0004) = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
0003:0000:4 MPCW BF
0003:0001 0003:0000:1 000200012003
0003:0002:0 PUSH B4
0003:0002:1 ZERO B0
0003:0002:2 BSET 47 962F
0003:0002:4 LT8 6 B206
0003:0003:0 STAG 95B4
(01,0004) = STRUCTURE_FREEZER
0003:0003:2 MKSN DF
0003:0003:3 NAMC (01,0004) 6004 STRUCTURE_FREEZER
0003:0003:5 ONE B1
0003:0004:0 ZERO B0
0003:0004:1 ZERO B0
0003:0004:2 ZERO B0
0003:0004:3 ZERO B0
0003:0004:4 ONE B1
0003:0004:5 LT8 15 B20F
0003:0005:1 ENTR AB
0003:0005:2 EXIT A3
The Structure Block Type Stack Building Code referenced by the PCW is the same code the compiler would emit for a Procedure with the same set of local variables and functions.
The special binding token for the Structure Block Type Descriptor is defined in the MCP at 4217288 as STRUCTDESC and it has this layout.
| Tag 5 - UnTouched DataDesc | ||
|---|---|---|
| Field | Name | Description |
| [45:2] | NewAITF | 1'11' |
| [42:3] | VariF = UntouchedSzF | STRUCT_VARI = 2 |
| [19:20] | Desc_AddrF | Composite of the fields below containing a pseudo Lexical Address of the Structure Block PCW |
| [19:4] | Levels_DownF | This is > 0 when the Structure Block PCW is at a lower Lex Level |
| [15:16] | SIRWDeltaF | Displacement of Structure Block PCW |
When the Structure Block Type Descriptor is touched a TBIT interrupt occurs. The TBIT function calls INITDATAPBIT which notices that the reference is to a Structure Block PCW at 5029150 and calls Architect.
IF PCW_OR_FCW(NEXT_DESC) THEN
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Build the type descriptor and we're done.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
BEGIN
ASD_SPACEUSAGE (ASDNO) := STRUCTUREDAREA;
RETURN_VALUE (ARCHITECT (DESC_REF, COPYSPACE));
END;
The Architect function builds the Structure Block Type Descriptor using the Structure Block PCW referenced by DESC_REF, which is passed as an untyped Procedure parameter called BluePrint at 4987500.
PROCEDURE BLUEPRINT = DESC_REF;
NULL;
Architect contains a ControlState function called Drawing_Board.
Drawing_Board forward declares the procedure called CallBack at Lex Offset 3 (CALLBACK_LEXOFFSET=3), and then declares the variables which make up the Type Descriptor Standard Header. The CallBack procedure is then implemented and and has access to the Standard Header variables.
The CallBack procedure has the same definition as STRUCTURE_FREEZER, because STRUCTURE_FREEZER is just a jacket which reaches down the stack and Calls the CallBack procedure passing the parameters supplied by the Compiler.
The Drawing_Board procedure then calls the BluePrint (the Compiler generated Stack Buliding Code PCW).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Mark the offset in the stack where the TD header starts. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% STKX := ENV_TOP + LEXOFFSET (STD_KIND); NO_KANGAROO_ABOVE_ME (TRUE); BLUEPRINT; NO_KANGAROO_ABOVE_ME (FALSE); END; % DRAWING_BOARD
The BluePrint procedure is entered and has the addressing environment of the Structure Block. The code builds the declared Functions, Procedures and Variables on the Stack, and then calls the Structure_Freezer Entrypoint,(in the MCP at 4695900).
PROCEDURE STRUCTURE_FREEZER (INTERFACE_VERSION,
INCEPTION_OFFSET,
INSTANCE_OFFSET,
SEARCH_OBJECTS,
MSCW_DISP,
SIRW_DISP,
FLAGS);
VALUE INTERFACE_VERSION,
INCEPTION_OFFSET,
INSTANCE_OFFSET,
SEARCH_OBJECTS,
MSCW_DISP,
SIRW_DISP,
FLAGS;
INTEGER INTERFACE_VERSION,
INCEPTION_OFFSET,
INSTANCE_OFFSET,
SEARCH_OBJECTS,
MSCW_DISP,
SIRW_DISP;
REAL FLAGS;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%. Description: %
% Provides the compiler interface for defining a structure type. %
% The parameters give the specifics of the structure that are put %
% into the structure type descriptor which is used to build %
% structure instances. This interface is made available via the %
% intrinsic mechanism, therefore we must transfer the data into %
% the environment creating the structure type by reaching into the %
% environment of the MCP frame that invoked the structure for the %
% CALLBACK routine that will do the actual data transfer into the %
% incipient STD. %
% %
%. Parameters: %
% %
% INTERFACE_VERSION %
% %
% To be incremented with each incompatible change in parameters. %
% The first version is 1. %
% %
% INCEPTION_OFFSET %
% %
% This is the lex offset of the PCW to initialization code. The %
% MCP will call this code to perform compiler built initialization %
% code for the frame. Execution of user specified initialization %
% code (PROLOG) occurs from inside of this code. If this value is %
% zero, then no initialization code is run. %
% %
% INSTANCE_OFFSET %
% %
% This is the lex offset of the cell which is to contain a "self" %
% reference for the THIS intrinsic. The MCP will store a copy %
% descriptor to the structure in this cell before entering compiler %
% built initialization code. If this value is zero, no self %
% reference will be stored. %
% %
% SEARCH_OBJECTS %
% %
% This is the count of the number of structure blocks and structure %
% block arrays that were declared in the structure. This value is %
% used to size the portion of the SB extension holding SIT-like %
% links, and includes neither structure type declarations nor the %
% structure block count of any embedded declaration. %
% %
% MSCW_DISP %
% %
% This is the displacement of the activation MSCW from the base of %
% the memory area. Normally, this would be zero. If the structure %
% is intended to imitate a FIB, a value of one would be used. %
% %
% SIRW_DISP %
% %
% This is the displacement of a cell the compiler has allocated to %
% contain a pseudo-SIRW to the activation. Note that this is a %
% displacement value, not a lex offset. If this value is valid, %
% that is, it is positive and less than the area length, the MCP %
% will generate such a pseudo-SIRW and store it into the word at %
% the word at that displacement from the base of the area. %
% %
% FLAGS %
% %
% Contains additional information from the compiler: %
% %
% NOREFSF = [0:1] %
% When set, no POINTER, ARRAY REFERENCE or STRUCTURE REFERENCE %
% variable declarations occurred in the structure. Note, for %
% UNSAFE NEWP, NOREFSF should never be set. %
% %
% NOEPILOGF = [1:1] %
% When set, no EPILOG procedure declaration occurred in the %
% structure. %
% %
% NOLIBSF = [2:1] %
% When set, no LIBRARY declarations occurred in the structure. %
% The compiler should not set NOLIBSF when CLEF is set, as the %
% MCP considers a Connection Library Environment to be a %
% library. %
% %
% NOSTRSF = [3:1] %
% When set, no structure block variables were declared in the %
% structure. %
% %
% CLEF = [46:1] %
% When set, the structure is to be initialized as a Connection %
% Library Environment. This causes instances of the structure %
% to have their area size adjusted according to Connection %
% Library requirements and BUILDCLE will be called at the %
% inception of each instance. %
% %
%. Assumptions: %
% The compiler has generated a call to this routine from the stack %
% building code of the BLUEPRINT procedure of the structure type. %
% %
% | | %
% | Str. Freezer | The PCW for CALLBACK is located %
% |----------------| inside DRAWING_BOARD. %
% | Stk. Building: | %
% | Blueprint | This exact calling sequence is %
% |----------------| assumed. %
% | Drawing_Board | %
% | of Arhitect | %
% |----------------| %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
The Structure_Freezer entrypoint in the MCP knows the layout of the stack, as shown above, and reaches into the environment of Drawing_Board, and calls the Callback procedure, passing in the parameters provided by the Compiler.
The parameters, described above, are used by CallBack to initialize the Structure Block Type Descriptor, and then Copy it to Memory.
The Structure Block Type Descriptor is used to construct a Structure Block Variable.
So, the Compiler must do these things to create a Structure Block Type Descriptor,
This is an example of generating a Structure Block and it's Type Descriptor and a Structure Block Variable.
% Structure Blocks StructureBlock:=Blocks[Block.AllocateBlock]; StructureBlock.Enter(LexLevel+1); StructureBlock.SinglePrecisionOperand(0); StructureBlock.SingleArray(10,0); StructureBlock.Freeze; // Call Structure_Freezer CodeSegments.Add(StructureBlock.CodeSegment.Me); Block.StructureBlockTypeDescriptor(StructureBlock); Block.StructureBlockVariable(StructureBlock);