Store.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Sweet, June 2, 1986 10:26:07 am PDT
Satterthwaite, October 10, 1985 2:11:49 pm PDT
Maxwell, August 11, 1983 9:22 am
Russ Atkinson (RRA) March 6, 1985 11:27:57 pm PST
Store:
PROGRAM
IMPORTS CPtr: Code, MPtr: ComData, CodeDefs, P5U, P5, SymbolOps, TreeOps
EXPORTS CodeDefs, P5, P5S = BEGIN OPEN CodeDefs, SymbolOps;
imported definitions
Node: TYPE = IntCodeDefs.Node;
wordlength: CARDINAL = Basics.bitsPerWord;
BitAddress: TYPE = Symbols.BitAddress;
CBTIndex: TYPE = Symbols.CBTIndex;
CTXIndex: TYPE = Symbols.CTXIndex;
ISEIndex: TYPE = Symbols.ISEIndex;
ISENull: ISEIndex = Symbols.ISENull;
lG: Symbols.ContextLevel = Symbols.lG;
RecordSEIndex: TYPE = Symbols.RecordSEIndex;
tb: Tree.Base; -- tree base (local copy)
seb: Symbols.Base; -- semantic entry base (local copy)
bb: Symbols.Base; -- body entry base (local copy)
cb: CodeDefs.Base; -- code base (local copy)
StoreNotify:
PUBLIC Alloc.Notifier =
BEGIN -- called by allocator whenever table area is repacked
seb ← base[Symbols.seType];
bb ← base[Symbols.bodyType];
tb ← base[Tree.treeType];
cb ← base[codeType];
END;
Assign:
PUBLIC
PROC [node: Tree.Index] RETURNS [l: Node] =
BEGIN -- generates code for assignment statement (RRA)
l ← ComAssign[
t1: tb[node].son[1], t2: tb[node].son[2],
options: [expr:
FALSE, init: tb[node].attr1,
counted: tb[node].attr2, composite: tb[node].attr3]];
END;
AssignExp:
PUBLIC
PROC [node: Tree.Index]
RETURNS [l: Node] =
BEGIN -- generates code for assignment expression (RRA)
l ← ComAssign[
t1: tb[node].son[1], t2: tb[node].son[2],
options: [expr:
TRUE, init: tb[node].attr1,
counted: tb[node].attr2, composite: tb[node].attr3]];
RETURN
END;
ComAssign:
PROC [t1, t2: Tree.Link, options: StoreOptions]
RETURNS [l: Node] =
BEGIN -- can support counted assignments (RRA)
nbits: CARDINAL;
aligned: BOOL ← FALSE;
lv: Var;
rv: Node;
nbits ← P5U.BitsForOperand[t1];
DO
-- until we get to something interesting
SELECT TreeOps.OpName[t2]
FROM
pad =>
BEGIN
t2 ← TreeOps.NthSon[t2, 1];
aligned ← TRUE; nbits ← P5U.BitsForOperand[t2];
END;
cast, safen => t2 ← TreeOps.NthSon[t2, 1];
ENDCASE => EXIT;
ENDLOOP;
SELECT TreeOps.OpName[t2]
FROM
construct =>
IF (SimpleLocation[t1]
OR options.counted
OR nbits > 20*WordSize
OR
TreeOps.ListLength[TreeOps.NthSon[t2, 2]] <= 4) AND ~ManySafens[t2, nbits] THEN
BEGIN
l ← P5.Construct[t1, TreeOps.GetNode[t2], options];
RETURN
END
ELSE rv ← P5.Construct[Tree.Null, TreeOps.GetNode[t2], []];
union => {l ← P5.VariantConstruct[t1, t2, options]; RETURN};
rowcons =>
IF options.counted
OR SimpleLocation[t1]
AND ~ManySafens[t2, nbits]
THEN
BEGIN
l ← P5.RowCons[t1, TreeOps.GetNode[t2], options];
RETURN
END
ELSE rv ← P5.RowCons[Tree.Null, TreeOps.GetNode[t2], []];
all =>
BEGIN
l ← P5.All[t1, TreeOps.GetNode[t2], options];
RETURN
END;
ENDCASE => rv ← P5.Exp[t2];
lv ← NARROW[P5.Exp[t1]];
IF aligned THEN lv ← P5U.TakeField[n: lv, vl: [disp: 0, size: nbits]];
l ← z.NEW[NodeRep.assign ← [details: assign[lhs: lv, rhs: rv]]];
END;
ManySafens:
PROC [t: Tree.Link, nbits:
CARDINAL]
RETURNS [
BOOL] =
BEGIN
nFields, nSafens: CARDINAL ← 0;
noAll: BOOL ← TRUE;
CountSafens:
PROC [t: Tree.Link] =
BEGIN
SELECT TreeOps.OpName[t]
FROM
rowcons, construct, union => TreeOps.ScanList[TreeOps.NthSon[t, 2], CountSafens];
all => BEGIN noAll ← FALSE; CountSafens[TreeOps.NthSon[t, 1]] END;
cast, pad => CountSafens[TreeOps.NthSon[t, 1]];
safen => BEGIN nSafens ← nSafens+1; nFields ← nFields+1 END;
ENDCASE => nFields ← nFields+1;
END;
CountSafens[t];
RETURN [
IF nbits<16*wordlength
THEN (nSafens >= 2)
ELSE (noAll AND 2*nSafens > nFields)]
END;
Extract:
PUBLIC
PROC [node: Tree.Index]
RETURNS [l: Node] =
BEGIN
cl: CodeList ← P5U.NewCodeList[];
[] ← ExtractToCl[cl, node];
l ← P5U.MakeBlock[cl];
END;
ExtractToCl:
PUBLIC
PROC [cl: CodeList, node: Tree.Index]
RETURNS [sn: Node] =
BEGIN
t1: Tree.Link = tb[node].son[1];
tsei: RecordSEIndex = LOOPHOLE[P5U.OperandType[t1]];
t2: Tree.Link = tb[node].son[2];
IF SimpleLocation[t2] THEN sn ← P5.Exp[t2]
ELSE {
e2: Node ← P5.Exp[t2];
tv: Var ← P5U.CreateTemp[e2.bits].var;
P5U.Declare[cl: cl, var: tv, init: e2];
sn ← tv};
ExtractFrom[cl, t1, tsei, sn];
END;
ExtractExp:
PUBLIC
PROC [node: Tree.Index]
RETURNS [l: Node] =
BEGIN
cl: CodeList ← P5U.NewCodeList[];
sn: Node = ExtractToCl[cl, node];
P5U.MoreCode[cl, sn];
l ← P5U.MakeBlock[cl];
l.bits ← sn.bits;
END;
ExtractFrom:
PUBLIC
PROC [
cl: CodeList, t1: Tree.Link, tsei: RecordSEIndex, sourceNode: Node] =
BEGIN
saveExtractState:
RECORD [
xtracting:
BOOL, xtractNode: Node, xtractsei: Symbols.ISEIndex] =
[CPtr.xtracting, CPtr.xtractNode, CPtr.xtractsei];
fa:
PROC [ISEIndex]
RETURNS [BitAddress,
CARDINAL] =
IF seb[tsei].argument THEN FnField ELSE RecField;
startsei: ISEIndex = FirstCtxSe[seb[tsei].fieldCtx];
sei: ISEIndex ← startsei;
isei: ISEIndex ← startsei;
node: Tree.Index = TreeOps.GetNode[t1];
soncount: CARDINAL ← 0;
totalBits: CARDINAL;
trashOnStack: CARDINAL ← 0;
SExtract:
PROC [node: Tree.Index] =
BEGIN
t1: Tree.Link = tb[node].son[1];
tsei: RecordSEIndex = LOOPHOLE[P5U.OperandType[t1]];
ExtractFrom[cl, t1, tsei, P5.Exp[tb[node].son[2]]];
END;
ExtractItem:
PROC [t: Tree.Link]
RETURNS [v: Tree.Link] =
BEGIN
posn: BitAddress;
size: CARDINAL;
v ← t;
[posn, size] ← fa[sei];
IF t # Tree.Null
THEN
BEGIN
subNode: Tree.Index = TreeOps.GetNode[t];
vl: VLoc ← [disp: P5U.Bits[posn], size: size];
IF fa # FnField
AND totalBits <= WordSize
THEN
vl ← P5U.AdjustLoc[vl: vl, rSei: tsei, fSei: sei, tBits: totalBits];
CPtr.xtractNode ← P5U.TakeField[n: sourceNode, vl: vl];
CPtr.xtractsei ← sei;
SELECT tb[subNode].name
FROM
assign => P5U.MoreCode[cl, Assign[subNode]];
extract => SExtract[subNode];
ENDCASE => ERROR;
END;
sei ← P5U.PrevVar[startsei, sei];
RETURN
END; -- of ExtractItem
xlist: Tree.Link ← tb[node].son[1];
UNTIL (isei ← NextSe[sei]) = ISENull
DO
isei ← P5U.NextVar[isei];
IF isei = ISENull THEN EXIT;
sei ← isei;
ENDLOOP;
totalBits ← sourceNode.bits;
CPtr.xtracting ← TRUE;
tb[node].son[1] ← TreeOps.ReverseUpdateList[xlist, ExtractItem];
[CPtr.xtracting, CPtr.xtractNode, CPtr.xtractsei] ← saveExtractState;
END;
SimpleLocation:
PROC [t: Tree.Link]
RETURNS [
BOOL] = {
GlobalOrLocal:
PROC [t: Tree.Link]
RETURNS [
BOOL] = {
sei: ISEIndex;
WITH t
SELECT
FROM
symbol => sei ← index;
ENDCASE => RETURN[FALSE];
{ctx: CTXIndex ← seb[sei].idCtx;
level: Symbols.ContextLevel ← SymbolOps.CtxLevel[ctx];
SELECT level
FROM
lG, CPtr.curctxlvl => RETURN[TRUE];
ENDCASE => NULL};
RETURN[FALSE]};
WITH t
SELECT
FROM
symbol => RETURN[GlobalOrLocal[t]];
subtree => {
node: Tree.Index = index;
SELECT tb[node].name
FROM
dot, uparrow => RETURN[GlobalOrLocal[tb[node].son[1]]];
ENDCASE;
};
ENDCASE;
RETURN[FALSE]};
BodyInit:
PUBLIC
PROC [node: Tree.Index]
RETURNS [Node ←
NIL] =
BEGIN -- assigns proc. desc for proc. variable
bti: CBTIndex = tb[node].info;
CPtr.fileLoc ← SourceMap.Up[bb[bti].sourceIndex];
P5.PushLProcDesc[bti];
RETURN [P5L.TOSLex[1]]
END;
ProcInit:
PUBLIC
PROC [node: Tree.Index]
RETURNS [Node ←
NIL] =
BEGIN
bti: CBTIndex = tb[node].info;
WITH body: bb[bti] SELECT FROM
Inner =>
BEGIN
CPtr.tailJumpOK ← FALSE; -- conservative
P5U.Out1[FOpCodes.qDESCB, body.entryIndex];
P5U.Out1[FOpCodes.qSL, body.frameOffset];
END;
ENDCASE;
END;
END.