perm filename SAIREC.FAI[S,AIL]2 blob
sn#109743 filedate 1974-07-11 generic text, type T, neo UTF8
COMPIL(REC,<$REC$,FLDKIL,$RERR,$RECGC,$M1FLD,$ENQR>
,<RECQQ,ALLFOR,ARYEL,CORGET,CORREL,X11,GOGTAB,$DEL1B,$GET1B>
,<SAIL RECORD HANDLER>,<$RDREF,$RALLO>);
BEGIN RECORD
RGC <
IFE ALWAYS, <
EXTERNAL RECCHN,RGCLST,RBLIST,RUNNER,SPRPDA,PLISTE,ACF
>;IFE ALWAYS
>;RGC
PDA ← 7 ;DEF USED BY THE GARBAGE COLLECTOR
$RDISP: JRST $RDREF ;DEREFERENCE ARG1
JRST $RALLO ;ALLOCATE RECORD WITH CLASS ARG1
JRST CPOPJ ;2
JRST CPOPJ ;3
JRST $MFLDS ;4 -- MARK ALL FIELDS OF A RECORD
JRST $DIE ;5 DELETE SPACE FOR RECORD
$RMAX ←← (.-$RDISP)-1
HEREFK($REC$,$REC$.)
POP P,C ;RET ADR
POP P,B
POP P,A
EXCH C,(P) ; NOW C=OP, A=ARG1, B=ARG2
CAILE C,$RMAX
POPJ P,
JUMPN C,@$RDISP(C) ; OBEY COMMAND
↑↑$RDREF:
NORGC <
SKIPE A ; HAVE ONE?
SOSLE -1(A) ; YEP, DECREMENT COUNT
POPJ P, ; RETURN
$DIE:
>;NORGC
RGC <
ERR <CALL ON $RDREF IN RECORD GC VERSION>,1
POPJ P,
$DIE: JUMPE A,CPOPJ ;
>;RGC
PUSH P,A ; SO CAN LATER CALL CORREL
HRRZ C,(A) ; CLASS ADDRESS
SUBI C,(A) ; CORRECTION FACTOR
ADDI A,1 ; FIRST DATA ELEMENT
HRLI C,(<POINT =13,(A),=12>); DESCRIPTOR TO GET BITS
PUSH P,C
GETFLD: LDB C,(P) ; GET FIELD
JUMPE C,NOMORE ; NO MORE FIELDS LEFT
DPB C,[POINT =13,A,=12] ; PUT DESCRIPTOR BITS IN PLACE
PUSHJ P,FLDKIL ; GO KILL THIS FIELD
AOJA A,GETFLD ; GO ON TO NEXT
NOMORE: SUB P,X11 ; JUST POP ONE OFF
POP P,B ; THE CORREL POINTER
SUBI B,1 ; NOW IT IS (THE REF CNT WORD, REMEMBER)
MOVE USER,GOGTAB ; FREE THE SPACE UP
MOVE A,$FSLIS(USER) ; BY CALLING THE FREER-UPPER
PUSHJ P,$DEL1B ;
ERR <CONFUSION IN FREEING A BLOCK>,1
POPJ P,
↑↑$RALLO:
LDB C,[POINT =13,(A),=12] ; A = RECORD CLASS ID. GET THE WORD COUNT
ADDI C,2 ; C = NUMBER OF WORDS+1 FOR REFCNT
HRLI A,20 ; INDIREC BIT
PUSH P,A ; EVENTUALLY, BECOMES THE RECID POINTER
MOVE USER,GOGTAB ; GET THE SYSTEM FREE LIST
MOVE A,$FSLIS(USER) ;
PUSHJ P,$GET1B ; MAY WANT MORE EFFICIENCY LATER
ERR <NO CORE FOR RECORD ALLOCATION>,1,ZPOPJ
MOVEI A,1(B) ;THE POINTER WE WILL ACTUALLY RETURN
ADDI C,-1(B) ;STOPPING PLACE
SETZM (B); ;ZERO OUT (ALSO REF CNT ← 0)
HRL B,B ;BUILD BLT PTR
HRRI B,1(B)
BLT B,(C) ;BLT THEM AWAY
NORGC <
AOS -1(A) ;BUMP REF CNT
>;NORGC
RGC <
HLLZ B,RECCHN ;ADD TO SWEEP LIST
HLLZM B,-1(A) ;LIKE SO
HRLM A,RECCHN
>;RCG
POP P,(A) ;THE RECID POINTER
POPJ P, ;RETURN
ZPOPJ: MOVEI A,0
POPJ P,
HEREFK($RERR,$RERR.)
ERR <ACCESS TO A SUBFIELD OF A NULL RECORD>,1
POPJ P,
NORGC <
$MFLDS: ERR <CALL TO $MFLDS IN NON RECORD GC VERSION>,1
POPJ P,
>;NORGC
HEREFK(FLDKIL,.FLDKI)
TLNN A,REFB ; IF REFB ON, THEN NO DELETION REQUIRED
SKIPN @A ; NOTHING TO DO IF A NULL
POPJ P,
TLNE A,ARY2B ;ITEMVAR ARRAY ??
JRST ARYKIL ;YEP
TLNN A,ITEMB ;NOTHING TO DO IF ITEM
TLNE A,PROCB ;OR PROCEDURE
POPJ P,
LDB TEMP,[POINT 6,A,=12] ; SIX BIT TYPE
CAIL TEMP,INVTYP ;VERIFY VALID
ERR <DRYROT -- INVALID REFERENCE TYPE IN FLDKIL>,5,RPOPJ
CAIG TEMP,MXSTYP ;IS THIS A LEGAL ARRAY TYPE ??
JRST @FKDISP(TEMP) ;NOPE DO WHATEVER YOU MUST
MOVEI TEMP,@FKDISP-ARRTYP(TEMP) ;FIND OUT WHAT SORT OF ARRAY YOU HAVE
CAIN TEMP,WZAPR ;A DONOTHING ??
JRST ARYKIL ;YEP
PUSH P,A ;HERE MUST CALL SELF RECURSIVELY TO
MOVEI A,@A ;PROCESS EACH ARRAY ELEMENT
PUSH P,TEMP ;ROUTINE TO CALL
HRRZ TEMP,-1(A) ;COUNT
JUMPE TEMP,NOELS ;NONE
PUSH P,TEMP ;SAVE COUNT
DEL1EL: SKIPE (A) ;HAVE ONE
PUSHJ P,@-1(P) ;CALL THE ROUTINE
SOSG (P) ;DECREMENT THE COUNT
AOJA A,DEL1EL ;DELETE ONE ELEMENT
POP P,TEMP ;GET THIS OFF
NOELS: POP P,TEMP ;GET THIS OFF, TOO.
JRST .+2 ;MAY AS WELL LEAVE A ON THE STACK
ARYKIL: PUSH P,A ;SINCE ARYEL CLOBBERS IT
PUSH P,@A ;CALL TO ARYEL
SETZM @A ;ZAP IT
PUSHJ P,ARYEL ;KILL THE ARRAY
POP P,A ;OH WELL, GET A BACK
POPJ P, ;RETURN FROM KILLING THE ARRAY
FKDISP: WZAPR ;ACTUALLY A NOTHING
WZAPR ;1 UNTYPED
WZAPR ;2 BTRIP
WZAPR ;3 STRING
WZAPR ;4 REAL
WZAPR ;5 INTEGER
WSLKL ;6 SET
WSLKL ;7 LIST
WZAPR ;8 PROCEDURE ITEM
WZAPR ;9 PROCESS ITEM
WZAPR ;10 EVENT TYPE
WCTXTK ;11 CONTEXT
WZAPR ;12 REFITEM
NORGC <
WRDRF ;13 RECORD DEREFERENCING
>;NORGC
RGC <
WZAPR ;13 RECORD DEREFERENCING
>;RGC
WSLKL: SKIPN B,@A ;DO WE HAVE ONE
JRST WZAPR ;NOPE JUST WORRY ABOUT FREES
PUSH P,A ;WHO KNOWS WHAT EVIL LURKS IN THE HEART OF LEAP
SETZM @A ;CLEAR IT OUT
MOVE A,B ;
MOVEI 5,0 ;ALL SET UP
PUSHJ P,RECQQ ;RELEASE THE SET OR LIST
POP P,A ;GET A BACK
JRST WZAPR
WCTXTK: SKIPN B,@A ;HAVE ONE
POPJ P, ;YEP
SETZM @A ;
PUSH P,A ;KILLING A CONTEXT
PUSH P,B
PUSHJ P,ALLFOR ;FORGET IT
POP P,A ;GET BACK A
JRST WZAPR
WRDRF: PUSH P,A ;SAVE
MOVE A,@A ; DO DEREFERENCE
PUSHJ P,$RDREF ;CALL DEREFERENCER
POP P,A ;GET A BACK
WZAPR: TLNN A,TMPB ;CALLING FROM LEAP ???
RPOPJ: POPJ P, ;
ERR <FLDKIL NOT YET READY FOR CALL FOR REFITEMS>,1,RPOPJ
RGC <
HEREFK($ENQR,$ENQR.)
JUMPE A,CPOPJ ;NULL NEVER
HRRZ TEMP,-1(A) ;BE SURE NOT THERE YET
JUMPN TEMP,CPOPJ
HRR TEMP,RECCHN ;LINK ONTO CHAIN
HRRM TEMP,-1(A)
HRRM A,RECCHN
POPJ P,
ENQRB: TLNN C,-1 ;C =-COUNT,,ADR
POPJ P, ;NULL CALL
HRRZ A,(C)
PUSHJ P,$ENQR ;PUT ONE ON QUEUE
AOBJN C,.-2 ;ITERATE
POPJ P,
ENQRBB: MOVE C,(B) ;B →→ A BLOCK OF -CNT,,ADR WORDS
JUMPE C,CPOPJ ;TERMINATED BY A ZERO
PUSHJ P,ENQRB
AOJA B,ENQRBB ;ITERATE
ENQRBL: HRRZ D,RBLIST ;ROUTINE THAT HANDLES RBLIST
EQRB.L: JUMPE D,CPOPJ
HRRZI B,1(D) ;POINT AT THIS BLOCK
PUSHJ P,ENQRBB ;MARK EM ALL
HRRZ D,(D) ;ITERATE
JRST EQRB.L
PAMRK: HLRZ PDA,1(RF) ;HANDLES ONE EACH PROCEDURE ACTIVATION
CAIN PDA,SPRPDA ;CAN QUIT ON THIS
POPJ P,
MOVEI D,-1(RF) ;LAST PARAMETER LOCATION
HRLI D,C
HRRZ C,PD.NPW(PDA) ;NUMBER OF ARITH PARAMS
MOVNI C,(C) ;
HRRZ B,PD.DLW(PDA) ;POINT AT PARAMS
MKPRM: AOJGE C,PRMSDN ;COUNT UP, QUIT WHEN RUN OUT
LDB TEMP,[POINT =12,(B),=12] ;INTERESTED IN VALUE RECORDS
CAIE TEMP,RECTYP ;TEST CODE
AOJA B,MKPRM ;NO, GO MARK NEXT
HRRZ A,@D ;PICK UP PARAMETER
PUSHJ P,$ENQR ;HANDLE IT
AOJA B,MKPRM
PRMSDN: HRRZ B,PD.LLW(PDA) ;POINT AT LVI
LVI.DO: SKIPN D,(B) ;A ZERO MEANS DONE
POPJ P,
LDB TEMP,[POINT 4,D,3]
CAIN TEMP,RPACOD
JRST MRKRPA
CAIE TEMP,RPCOD
AOJA B,LVI.DO
HRRZ A,@D ;GET DESCRIPTOR
PUSHJ P,$ENQR
AOJA B,LVI.DO
MRKRPA: SKIPN C,@D
AOJA B,LVI.DO
MOVN TEMP,-1(C) ;WORD COUNT
HRL C,TEMP
PUSHJ P,ENQRB ;DO THEM ALL
AOJA B,LVI.DO
%PSMRR:
SKIPE TEMP,RUNNER ;FANCY CASE
JRST PSMK.2 ;HERE IF PROCESSES IN USE
PUSH P,RF ;SAVE RF
PUSHJ P,PSMK.1 ;
POP P,RF
POPJ P,
PSMK.1: PUSHJ P,PAMRK ;MARK
HRRZ RF,(RF) ;DYNAMIC LINK
CAIE RF,-1 ;DONE??
JUMPN RF,PSMK.1 ;NO (ALSO TEST DONE ANOTHER WAY)
POPJ P, ;DONE ALL
PSMK.2: MOVEM RF,ACF(TEMP) ;SAVE RF IN TABLE
HRLZI B,-NPRIS
HRR B,GOGTAB
PSCHL: SKIPN TEMP,PRILIS(B)
JRST NXLS
PUSH P,B ;SAVE B
PSCHL2:
PUSH P,TEMP
MOVE RF,ACF(TEMP)
PUSHJ P,PSMK.1 ;MARK THAT STACK
POP P,TEMP
HRRZ TEMP,PLISTE(TEMP)
JUMPN TEMP,PSCHL2
POP P,B
NXLS: AOBJN B,PSCHL
MOVE TEMP,RUNNER
MOVE RF,ACF(TEMP)
POPJ P,
RCIMRK: MOVE USER,GOGTAB
SKIPE HASMSK(USER) ;ACTUALLY HAVE LEAP
SKIPG C,MAXITM(USER) ;ALL THE ITEMS TO MARK
POPJ P, ;NOPE
RI1MK: LDB TEMP,INFOTAB(USER) ;GET TYPE
MOVE A,@DATAB(USER) ;AND DATUM READY
CAIN TEMP,RFITYP ;REFERENCE
JRST RFFOL
CAIN TEMP,ARRTYP+RECTYP ;RECORD ARRAY??
JRST RAIMK ;YES
CAIN TEMP,RECTYP ;REGULAR RECORD
PUSHJ P,$ENQR ;YES
RIMITR: SOJG C,RI1MK ;ITERATE
POPJ P,
RFFOL: PUSH P,C ;SINCE NO PROMISSES WERE MADE
PUSHJ P,$M1FLD ;MARK A FIELD
POP P,C
JRST RIMITR
RAIMK:
SKIPN TEMP,@A ;POINT AT RECORD ARRAY
JRST RIMITR ;EMPTY
PUSH P,C ;SAVE ITEM NUMBER
MOVN C,-1(TEMP)
HRL C,TEMP
MOVS C,C ;-CNT,,ADR
PUSHJ P,ENQRB ;HANDLE EM ALL
JRST RIMITR ;ITERATE
$MRK1R: PUSHJ P,$ENQR ;ENQUEUE ONE RECORD
$MRK.1: HRRZ A,RECCHN ;GET A RECORD OFF THE CHAIN
CAIN A,-1 ;END OF THE ROAD??
POPJ P, ;YES
MOVE D,-1(A) ;CDR THE QUEUE
HRRM D,RECCHN ;NEW NEXT ELT ON QUEUE
MOVEI D,@(A) ;GET HANDLER ADDRESS
CAIN D,$REC$ ;STANDARD HANDLER??
JRST MFLDS1 ;YES
PUSH P,[4] ;THE "MARK" OP
PUSH P,A ;REC ID
PUSH P,[0] ;PLACE HOLDER
PUSHJ P,(D) ;CALL ROUTINE
JRST $MRK.1
MFLDS1: PUSH P,[$MRK.1]
$MFLDS: JUMPE A,CPOPJ ;MARK ALL FIELDS OF RCD IN A
HRRZ C,(A) ;CLASS ID
SUBI C,(A) ;CORRECTION FACTOR
ADDI A,1 ;FIRST DATA FIELD
HRLI C,(<POINT =13,(A),=12>) ;TO GET TYPE BITS
PUSH P,C ;SAVE IT
G1FLD: LDB C,(P) ;GET TYPE
JUMPE C,CPOP1J ;ALL DONE
DPB C,[POINT =13,A,=12] ;DESCRIPTOR FOR ONE FIELD
PUSHJ P,$M1FLD ;MARK ONE FIELD
AOJA A,G1FLD ;ITERATE UNTIL DONE
CPOP1J: SUB P,X11
CPOPJ: POPJ P,
$RGCMK: PUSHJ P,ENQRBL ;DO SOME STANDARD MARK ROUTINES -- OWNS
PUSHJ P,RCIMRK ;ITEMS
PUSHJ P,%PSMRR ;ACTIVE PROCEDURES
PUSH P,RGCLST ;NOW DO ANY SPECIAL ENLISTED ROUTINES
RGCMK1: POP P,A ;GET NEXT ENQUEUEING ROUTINE TO CALL
JUMPE A,$MRK.1 ;NO MORE -- GO PROCESS ALL WE HAVE SEEN
PUSH P,(A) ;SAVE LINK
PUSHJ P,@1(A) ;CALL THIS FELLOW
JRST RGCMK1 ;GO GET SOME MORE
$RGCSW: HLRZ A,RECCHN
MOVEI D,-1 ;NEW RECORD LIST
JUMPE A,RGSWPT ;DONE
RGSWPP: MOVS TEMP,-1(A) ;GET NEXT
TLNN TEMP,-1 ;
JRST RGSWP1 ;UNMARKED MEANS IT DIES
HLLZM D,-1(A) ;LINK ONTO LIVE LIST
HRLO D,A
HRRZ A,TEMP ;POINT AT NEXT
JUMPN A,RGSWPP
RGSWPT: MOVEM D,RECCHN
POPJ P,
RGSWP1: PUSH P,TEMP ;WILL EVENTUALLY BE RECORD WE LOOK AT
MOVEM D,RECCHN ;OUT OF HARMS WAY
HRRZI TEMP,@(A) ;LOOK AT HANDLER ROUTINE
CAIE TEMP,$REC$ ;IS IT STANDARD
JRST RGSWP3 ;NO DO A REGULAR CALL
PUSHJ P,$DIE ;KILL RECORD
RGSWP2: MOVE D,RECCHN
POP P,A
JUMPN A,RGSWPP
JRST RGSWPT
RGSWP3:
PUSH P,[5] ;KILL YOURSELF
PUSH P,A
PUSH P,[0] ;PLACE HOLDER
PUSHJ P,(TEMP)
JRST RGSWP2
HEREFK($RECGC,$RECG.)
HLRZ A,RECCHN ;FIRST VERIFY THAT THE CHAIN IS OK
JUMPE A,CPOPJ ;NO RECORDS AT ALL
RGC.1: MOVE D,A ;FOR REMEMBERING
MOVS A,-1(A) ;CHECK LINK
TLNE A,-1
JRST RGCLER ;LINK GLUBBED UP
JUMPN A,RGC.1 ;GO BACK & CHECK NEXT ONE
RGC.2: HLLOS RECCHN ;INITIALIZE MARK AS NULL
PUSHJ P,$RGCMK ;MARK THEM ALL
JRST $RGCSW ;SWEEP THEM ALL
RGCLER: CAI D,
ERR <GLUBBED UP RECORD LINK FOUND BY RECORD GC>,7
SETZM (D) ;JUST CUT YOUR LOSSES
JRST RGC.2
HEREFK($M1FLD,$M1FL.)
JUMPE A,CPOPJ ;NOTHING TO DO IF NULL
TLNN A,ITEMB ;NOTHING TO DO IF ITEMISH
TLNE A,PROCB ;OR PROCEDURE
POPJ P,
LDB TEMP,[POINT 6,A,=12] ; SIX BIT TYPE
CAIN TEMP,RECTYP ;A RECORD??
JRST M1REC ;YES, ENQUEUE IT
CAIN TEMP,RFITYP ;A REFERENCE ITSELF
JRST M1REF ;YES
CAIE TEMP,RECTYP+ARRTYP; A RECORD ARRAY??
POPJ P, ;NOPE
PUSH P,A ;SINCE AGREED TO LEAVE ALONE
PUSH P,B
SKIPN B,(A) ;PICK UP ARRAY DESCRIPTOR
POPJ P, ;EMPTY
MOVN TEMP,-1(B) ;WORD COUNT
JUMPE TEMP,M1AXIT ;NO WORDS
HRL B,TEMP
M1ALP: MOVE A,(B) ;PICK UP A WORD
PUSHJ P,$ENQR ;ENQUEUE IT
AOBJN B,M1ALP
M1AXIT: POP P,B ;
POP P,A
POPJ P,
M1REC: PUSH P,A ;WE PROMISSED TO LEAVE ALONE
MOVE A,@A ;FETCH VARIABLE
PUSHJ P,$ENQR ;ENQUEUE IT
POP P,A ;RESTORE
POPJ P,
M1REF: PUSH P,A
MOVE A,@A
PUSHJ P,$M1FLD ;MARK THE THING REFERENCED
POP P,A
POPJ P,
>;RGC
BEND RECORD
ENDCOM(REC)