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