Calls.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Sweet, May 27, 1986 5:15:28 pm PDT
Satterthwaite, March 27, 1986 9:31:07 am PST
Maxwell, August 11, 1983 9:02 am
Paul Rovner, November 14, 1983 8:37 am
Russ Atkinson (RRA) March 6, 1985 11:12:07 pm PST
DIRECTORY
Alloc,
Code,
CodeDefs,
ComData,
Counting,
IntCodeDefs,
P5,
P5S,
P5U,
SymbolOps,
Symbols,
Tree,
TreeOps;
Calls: PROGRAM
IMPORTS MPtr: ComData, CPtr: Code, Counting, P5, P5U, SymbolOps
EXPORTS CodeDefs, P5, P5S = BEGIN OPEN CodeDefs;
imported definitions
BitAddress: TYPE = Symbols.BitAddress;
BitCount: TYPE = Symbols.BitCount;
CBTIndex: TYPE = Symbols.CBTIndex;
CBTNull: CBTIndex = Symbols.CBTNull;
ContextLevel: TYPE = Symbols.ContextLevel;
CSEIndex: TYPE = Symbols.CSEIndex;
CTXIndex: TYPE = Symbols.CTXIndex;
ISEIndex: TYPE = Symbols.ISEIndex;
lG: ContextLevel = Symbols.lG;
RecordSEIndex: TYPE = Symbols.RecordSEIndex;
tb: Tree.Base;  -- tree base (local copy)
seb: Symbols.Base;  -- semantic entry base (local copy)
ctxb: Symbols.Base;  -- context entry base (local copy)
bb: Symbols.Base;  -- body entry base (local copy)
cb: CodeDefs.Base;  -- code base (local copy)
CallsNotify: PUBLIC Alloc.Notifier =
BEGIN -- called by allocator whenever table area is repacked
seb ← base[Symbols.seType];
ctxb ← base[Symbols.ctxType];
bb ← base[Symbols.bodyType];
tb ← base[Tree.treeType];
cb ← base[codeType];
END;
SysError: PUBLIC PROC RETURNS [Node] =
BEGIN
RETURN[P5U.ApplyOp[oper: P5U.MesaOpNode[unnamedError], args: NIL]];
END;
SysErrExp: PUBLIC PROC[node: Tree.Index] RETURNS[Node] =
BEGIN
bits: BitCount = P5U.BitsForType[tb[node].info];
RETURN[P5U.ApplyOp[oper: P5U.MesaOpNode[unnamedError], args: NIL, bits: bits]];
END;
Create: PUBLIC PROC[node: Tree.Index] RETURNS[l: ApplyNode] =
BEGIN -- generate code for NEW (of program, not zone allocation)
mod: Node;
IF tb[node].attr1 THEN --NEW of self, set mod to own global frame, otherwise
mod ← P5.Exp[tb[node].son[1]];
l ← P5U.ApplyOp[oper: P5U.MesaOpNode[copyGlobal], args: P5U.MakeNodeList[mod], bits: PtrSize];
IF tb[node].nSons > 2 THEN l.handler ← P5.SCatchPhrase[tb[node].son[3]];
END;
Start, StartExp: PUBLIC PROC[node: Tree.Index] RETURNS[l: ApplyNode] =
BEGIN -- generates code for procedure start statement
psei: CSEIndex = P5U.OperandType[tb[node].son[1]];
gf: Node ← P5.Exp[tb[node].son[1]];
applyToReturnOfAnotherProc: BOOL = tb[node].attr1;
bits: BitCount ← P5U.BitsForType[SymbolOps.TransferTypes[psei].typeOut];
t2: Tree.Link ← tb[node].son[2];
args: NodeList ←
IF applyToReturnOfAnotherProc THEN P5U.MakeNodeList[P5.Exp[t2]]
ELSE P5.ExpList[t2].head;
l ← P5U.ApplyOp[oper: P5U.MesaOpNode[startGlobal], args: P5U.MakeNodeList[gf, args], bits: bits];
IF tb[node].nSons > 2 THEN l.handler ← P5.SCatchPhrase[tb[node].son[3]];
END;
Restart: PUBLIC PROC[node: Tree.Index] RETURNS[l: ApplyNode] =
BEGIN -- generates code for procedure start statement
gf: Node ← P5.Exp[tb[node].son[1]];
l ← P5U.ApplyOp[oper: P5U.MesaOpNode[restartGlobal], args: P5U.MakeNodeList[gf]];
IF tb[node].nSons > 2 THEN l.handler ← P5.SCatchPhrase[tb[node].son[3]];
END;
Stop: PUBLIC PROC[node: Tree.Index] RETURNS[Node] =
BEGIN
IF ~MPtr.stopping THEN SIGNAL CPtr.CodePassInconsistency;
RETURN[P5U.ApplyOp[oper: P5U.MesaOpNode[stopGlobal], args: NIL]];
END;
Call, CallExp: PUBLIC PROC[node: Tree.Index] RETURNS[Node] =
BEGIN -- generates code for procedure call statement
l: ApplyNode;
cl: CodeList ← P5U.NewCodeList[];
psei: CSEIndex = P5U.OperandType[tb[node].son[1]];
proc: Node ← P5.Exp[tb[node].son[1]];
applyToReturnOfAnotherProc: BOOL = tb[node].attr1;
bits: BitCount ← P5U.BitsForType[SymbolOps.TransferTypes[psei].typeOut];
t2: Tree.Link ← tb[node].son[2];
args: NodeList;
t2 ← P5U.ProcessSafens[cl, t2];
args ← IF applyToReturnOfAnotherProc THEN P5U.MakeNodeList[P5.Exp[t2]]
ELSE P5.ExpList[t2].head;
l ← P5U.ApplyOp[oper: proc, args: args, bits: bits];
IF tb[node].nSons > 2 THEN l.handler ← P5.SCatchPhrase[tb[node].son[3]];
RETURN[P5U.MaybeBlock[cl, l]];
END;
SSigErr: PROC[node: Tree.Index, error: BOOL] RETURNS[Node] =
BEGIN -- generates code for procedure signal/error statement
psei: CSEIndex = P5U.OperandType[tb[node].son[1]];
cl: CodeList ← P5U.NewCodeList[];
l: ApplyNode;
sig: Node ← P5.Exp[tb[node].son[1]];
applyToReturnOfAnotherProc: BOOL = tb[node].attr1;
bits: BitCount ← P5U.BitsForType[SymbolOps.TransferTypes[psei].typeOut];
t2: Tree.Link ← tb[node].son[2];
args: NodeList;
t2 ← P5U.ProcessSafens[cl, t2];
args ← IF applyToReturnOfAnotherProc THEN P5U.MakeNodeList[P5.Exp[t2]]
ELSE P5.ExpList[t2].head;
l ← P5U.ApplyOp[oper: P5U.MesaOpNode[IF error THEN error ELSE signal], args: P5U.MakeNodeList[sig, args], bits: bits];
IF tb[node].nSons > 2 THEN l.handler ← P5.SCatchPhrase[tb[node].son[3]];
RETURN[P5U.MaybeBlock[cl, l]];
END;
RetWithError: PUBLIC PROC[node: Tree.Index] RETURNS[Node] =
BEGIN -- generates code for procedure signal/error statement
cl: CodeList ← P5U.NewCodeList[];
l: ApplyNode;
psei: CSEIndex = P5U.OperandType[tb[node].son[1]];
sig: Node ← P5.Exp[tb[node].son[1]];
t2: Tree.Link ← tb[node].son[2];
args: NodeList;
monitored: BOOL ← tb[node].attr1;
IF monitored THEN {
t2← P5U.ProcessSafens[cl: cl, t: t2];
P5.ReleaseLock[cl]};
args ← P5.ExpList[t2].head;
l ← P5U.ApplyOp[oper: P5U.MesaOpNode[error], args: P5U.MakeNodeList[sig, args]];
RETURN[P5U.MaybeBlock[cl, l]];
END;
SigErr: PUBLIC PROC[node: Tree.Index] RETURNS [Node] =
BEGIN
error: BOOL = (tb[node].name = error);
RETURN[SSigErr[node, error]];
END;
SigExp: PUBLIC PROC[node: Tree.Index] RETURNS[Node] =
BEGIN
RETURN[SSigErr[node, FALSE]];
END;
ErrExp: PUBLIC PROC[node: Tree.Index] RETURNS[Node] =
BEGIN
RETURN[SSigErr[node, TRUE]];
END;
Wait: PUBLIC PROC[node: Tree.Index] RETURNS [l: ApplyNode] =
BEGIN
monitor: Node ← P5.Exp[tb[node].son[1]];
condition: Node ← P5.Exp[tb[node].son[2]];
l ← P5U.ApplyOp[oper: P5U.MesaOpNode[wait], args: P5U.MakeNodeList2[monitor, condition]];
IF tb[node].nSons > 2 THEN l.handler ← P5.SCatchPhrase[tb[node].son[3]];
END;
ForkExp: PUBLIC PROC[node: Tree.Index] RETURNS[Node] =
BEGIN
cl: CodeList ← P5U.NewCodeList[];
applyToReturnOfAnotherProc: BOOL = tb[node].attr1;
t2: Tree.Link ← tb[node].son[2];
l: ApplyNode;
args: NodeList;
proc: Node ← P5.Exp[tb[node].son[1]];
t2 ← P5U.ProcessSafens[cl, t2];
args ← IF applyToReturnOfAnotherProc THEN P5U.MakeNodeList[P5.Exp[t2]]
ELSE P5.ExpList[t2].head;
l ← P5U.ApplyOp[oper: P5U.MesaOpNode[fork], args: P5U.MakeNodeList[proc, args], bits: ProcessSize];
IF tb[node].nSons > 2 THEN l.handler ← P5.SCatchPhrase[tb[node].son[3]];
RETURN[P5U.MaybeBlock[cl, l]];
END;
SJoin: PUBLIC PROC[node: Tree.Index] RETURNS[l: ApplyNode] =
BEGIN
ptsei: CSEIndex = P5U.OperandType[tb[node].son[1]];
bits: BitCount = P5U.BitsForType[SymbolOps.TransferTypes[ptsei].typeOut];
process: Node ← P5.Exp[tb[node].son[1]];
l ← P5U.ApplyOp[oper: P5U.MesaOpNode[join], args: P5U.MakeNodeList[process], bits: bits];
IF tb[node].nSons > 2 THEN l.handler ← P5.SCatchPhrase[tb[node].son[3]];
END;
JoinExp: PUBLIC PROC[node: Tree.Index] RETURNS[Node] =
BEGIN
RETURN[SJoin[node]]
END;
Join: PUBLIC PROC[node: Tree.Index] RETURNS [Node] = {RETURN[SJoin[node]]};
Unlock: PUBLIC PROC[node: Tree.Index] RETURNS [l: Node] =
BEGIN
mlock: Tree.Link = tb[node].son[1];
IF mlock # Tree.Null THEN
BEGIN
ln: Node = P5.Exp[mlock];
l ← P5U.ApplyOp[oper: P5U.MesaOpNode[monitorExit], args: P5U.MakeNodeList[ln]];
END;
END;
ProcCheck: PUBLIC PROC[node: Tree.Index] RETURNS[l: ApplyNode] =
BEGIN
proc: Node ← P5.Exp[tb[node].son[1]];
l ← P5U.ApplyOp[oper: P5U.CedarOpNode[procCheck], args: P5U.MakeNodeList[proc], bits: WordSize];
END;
freeOffset: INT = ProcSize;
Free: PUBLIC PROC[node: Tree.Index] RETURNS [l: Node] =
BEGIN
countedVar: BOOL = tb[node].attr1;
counted: BOOL = tb[node].attr3;
zoneLink: Tree.Link = tb[node].son[1];
varLink: Tree.Link = tb[node].son[2];
catchLink: Tree.Link = IF tb[node].nSons > 3 THEN tb[node].son[4] ELSE Tree.Null;
r: Var ← NARROW[P5.Exp[varLink]];
IF counted THEN l ← Counting.Free[r, countedVar, zoneLink, catchLink]
ELSE
BEGIN
cl: CodeList ← P5U.NewCodeList[];
ptrVal: Var ← P5U.MakeTemp[cl: cl, bits: PtrSize, init: r].var;
P5U.DoAssign[cl: cl, lhs: r, rhs: CPtr.nC0];
l ← ZoneOp[zone: zoneLink, procOffset: freeOffset, args: P5U.MakeNodeList[ptrVal], catch: catchLink];
END;
END;
ZoneOp: PUBLIC PROC[
zone: Tree.Link, procOffset: INT, args: NodeList, catch: Tree.Link] RETURNS [Node] =
BEGIN
l: ApplyNode;
z, zup, proc: Node;
z ← P5.Exp[zone];
zup ← P5U.Deref[n: z, bits: PtrSize];
proc ← P5U.TakeField[n: P5U.Deref[n: zup, bits: procOffset+ProcSize], vl: [disp: procOffset, size: ProcSize]];
l ← P5U.ApplyOp[oper: proc, args: P5U.MakeNodeList[z, args]];
IF catch # Tree.Null THEN
l.handler ← P5.SCatchPhrase[catch];
RETURN[l];
END;
END.