DIRECTORY
Alloc: TYPE USING [Notifier],
Basics: TYPE USING [BITAND, BITSHIFT],
BcdDefs: TYPE USING [Link],
Code: TYPE USING [catchcount, curctxlvl, firstTemp, tempcontext],
CodeDefs:
TYPE
USING [
Base, BdoVarIndex, BoVarIndex, BYTE, codeType, DataStackIndex, IndVarIndex,
Lexeme, MoveDirection, OVarIndex, StackBackup, StackIndex, StackLocRec,
TempAddr, VarComponent, VarIndex, VarItem, VarNull, VarTag, wordlength],
LiteralOps: TYPE USING [MasterString, Value],
Literals: TYPE USING [Base, LTNull, MSTIndex, stType],
P5: TYPE USING [CreateTempLex, GenAnonLex, GenTempLex, ReleaseTempLex],
P5L:
TYPE
USING [
AddrComponent, LoadAddress, LoadComponent, LoadVar, MakeBo, MakeComponent,
StoreComponent, VarVarAssign, Words],
P5U: TYPE USING [FreeChunk, GetChunk],
PrincOps: TYPE USING [EPRange, GFTNull],
Stack:
TYPE
USING [
Above, DataIndex, Forget, KeepOnly, Load, Loc, MoveToTemp, Pop,
TempStore, Top],
SymbolOps: TYPE USING [CtxLevel, XferMode],
Symbols:
TYPE
USING [
Base, BitAddress, bodyType, BTNull, CBTIndex, ContextLevel, ctxType,
ISEIndex, ISENull, lG, lZ, RecordSEIndex, seType];
VarUtils:
PROGRAM
IMPORTS Basics, CPtr: Code, LiteralOps, P5, P5U, P5L, Stack, SymbolOps
EXPORTS P5L, CodeDefs =
BEGIN OPEN CodeDefs, Symbols;
CopyToTemp:
PUBLIC
PROC [r: VarIndex, tsei: ISEIndex ← ISENull]
RETURNS [var: VarComponent, sei: ISEIndex] =
BEGIN -- needs work for non aligned things
tsei, if # ISENull, is an available temp of the right size
bd, bSize: [0..wordlength);
wSize, wS: CARDINAL;
rr: VarIndex;
sei ← tsei;
[bd: bd, bSize: bSize, wSize: wSize] ← VarAlignment[r, load];
wS ← P5L.Words[wSize, bSize];
WITH cc: cb[r]
SELECT
FROM
o =>
WITH vv: cc.var
SELECT
FROM
stack =>
IF vv.bd = 0
AND vv.bSize = 0
THEN
BEGIN
junk: CARDINAL ← vv.wd;
originalFirst: StackIndex = vv.sti;
sti: StackIndex ← Stack.Above[vv.sti, junk];
IF sei = ISENull
THEN
-- can store anywhere
BEGIN
var ← Stack.MoveToTemp[firstIndex: sti, count: wS, preChaff: junk];
WITH vv1: var
SELECT
FROM
frame =>
BEGIN
tlex: Lexeme.se;
IF vv1.level # SymbolOps.CtxLevel[CPtr.tempcontext] THEN GO TO move;
tlex ← P5.CreateTempLex[wdoffset: vv1.wd, nwords: wS];
sei ← tlex.lexsei;
IF vv1.wd >= CPtr.firstTemp
THEN
-- not somebody's immutable
P5.ReleaseTempLex[tlex]; -- will be freed after stmt
END;
ENDCASE => GO TO move;
EXITS
move =>
BEGIN
tlex: Lexeme.se = P5.GenTempLex[wS];
sei ← tlex.lexsei;
[] ← P5L.VarVarAssign[
to: VarForLex[tlex], from: OVarItem[var], isexp: FALSE];
var ← ComponentForSE[sei];
END;
END
ELSE
BEGIN
tvar: VarComponent;
var ← ComponentForSE[sei];
FOR i:
CARDINAL
DECREASING
IN [0..wS)
DO
Stack.Load[Stack.Above[sti, i]];
tvar ← var;
FieldOfComponent[var: @tvar, wd: i, wSize: 1];
P5L.StoreComponent[tvar];
ENDLOOP;
IF junk # 0
THEN {
Stack.Load[originalFirst, junk]; -- in case they aren't on top
Stack.Pop[junk]};
END;
ReleaseVarItem[r];
RETURN
END;
ENDCASE;
ENDCASE;
IF sei = ISENull THEN sei ← P5.GenTempLex[wS].lexsei;
var ← ComponentForSE[sei];
IF wS > 1
THEN
BEGIN
var.wSize ← wSize; var.bSize ← bSize;
WITH vv: var
SELECT
FROM
frame => vv.bd ← bd;
ENDCASE;
END;
rr ← OVarItem[var];
[] ← P5L.VarVarAssign[rr, r, FALSE];
RETURN
END;