-- 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...