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 = { seb _ base[seType]; cb _ base[codeType]}; Allocate: PUBLIC PROC[zone: Tree.Link, type: SEIndex, catch: Tree.Link, size: Node] RETURNS [Node _ NIL] = { }; Free: PUBLIC PROC[var: Var, counted: BOOL, zone, catch: Tree.Link] RETURNS [Node _ NIL] = { }; FillCounted: PUBLIC PROC[space, source: Var, options: StoreOptions, type: Symbols.SEIndex] RETURNS [Node _ NIL] = { }; GetSystemZone: PUBLIC PROC RETURNS [Node _ NIL] = { }; }. VCountingImpl.mesa Copyright c 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 called by allocator whenever table area is repacked 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]}; }; 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]; 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]; P5U.PushLitVal[LOOPHOLE[PrincOps.SD, CARDINAL] + RTSD.sSystemZone]; P5U.Out1[FOpCodes.qRD, 0]; ΚK˜codešœ™Kšœ Οmœ1™