-- file Temp.mesa -- last modified by Sweet, November 19, 1979 10:20 PM DIRECTORY AltoDefs: FROM "altodefs" USING [BYTE, wordlength], Code: FROM "code" USING [ bodyComRetLabel, bodyOutRecord, bodyRetLabel, curctxlvl, fileindex, framesz, inlineFileIndex, mainBody, tempcontext, tempstart], CodeDefs: FROM "codedefs" USING [ Lexeme, StackIndex, StatementStateRecord, TempStateRecord], ComData: FROM "comdata" USING [bodyIndex, mainCtx, objectFrameSize], ControlDefs: FROM "controldefs" USING [MaxFrameSize], FOpCodes: FROM "fopcodes" USING [qFREE], Log: FROM "log" USING [ErrorSei], P5: FROM "p5" USING [PushLex], P5U: FROM "p5u" USING [LabelAlloc, Out0], Stack: FROM "stack" USING [Dump, New, Prefix], StringDefs: FROM "stringdefs" USING [WordsForString], SymbolOps: FROM "symbolops" USING [NewCtx, NextSe, SetSeLink], Symbols: FROM "symbols" USING [ BitAddress, bodyType, ContextLevel, CSEIndex, CTXIndex, ctxType, HTIndex, HTNull, ISEIndex, ISENull, lG, lZ, SEIndex, SENull, SERecord, seType, typeANY], Table: FROM "table" USING [Allocate, Base, Notifier], Tree: FROM "tree" USING [treeType]; Temp: PROGRAM IMPORTS MPtr: ComData, CPtr: Code, P5U, Log, P5, Stack, StringDefs, SymbolOps, Table EXPORTS CodeDefs, P5 = BEGIN OPEN CodeDefs; -- imported definitions BYTE: TYPE = AltoDefs.BYTE; wordlength: CARDINAL = AltoDefs.wordlength; BitAddress: TYPE = Symbols.BitAddress; ContextLevel: TYPE = Symbols.ContextLevel; CSEIndex: TYPE = Symbols.CSEIndex; CTXIndex: TYPE = Symbols.CTXIndex; HTIndex: TYPE = Symbols.HTIndex; HTNull: HTIndex = Symbols.HTNull; ISEIndex: TYPE = Symbols.ISEIndex; ISENull: ISEIndex = Symbols.ISENull; lZ: ContextLevel = Symbols.lZ; lG: ContextLevel = Symbols.lG; SEIndex: TYPE = Symbols.SEIndex; SENull: SEIndex = Symbols.SENull; SERecord: TYPE = Symbols.SERecord; typeANY: CSEIndex = Symbols.typeANY; InvalidHeapRelease: SIGNAL = CODE; InvalidTempRelease: SIGNAL = CODE; seb: Table.Base; -- semantic entry base (local copy) ctxb: Table.Base; -- context entry base (local copy) cb: Table.Base; -- code base (local copy) bb: Table.Base; -- body table base (local copy) TempNotify: PUBLIC Table.Notifier = BEGIN -- called by allocator whenever table area is repacked seb ← base[Symbols.seType]; ctxb ← base[Symbols.ctxType]; cb ← base[Tree.treeType]; bb ← base[Symbols.bodyType]; RETURN END; pendTempList, tempListPool, heapList: ISEIndex; TempInit: PUBLIC PROCEDURE = BEGIN -- called at beginning of MODULE to init stack stuff pendTempList ← tempListPool ← heapList ← ISENull; CPtr.tempcontext ← SymbolOps.NewCtx[lZ]; RETURN END; PushTempState: PUBLIC PROCEDURE [p: POINTER TO TempStateRecord, newfs: CARDINAL] = BEGIN p↑ ← TempStateRecord[pendtemplist: pendTempList, templist: ISENull, heaplist: heapList, tempctxlvl: ctxb[CPtr.tempcontext].level, tempstart: CPtr.tempstart, framesz: CPtr.framesz]; pendTempList ← heapList ← ISENull; ctxb[CPtr.tempcontext].level ← CPtr.curctxlvl; CPtr.tempstart ← CPtr.framesz ← newfs; RETURN END; PopTempState: PUBLIC PROCEDURE [p: POINTER TO TempStateRecord] = BEGIN PurgePendTempList[]; [pendtemplist: pendTempList, templist: , heaplist: heapList, tempctxlvl: ctxb[CPtr.tempcontext].level, tempstart: CPtr.tempstart, framesz: CPtr.framesz] ← p↑; RETURN END; PushStatementState: PUBLIC PROCEDURE [p: POINTER TO StatementStateRecord] = BEGIN Stack.Dump[]; p↑ ← [retLabel: CPtr.bodyRetLabel, comRetLabel: CPtr.bodyComRetLabel, outRecord: CPtr.bodyOutRecord, pendtemplist: pendTempList, stkPtr: Stack.New[], inlineFileIndex: CPtr.inlineFileIndex]; CPtr.bodyRetLabel ← P5U.LabelAlloc[]; CPtr.bodyComRetLabel ← P5U.LabelAlloc[]; pendTempList ← ISENull; CPtr.inlineFileIndex ← CPtr.fileindex; RETURN END; PopStatementState: PUBLIC PROCEDURE [p: POINTER TO StatementStateRecord] = BEGIN sp: StackIndex; PurgePendTempList[]; [retLabel: CPtr.bodyRetLabel, comRetLabel: CPtr.bodyComRetLabel, pendtemplist: pendTempList, outRecord: CPtr.bodyOutRecord, stkPtr: sp, inlineFileIndex: CPtr.inlineFileIndex] ← p↑; Stack.Prefix[sp]; RETURN END; GenTempLex: PUBLIC PROCEDURE [nwords: CARDINAL] RETURNS [l: se Lexeme] = BEGIN l ← CreateTempLex[CPtr.tempstart, nwords]; ReleaseTempLex[l]; BumpTemps[nwords]; RETURN END; GenAnonLex: PUBLIC PROCEDURE [nwords: CARDINAL] RETURNS [l: se Lexeme] = BEGIN l ← CreateTempLex[CPtr.tempstart, nwords]; BumpTemps[nwords]; RETURN END; GenStringBodyLex: PUBLIC PROCEDURE [nchars: CARDINAL] RETURNS [l: se Lexeme] = BEGIN nwords: CARDINAL ← StringDefs.WordsForString[nchars]; IF ~CPtr.mainBody THEN RETURN [GenAnonLex[nwords]]; l ← CreateTempLex[MPtr.objectFrameSize, nwords]; seb[l.lexsei].idCtx ← MPtr.mainCtx; MPtr.objectFrameSize ← MPtr.objectFrameSize + nwords; RETURN END; BumpTemps: PROCEDURE [n: CARDINAL] = BEGIN -- updates CPtr.tempstart (and CPtr.framesz, if necessary) CPtr.framesz ← MAX[CPtr.tempstart ← CPtr.tempstart+n, CPtr.framesz]; IF CPtr.framesz > ControlDefs.MaxFrameSize THEN Log.ErrorSei[addressOverflow, bb[MPtr.bodyIndex].id]; RETURN END; PurgePendTempList: PUBLIC PROCEDURE = BEGIN -- after each statment the temp sei's are released sei: ISEIndex ← pendTempList; nsei: ISEIndex; WHILE sei # ISENull DO nsei ← SymbolOps.NextSe[sei]; ReleaseTempSei[sei]; sei ← nsei; ENDLOOP; pendTempList ← ISENull; RETURN END; PurgeHeapList: PUBLIC PROCEDURE[oldheaplist: ISEIndex] = BEGIN -- after each statment the heap chunks are freed sei: ISEIndex ← heapList; nsei: ISEIndex; l: se Lexeme ← Lexeme[se[NULL]]; WHILE sei # ISENull DO nsei ← SymbolOps.NextSe[sei]; l.lexsei ← sei; FreeHeapLex[l]; sei ← nsei; ENDLOOP; heapList ← oldheaplist; RETURN END; FreeHeapLex: PUBLIC PROCEDURE [l: se Lexeme] = BEGIN P5.PushLex[l]; P5U.Out0[FOpCodes.qFREE]; ReleaseTempSei[l.lexsei]; RETURN END; PushHeapList: PUBLIC PROCEDURE RETURNS[oldheaplist: ISEIndex] = BEGIN oldheaplist ← heapList; heapList ← ISENull; RETURN END; GenHeapLex: PUBLIC PROCEDURE RETURNS[l: se Lexeme] = BEGIN l ← GenAnonLex[1]; SymbolOps.SetSeLink[l.lexsei, heapList]; heapList ← l.lexsei; RETURN END; FreeTempSei: PUBLIC PROCEDURE [sei: ISEIndex] = BEGIN -- de-links a temp sei from its chain SymbolOps.SetSeLink[sei, tempListPool]; tempListPool ← sei; RETURN END; ReleaseTempSei: PROCEDURE [sei: ISEIndex] = BEGIN -- puts a temp sei on the templist a: BitAddress ← seb[sei].idValue; CPtr.tempstart ← MIN[CPtr.tempstart, a.wd]; FreeTempSei[sei]; RETURN END; CreateTempLex: PROCEDURE [wdoffset, nwords: INTEGER] RETURNS [l: se Lexeme] = BEGIN -- inits (if nec) a new temp sei cell sei: ISEIndex; a: BitAddress; IF tempListPool # SENull THEN BEGIN sei ← tempListPool; tempListPool ← SymbolOps.NextSe[sei]; seb[sei].idCtx ← CPtr.tempcontext; END ELSE BEGIN sei ← Table.Allocate[Symbols.seType, SIZE[linked id SERecord]]; seb[sei] ← SERecord[mark3: , mark4: , body: id[extended: FALSE, public: , immutable: TRUE, linkSpace: FALSE, constant: FALSE, idCtx: CPtr.tempcontext, hash:HTNull , idType: typeANY, idInfo: , idValue: , ctxLink: linked[LOOPHOLE[0]]]]; END; SymbolOps.SetSeLink[sei, LOOPHOLE[0]]; a ← BitAddress[wd: wdoffset, bd: 0]; seb[sei].idValue ← a; seb[sei].idInfo ← nwords*wordlength; l ← Lexeme[se[lexsei: sei]]; RETURN END; ReleaseTempLex: PUBLIC PROCEDURE [l: se Lexeme] = BEGIN -- releases a cell of temporary storage IF SymbolOps.NextSe[l.lexsei] # LOOPHOLE[0, ISEIndex] THEN RETURN; SymbolOps.SetSeLink[l.lexsei, pendTempList]; pendTempList ← l.lexsei; RETURN END; END...