-- file Temp.mesa -- last modified by Sweet, 9-Oct-81 11:38:06 -- last modified by Satterthwaite, December 16, 1982 10:15 am 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 [qFF], 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: Lexeme.se] = BEGIN l ← CreateTempLex[CPtr.tempstart, nwords]; ReleaseTempLex[l]; BumpTemps[nwords]; RETURN END; GenAnonLex: PUBLIC PROC [nwords: CARDINAL] RETURNS [l: Lexeme.se] = BEGIN l ← CreateTempLex[CPtr.tempstart, nwords]; BumpTemps[nwords]; RETURN END; GenStringBodyLex: PUBLIC PROC [nchars: CARDINAL] RETURNS [l: Lexeme.se] = 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: Lexeme.se ← Lexeme[se[NULL]]; WHILE sei # ISENull DO nSei ← SymbolOps.NextSe[sei]; l.lexsei ← sei; FreeHeapLex[l]; sei ← nSei; ENDLOOP; heapList ← oldheaplist; END; FreeHeapLex: PUBLIC PROC [l: Lexeme.se] = BEGIN P5.PushLex[l]; P5U.Out0[FOpCodes.qFF]; ReleaseTempSei[l.lexsei]; END; PushHeapList: PUBLIC PROC RETURNS [oldheaplist: ISEIndex] = BEGIN oldheaplist ← heapList; heapList ← ISENull; RETURN END; GenHeapLex: PUBLIC PROC RETURNS [l: Lexeme.se] = 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 [Lexeme.se] = 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: Lexeme.se] = 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.