There are several different forms of On Fault structure available, depending on the actions to be taken by the program and the amount of descriptive information to be returned.
A Fault Marker occupies 1 Stack Cell and has a Tag 4. The PCW for the Procedure which handles the selected Faults occupies 1 Stack Cell and is stored immediately above the Fault Marker. The MCP FaultHandler procedure will accept either the PCW or an SIRW to the PCW.
If the Stack History is requested, an Indexed Copy Descriptor, occupying one Stack Cell, is placed below the Fault Marker.
If the Fault Number is requested, an SIRW to a Single Precision Operand, which occupies one Stack Cell, is placed below the Fault Marker, or below the Stack History Descriptor if present.
An On Fault structure may occupy between 2 and 4 Stack Cells.
In Algol the On Fault is considered to be a Statement, while in Newp it is a Declaration.
Any number of Fault Markers and Fault Handlers can be added into a single activation record, which is what happens when On Statements are used in Algol. They create a series of Fault filters which are checked by FaultHandler as it descends through the Stack.
This is the Layout of a Fault Marker from the MCP at 24602800,
| Tag 4 - Fault Marker | ||
|---|---|---|
| Field | Name | Description |
| [47:27] | FaultBitMaskF | Faults are indexed by Bit[Fault + 20:1]. 1 - ZeroDivide 2 - ExponentOverFlow 3 - ExponentUnderFlow 4 - InvalidIndex 5 - IntegerOverFlow 6 - InactiveQueue 7 - MemoryProtect 8 - InvalidOp 9 - Loop 10 - MemoryParity 11 - ScanParity 12 - InvalidAddress 13 - StackOverFlow 14 - StringProtect 15 - ProgrammedOperator 16 - AssertionFailure 17 - SequenceError 18 - InvalidProgramWord 19 - StackUnderFlow |
| [20:1] | FaultGoToF | 0 = Call (On AnyFault,) 1 = GoTo (On AnyFault:) If set (GoTo) the Fault Procedure PCW is passed to GoToSolver. The PCW is a reference to the code that handles the fault, and then continues executing at the next instruction, and does not perform an EXIT. If not set(Call), the Fault Procedure is entered, and if it returns without doing a Bad GoTo, the FaultHandler searches down the Stack for another Fault Marker Procedure. If no Fault Marker Procedure in the sequence performs a Bad GoTo, the Task is DSED. |
| [19:3] | FaultMarkF | FaultMarkOnStmtV = 1 |
| [16:1] | FaultHistoryF | If set, store stack history |
| [15:1] | FaultNumReqF | If set, store fault number |
| [14:1] | FaultBlockF | If set, these faults are disabled (On AnyFault;) In this case, there is no PCW above the Fault Marker, and this Fault Marker is ignored. |
| [13:1] | FaultIndependentF | If set, do not skip other fault markers. If not set, then FaultHandler will ignore any Fault Marker below this one in the currect activation record, marked by its MSCW. Not set by Algol, otherwise the Disabling On Statement would have no effect. |
| [12:1] | FaultNoParamF | If set, the fault procedure has no parameters. Otherwise, the fault procedure accepts 2 parameters. |
| [15:1] | FaultNumReqF | If set, store fault number |
When a Fault occurs, the MCP FaultHandler procedure searches down the stack looking for Fault Markers which can handle the fault number which occurred.
0048 (02,0032) 7 600884 201CF4 PCW: ASD=00E7A3, LL=2, Segment @ 0003:0044:1, Normal state
0047 (02,0031) 4 000000 321000 On fault marker: Armed faults = 1;
Type = Go-to
0046 (02,0030) 7 E00004 301D16 BLOCK#2 (Procedure) ASD=00E8B7, LL=3,
Segment @ 0007:0000:1, Normal state
0045 (02,002F) 7 600810 301CF4 PCW: ASD=00E7A3, LL=3, Segment @ 0003:0040:4, Normal state
0044 (02,002E) 4 025FFF E38000 On fault marker: Armed faults = 1-16,18 and 21;
Type = Procall [Stackhistory:Faultnum]
0043 (02,002D) D 740000 001CB8 Desc: Present-copy, ASD=00E5C3, EBCDIC, Index=0+0,
Reindexable (Mom @ 003F in this stack)
0042 (02,002C) 1 05D300 16002A SIRW: Offset=0040 (0016+002A) in this stack
0041 (02,002B) 0 FFFFFF FFFFFF TOS (Real) Dec: -7.006492321611341-46
0040 (02,002A) 0 000000 000000 FAULTNUMBER (Integer)
003F (02,0029) C 600000 001CB8 FAULTINFO (Real array) Present-mom, ASD=00E5C3,
Length=256
0(0000) 0 000000 000000 Thru 255(00FF)
The Algol compiler generated the code for these On Statements.
Real Array FaultInfo[0:255];
**003:0024:2 BRUN 003A:0 A2003A
(02,0029) = FAULTINFO
Integer FaultNumber;
(02,002A) = FAULTNUMBER
Real TOS;
(02,002B) = TOS
On AnyFault [FaultInfo:FaultNumber],
0003:003A:5 ZERO B0
0003:003B:0 NAMC (02,0029) 5029
0003:003B:2 INDX A6
0003:003B:3 SE8C 95A1
0003:003B:5 NAMC (02,002A) 502A
0003:003C:1 STFF AF
(02,002C) = FAULT NUMBER
0003:003C:2 NAMC (02,002C) 502C
0003:003C:4 OVRD BA
(02,002D) = FAULT STACK HISTORY
0003:003C:5 NAMC (02,002D) 502D
0003:003D:1 OVRD BA
Begin
0003:003D:2 LT48 BE
0003:003E 025FFFE38000
0003:003F:0 LT8 4 B204
0003:003F:2 STAG 95B4
(02,002E) = FAULT SIW
0003:003F:4 NAMC (02,002E) 502E
0003:0040:0 OVRD BA
(02,002F) = FAULT PCW
0003:0040:1 BRUN-LINK 0000:0 A20000
TOS:=-1;
(02,0030) = BLOCK#2
(01,0007) = SEGMENT DESCRIPTOR
BLOCK#2 IS SEGMENT 0007
0007:0000:0 NVLD FF
0007:0000:1 ONE B1
0007:0000:2 CHSN 8E
0007:0000:3 NAMC (02,002B) 502B
0007:0000:5 STOD B8
End;
0007:0001:0 EXIT A3
********************* STACK BUILDING CODE FOR LEVEL 03 *********************
0007:0001:1 NVLD FF
0007:0001:2 NVLD FF
0007:0001:3 NVLD FF
0007:0001:4 NVLD FF
0007:0001:5 NVLD FF
BLOCK#2(0007)
LENGTH IN WORDS IS 0002
0003:0040:4 MKSN DF
0003:0040:5 NAMC (02,0030) 5030
0003:0041:1 ENTR AB
0003:0041:2 EXIT A3
On ZeroDivide:
TOS:=-2;
0003:0041:3 LT16 51264 B3C840
0003:0042:0 ISOL 41:48 9A2930
0003:0042:3 LT8 4 B204
0003:0042:5 STAG 95B4
(02,0031) = FAULT SIW
0003:0043:1 NAMC (02,0031) 5031
0003:0043:3 OVRD BA
(02,0032) = FAULT PCW
0003:0043:4 BRUN-LINK 0000:0 A20000
0003:0044:1 LT8 2 B202
0003:0044:3 CHSN 8E
0003:0044:4 NAMC (02,002B) 502B
0003:0045:0 STOD B8