-- File: StorageImpl.Mesa Edited by -- Smokey, 26-Jan-81 18:09:03 -- Karlton, Oct 8, 1980 1:37 PM -- Forrest, July 25, 1980 7:06PM DIRECTORY Environment USING [wordsPerPage], Heap USING [ExpandMDS, FreeMDSNode, GetAttributesMDS, MakeMDSNode, PruneMDS, systemMDSZone], Runtime USING [GetCaller], Space USING [ Create, defaultBase, defaultWindow, Delete, GetHandle, Handle, Map, mds, PageFromLongPointer, Pointer], Storage USING []; StorageImpl: PROGRAM IMPORTS Runtime, Space, Heap EXPORTS Storage = BEGIN ownerChecking: BOOLEAN = Heap.GetAttributesMDS[Heap.systemMDSZone].ownerChecking; PageSize: CARDINAL = Environment.wordsPerPage; InvalidNode: PUBLIC ERROR [p: POINTER] = CODE; ZoneTooSmall: PUBLIC ERROR [p: POINTER] = CODE; Pages: PUBLIC PROCEDURE [npages: CARDINAL] RETURNS [base: POINTER] = BEGIN OPEN Space; space: Handle ← Create[npages, mds, defaultBase]; Map[space, defaultWindow]; RETURN[Pointer[space]]; END; Words: PUBLIC PROCEDURE [nwords: CARDINAL] RETURNS [base: POINTER] = {RETURN[Pages[(nwords + PageSize - 1) / PageSize]]}; FreePages, FreeWords: PUBLIC PROCEDURE [base: POINTER] = BEGIN OPEN Space; IF base # NIL THEN Delete[GetHandle[PageFromLongPointer[base]]]; END; -- management of the heap Node: PUBLIC PROCEDURE [nwords: CARDINAL] RETURNS [p: POINTER] = BEGIN p ← Heap.MakeMDSNode[n: nwords]; IF ownerChecking THEN (p-1)↑ ← Runtime.GetCaller[]; RETURN[p] END; Free: PUBLIC PROCEDURE [p: POINTER] = {IF p # NIL THEN Heap.FreeMDSNode[p: p]}; LocalString: PROCEDURE [nchars: CARDINAL] RETURNS [s: STRING] = BEGIN s ← Heap.MakeMDSNode[n: (nchars+1)/2 + 2]; s↑ ← [length: 0, maxlength: nchars, text:]; RETURN END; String: PUBLIC PROCEDURE [nchars: CARDINAL] RETURNS [s: STRING] = BEGIN s ← LocalString[nchars]; IF ownerChecking THEN LOOPHOLE[(s-1), POINTER]↑ ← Runtime.GetCaller[]; RETURN END; CopyString: PUBLIC PROCEDURE [s: LONG STRING, longer: CARDINAL ← 0] RETURNS [newS: STRING] = BEGIN l: CARDINAL = (IF s = NIL THEN 0 ELSE s.length); IF s = NIL AND longer = 0 THEN RETURN[NIL]; newS ← LocalString[l + longer]; FOR i: CARDINAL IN [0..l) DO newS[i] ← s[i] ENDLOOP; newS.length ← l; IF ownerChecking THEN LOOPHOLE[(newS-1), POINTER]↑ ← Runtime.GetCaller[]; END; ExpandString: PUBLIC PROCEDURE [s: POINTER TO STRING, longer: CARDINAL ← 0] = BEGIN newS: STRING ← CopyString[s↑, longer + (IF s↑ = NIL THEN 0 ELSE s.maxlength - s.length)]; FreeString[s↑]; s↑ ← newS; IF ownerChecking THEN LOOPHOLE[(newS-1), POINTER]↑ ← Runtime.GetCaller[]; END; FreeString: PUBLIC PROCEDURE [s: STRING] = LOOPHOLE[Free]; Prune: PUBLIC PROCEDURE RETURNS [BOOLEAN] = { Heap.PruneMDS[Heap.systemMDSZone]; RETURN[TRUE]}; Expand: PUBLIC PROCEDURE [pages: CARDINAL] = {Heap.ExpandMDS[Heap.systemMDSZone, pages]}; -- initialization code END.