<> <> <> <> <> DIRECTORY Alloc USING [Notifier], Code USING [bodyComRetLabel, bodyOutRecord, bodyRetLabel, curctxlvl, fileLoc, firstTemp, framesz, inlineFileLoc, mainBody, tempcontext, tempstart], CodeDefs USING [Base, codeType, FrameStateRecord, Lexeme, StackIndex, StatementStateRecord, TempStateRecord], ComData USING [bodyIndex, globalFrameSize, mainCtx], FOpCodes USING [qFREE], Log USING [Error, ErrorSei], P5 USING [PushLex], P5U USING [LabelAlloc, Out0, WordsForString], PrincOps USING [MaxFrameSize], Stack USING [Dump, New, Prefix], SymbolOps USING [CtxLevel, MakeCtxSe, NewCtx, NextSe, SetCtxLevel, SetSeLink], Symbols USING [Base, BitAddress, bodyType, ContextLevel, CTXNull, ctxType, HTNull, ISEIndex, ISENull, lZ, seType, typeANY, WordLength]; VarTemp: PROGRAM IMPORTS MPtr: ComData, CPtr: Code, P5U, Log, P5, Stack, SymbolOps EXPORTS CodeDefs, P5 = BEGIN OPEN CodeDefs; <> 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 RETURNS [p: TempStateRecord] = BEGIN p.heaplist _ PushHeapList[]; p.pendtemplist _ pendTempList; pendTempList _ ISENull; RETURN END; PopTempState: PUBLIC PROC [p: TempStateRecord] = BEGIN PurgePendTempList[]; PurgeHeapList[p.heaplist]; pendTempList _ p.pendtemplist; END; PushFrameState: PUBLIC PROC [p: POINTER TO FrameStateRecord, newfs: CARDINAL] = BEGIN p^ _ [pendtemplist: pendTempList, heaplist: heapList, tempctxlvl: SymbolOps.CtxLevel[CPtr.tempcontext], firstTemp: CPtr.firstTemp, tempstart: CPtr.tempstart, framesz: CPtr.framesz]; pendTempList _ heapList _ ISENull; SymbolOps.SetCtxLevel[CPtr.tempcontext, CPtr.curctxlvl]; CPtr.firstTemp _ CPtr.tempstart _ CPtr.framesz _ newfs; END; PopFrameState: PUBLIC PROC [p: POINTER TO FrameStateRecord] = BEGIN tctxlvl: Symbols.ContextLevel; PurgePendTempList[]; [pendtemplist: pendTempList, heaplist: heapList, tempctxlvl: tctxlvl, tempstart: CPtr.tempstart, firstTemp: CPtr.firstTemp, framesz: CPtr.framesz] _ p^; SymbolOps.SetCtxLevel[CPtr.tempcontext, tctxlvl]; 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[], inlineFileLoc: CPtr.inlineFileLoc]; CPtr.bodyRetLabel _ P5U.LabelAlloc[]; CPtr.bodyComRetLabel _ P5U.LabelAlloc[]; pendTempList _ ISENull; CPtr.inlineFileLoc _ CPtr.fileLoc; 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, inlineFileLoc: CPtr.inlineFileLoc] _ 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[TRASH]]; 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.qFREE]; 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.