-- file Temp.mesa -- last modified by Sweet, July 29, 1980 11:10 AM -- last modified by Satterthwaite, November 2, 1982 4:15 pm DIRECTORY Alloc: TYPE USING [Notifier], Code: TYPE USING [ bodyComRetLabel, bodyOutRecord, bodyRetLabel, curctxlvl, fileindex, firstTemp, framesz, inlineFileIndex, mainBody, tempcontext, tempstart], CodeDefs: TYPE USING [ Base, codeType, Lexeme, StackIndex, StatementStateRecord, TempStateRecord], ComData: TYPE USING [bodyIndex, globalFrameSize, mainCtx], FOpCodes: TYPE USING [qFREE], Log: TYPE USING [Error, ErrorSei], P5: TYPE USING [PushLex], P5U: TYPE USING [LabelAlloc, Out0, WordsForString], PrincOps: TYPE USING [MaxFrameSize], Stack: TYPE USING [Dump, New, Prefix], SymbolOps: TYPE USING [MakeCtxSe, NewCtx, NextSe, SetSeLink], Symbols: TYPE USING [ Base, BitAddress, bodyType, CTXNull, ctxType, HTNull, ISEIndex, ISENull, lZ, seType, typeANY, WordLength]; Temp: PROGRAM IMPORTS MPtr: ComData, CPtr: Code, P5U, Log, P5, Stack, SymbolOps EXPORTS CodeDefs, P5 = BEGIN OPEN CodeDefs; -- imported definitions BitAddress: TYPE = Symbols.BitAddress; ISEIndex: TYPE = Symbols.ISEIndex; ISENull: ISEIndex = Symbols.ISENull; WordLength: CARDINAL = Symbols.WordLength; InvalidHeapRelease: SIGNAL = CODE; InvalidTempRelease: SIGNAL = CODE; seb: Symbols.Base; -- semantic entry base (local copy) ctxb: Symbols.Base; -- context entry base (local copy) cb: CodeDefs.Base; -- code base (local copy) bb: Symbols.Base; -- body table base (local copy) TempNotify: PUBLIC Alloc.Notifier = BEGIN -- called by allocator whenever table area is repacked seb _ base[Symbols.seType]; ctxb _ base[Symbols.ctxType]; cb _ base[codeType]; bb _ base[Symbols.bodyType]; END; pendTempList, tempListPool, heapList: ISEIndex; TempInit: PUBLIC PROC = BEGIN -- called at beginning of MODULE to init stack stuff pendTempList _ tempListPool _ heapList _ ISENull; CPtr.tempcontext _ SymbolOps.NewCtx[Symbols.lZ]; END; PushTempState: PUBLIC PROC [p: POINTER TO TempStateRecord, newfs: CARDINAL] = BEGIN p^ _ [pendtemplist: pendTempList, templist: ISENull, heaplist: heapList, tempctxlvl: ctxb[CPtr.tempcontext].level, firstTemp: CPtr.firstTemp, tempstart: CPtr.tempstart, framesz: CPtr.framesz]; pendTempList _ heapList _ ISENull; ctxb[CPtr.tempcontext].level _ CPtr.curctxlvl; CPtr.firstTemp _ CPtr.tempstart _ CPtr.framesz _ newfs; END; PopTempState: PUBLIC PROC [p: POINTER TO TempStateRecord] = BEGIN PurgePendTempList[]; [pendtemplist: pendTempList, templist: , heaplist: heapList, tempctxlvl: ctxb[CPtr.tempcontext].level, tempstart: CPtr.tempstart, firstTemp: CPtr.firstTemp, framesz: CPtr.framesz] _ p^; END; PushStatementState: PUBLIC PROC [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; END; PopStatementState: PUBLIC PROC [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]; END; GenTempLex: PUBLIC PROC [nwords: CARDINAL] RETURNS [l: se Lexeme] = BEGIN l _ CreateTempLex[CPtr.tempstart, nwords]; ReleaseTempLex[l]; BumpTemps[nwords]; RETURN END; GenAnonLex: PUBLIC PROC [nwords: CARDINAL] RETURNS [l: se Lexeme] = BEGIN l _ CreateTempLex[CPtr.tempstart, nwords]; BumpTemps[nwords]; RETURN END; GenStringBodyLex: PUBLIC PROC [nchars: CARDINAL] RETURNS [l: se Lexeme] = BEGIN nwords: CARDINAL = P5U.WordsForString[nchars]; IF ~CPtr.mainBody THEN l _ GenAnonLex[nwords] ELSE BEGIN l _ CreateTempLex[MPtr.globalFrameSize, nwords]; seb[l.lexsei].idCtx _ MPtr.mainCtx; MPtr.globalFrameSize _ MPtr.globalFrameSize + nwords; IF MPtr.globalFrameSize > PrincOps.MaxFrameSize THEN Log.Error[addressOverflow]; END; RETURN END; BumpTemps: PROC [n: CARDINAL] = BEGIN -- updates CPtr.tempstart (and CPtr.framesz, if necessary) CPtr.framesz _ MAX[CPtr.tempstart _ CPtr.tempstart+n, CPtr.framesz]; IF CPtr.framesz > PrincOps.MaxFrameSize THEN Log.ErrorSei[addressOverflow, bb[MPtr.bodyIndex].id]; END; PurgePendTempList: PUBLIC PROC = 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; END; PurgeHeapList: PUBLIC PROC [oldheaplist: ISEIndex] = BEGIN -- after each statment the heap chunks are freed sei: ISEIndex _ heapList; nSei: ISEIndex; l: se Lexeme _ Lexeme[se[TRASH]]; WHILE sei # ISENull DO nSei _ SymbolOps.NextSe[sei]; l.lexsei _ sei; FreeHeapLex[l]; sei _ nSei; ENDLOOP; heapList _ oldheaplist; END; FreeHeapLex: PUBLIC PROC [l: se Lexeme] = BEGIN P5.PushLex[l]; P5U.Out0[FOpCodes.qFREE]; ReleaseTempSei[l.lexsei]; END; PushHeapList: PUBLIC PROC RETURNS [oldheaplist: ISEIndex] = BEGIN oldheaplist _ heapList; heapList _ ISENull; RETURN END; GenHeapLex: PUBLIC PROC RETURNS [l: se Lexeme] = BEGIN l _ GenAnonLex[1]; SymbolOps.SetSeLink[l.lexsei, heapList]; heapList _ l.lexsei; RETURN END; FreeTempSei: PUBLIC PROC [sei: ISEIndex] = BEGIN -- de-links a temp sei from its chain SymbolOps.SetSeLink[sei, tempListPool]; tempListPool _ sei; END; ReleaseTempSei: PROC [sei: ISEIndex] = BEGIN -- puts a temp sei on the templist a: BitAddress = seb[sei].idValue; CPtr.tempstart _ MIN[CPtr.tempstart, a.wd]; FreeTempSei[sei]; END; CreateTempLex: PUBLIC PROC [wdoffset, nwords: INTEGER] RETURNS [se Lexeme] = BEGIN -- inits (if nec) a new temp sei cell sei: ISEIndex; IF tempListPool # ISENull THEN BEGIN sei _ tempListPool; tempListPool _ SymbolOps.NextSe[sei]; seb[sei].idCtx _ CPtr.tempcontext; END ELSE BEGIN sei _ SymbolOps.MakeCtxSe[Symbols.HTNull, Symbols.CTXNull]; seb[sei].constant _ seb[sei].extended _ seb[sei].linkSpace _ FALSE; seb[sei].immutable _ TRUE; seb[sei].idCtx _ CPtr.tempcontext; seb[sei].idType _ Symbols.typeANY; END; SymbolOps.SetSeLink[sei, ISENull]; seb[sei].idValue _ BitAddress[wd: wdoffset, bd: 0]; seb[sei].idInfo _ nwords*WordLength; RETURN [[se[lexsei: sei]]] END; ReleaseTempLex: PUBLIC PROC [l: se Lexeme] = BEGIN -- releases a cell of temporary storage IF SymbolOps.NextSe[l.lexsei] = ISENull THEN BEGIN SymbolOps.SetSeLink[l.lexsei, pendTempList]; pendTempList _ l.lexsei; END; END; END. J:A