CountingImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Satterthwaite, April 16, 1986 3:13:20 pm PST
Maxwell, August 2, 1983 8:04 am
Russ Atkinson (RRA) March 6, 1985 11:40:33 pm PST
Sweet May 30, 1986 1:53:32 pm PDT
DIRECTORY
Alloc: TYPE,
CodeDefs: TYPE,
ComData: TYPE,
Counting: TYPE,
FOpCodes: TYPE,
IntCodeDefs: TYPE,
PrincOps: TYPE,
Symbols: TYPE,
SymLiteralOps: TYPE,
Tree: TYPE;
CountingImpl: PROGRAM
IMPORTS MPtr: ComData
EXPORTS Counting, CodeDefs = {
OPEN CodeDefs, Counting, Symbols;
seb: Symbols.Base;  -- se base (local copy)
cb: CodeDefs.Base;  -- code base (local copy)
CountingNotify: PUBLIC Alloc.Notifier = {
called by allocator whenever table area is repacked
seb ← base[seType]; cb ← base[codeType]};
Allocate: PUBLIC PROC[zone: Tree.Link, type: SEIndex, catch: Tree.Link, size: Node] RETURNS [Node ← NIL] = {
Allocate generates code for space allocation from counted zones
first, generate code to perform the allocation
nwords: CARDINAL = P5U.WordsForSei[type];
zoneVar, copyVar: VarIndex;
topVar: VarIndex ← VarNull;
initRC: RefClass = SymbolOps.RCType[SymbolOps.UnderType[type]];
typeTree: Tree.Link ← SymLiteralOps.TypeRef[SymbolOps.TypeRoot[type], FALSE];
Stack.Dump[]; Stack.Mark[];
IF zone = Tree.Null THEN LoadSystemZone[]
ELSE {
zoneVar ← P5L.VarForLex[P5.Exp[zone]];
[first: zoneVar, next: copyVar] ← P5L.ReusableCopies[zoneVar, load, FALSE];
P5L.LoadVar[zoneVar]};
IF pushSize # NIL THEN {
pushSize[]; -- (must save it for later)
P5U.Out0[FOpCodes.qDUP]; sizeVar ← StackTemp[1]}
ELSE P5U.PushLitVal[nwords];
P5.PushRhs[typeTree]; typeTree ← TreeOps.FreeTree[typeTree];
IF zone = Tree.Null THEN LoadSystemZone[]
ELSE {
P5L.LoadVar[copyVar];
IF ~MPtr.switches['a] THEN P5U.Out0[FOpCodes.qNILCKL]};
P5U.Out1[FOpCodes.qRL, 0];
Stack.DeleteToMark[]; Stack.Incr[1]; P5U.Out0[FOpCodes.qSFC];
P5.CallCatch[catch];
Stack.Incr[2];
if size is in a variable and we are RC, then clear the world to NIL
IF initRC # none AND pushSize # NIL THEN {
IF nwords = 0 OR sizeVar = VarNull THEN ERROR;
IF MPtr.switches['m] THEN {
CopyLoad[sizeVar]; P5U.Out0[FOpCodes.qBLZL]}
ELSE {
topVar ← StackTemp[2];
P5U.PushLitVal[0]; CopyLoad[topVar]; P5U.Out1[FOpCodes.qWL, 0];
CopyLoad[topVar];
CopyLoad[sizeVar]; P5U.PushLitVal[1]; P5U.Out0[FOpCodes.qSUB];
DoubleIncr[topVar, 1];
P5U.Out0[FOpCodes.qBLTL];
CopyLoad[topVar]};
};
};
Free: PUBLIC PROC[var: Var, counted: BOOL, zone, catch: Tree.Link] RETURNS [Node ← NIL] = {
emit code for zone.FREE[@ var ! catch]
c0: VarIndex ← P5L.OVarItem[[wSize: 2, space: const[d1:0, d2:0]]];
bor: BoVarIndex ← P5L.MakeBo[var];
r, rr, zoneVar, copyVar: VarIndex;
cb[bor].base ← P5L.EasilyLoadable[cb[bor].base, load];
rr ← P5L.CopyVarItem[bor];
r ← P5L.OVarItem[P5L.CopyToTemp[bor].var];
IF counted THEN [] ← VarVarAssignCounted[rr, c0, [counted: TRUE], MPtr.typeRefANY]
ELSE [] ← P5L.VarVarAssign[rr, c0, FALSE];
Stack.Dump[]; Stack.Mark[];
IF zone = Tree.Null THEN LoadSystemZone[]
ELSE {
zoneVar ← P5L.VarForLex[P5.Exp[zone]];
[first: zoneVar, next: copyVar] ← P5L.ReusableCopies[zoneVar, load, FALSE];
P5L.LoadVar[zoneVar]};
P5L.LoadVar[r]; -- reload the REF
IF zone = Tree.Null THEN LoadSystemZone[]
ELSE {
P5L.LoadVar[copyVar];
IF ~MPtr.switches['a] THEN P5U.Out0[FOpCodes.qNILCKL]};
P5U.Out1[FOpCodes.qRL, 1];
Stack.DeleteToMark[]; Stack.Incr[1]; P5U.Out0[FOpCodes.qSFC];
P5.CallCatch[catch];
};
FillCounted: PUBLIC PROC[space, source: Var, options: StoreOptions, type: Symbols.SEIndex] RETURNS [Node ← NIL] = {
subType: CSEIndex = SymbolOps.UnderType[type];
wordsPerItem: CARDINAL = SymbolOps.WordsForType[subType];
nItems: CARDINAL = P5L.VarAlignment[space, load].wSize/wordsPerItem;
countLex: Lexeme.se = P5.GenTempLex[1];
ptrTemp: VarIndex;
loopLabel: CodeDefs.LabelCCIndex = P5U.LabelAlloc[];
testLabel: LabelCCIndex = P5U.LabelAlloc[];
LoadLongAddress[space]; ptrTemp ← StackTemp[2];
Stack.Dump[];
P5U.PushLitVal[nItems]; Stack.Decr[1];
P5U.OutJump[Jump, testLabel];
P5U.InsertLabel[loopLabel]; -- top of the assignment loop
IF SymbolOps.RCType[subType] = composite THEN {
typeTree: Tree.Link ← SymLiteralOps.TypeRef[subType];
Stack.Mark[];
LoadLongVarAddress[source];
CopyLoad[ptrTemp];
P5.PushRhs[typeTree]; typeTree ← TreeOps.FreeTree[typeTree];
P5U.PushLitVal[wordsPerItem];
P5.SysCall[IF options.init THEN RTSD.sAssignCompositeNew ELSE RTSD.sAssignComposite]}
ELSE {
WCDOp: ARRAY BOOL OF [0..256) = [FALSE: FOpCodes.qWCDL, TRUE: FOpCodes.qICDL];
P5L.LoadVar[source];
CopyLoad[ptrTemp];
P5U.Out1[WCDOp[options.init], 0]};
DoubleIncr[ptrTemp, wordsPerItem]; -- update pointer
P5L.StoreVar[ptrTemp];
P5.PushLex[countLex];
P5U.PushLitVal[1];
P5U.Out0[FOpCodes.qSUB];
P5U.InsertLabel[testLabel];
P5.SAssign[countLex.lexsei];
P5U.Out0[FOpCodes.qPUSH];
P5U.PushLitVal[0];
P5U.OutJump[JumpG, loopLabel];
};
GetSystemZone: PUBLIC PROC RETURNS [Node ← NIL] = {
P5U.PushLitVal[LOOPHOLE[PrincOps.SD, CARDINAL] + RTSD.sSystemZone];
P5U.Out1[FOpCodes.qRD, 0];
};
}.