VarTemp.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Sweet, July 29, 1980 11:10 AM
Satterthwaite, April 16, 1986 3:53:02 pm PST
Russ Atkinson (RRA) March 6, 1985 11:28:56 pm PST
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;
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 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.