<> <> <> <> <> DIRECTORY Atom USING [GetProp, PutProp], BcdDefs USING [BcdBase, Link, MTHandle, NullVersion, VersionStamp, ModuleIndex], FS USING [OpenFile], Loader USING [IRItem], LoadState USING [ConfigID], PrincOps USING [ControlLink, ControlModule, NullLink, GlobalFrameHandle], Rope USING [Text], VM USING [Interval]; LoaderOps: DEFINITIONS IMPORTS Atom = BEGIN OPEN BcdDefs, LoadState, PrincOps; <> <<>> FrameList: TYPE = LIST OF FrameListEntry; FrameListEntry: TYPE = RECORD[ SELECT tag: * FROM frame => [ptr: POINTER], mdsInterval => [interval: VM.Interval--pages in mds--] ENDCASE]; CreateGlobalFrames: PROC[cid: ConfigID, allframelinks: BOOL] RETURNS[fl: FrameList _ NIL]; AssignCodeToFrames: PROC [config: ConfigID, bcdCap: FS.OpenFile, pageOffset: INT]; AssignControlModules: PROC[config: ConfigID] RETURNS [cm: PrincOps.ControlModule]; AllocateFrames: PROC[size: CARDINAL, single, resident: BOOL] RETURNS [fl: FrameList, frames: POINTER]; <<... allocates mds VM for "size" words, either from the frame heap or as a VM.Interval, depending on whether single is TRUE or FALSE, respectively. It returns a single-element FrameList and a POINTER to the new block of mds storage.>> ReleaseFrames: PROC[fl: FrameList, cid: ConfigID]; <<... releases the frame(s) and/or mds VM intervals listed in fl, then resets the GFT and loadstate entries as per map to "empty" states>> GetModuleLink: PROC[atom: ATOM] RETURNS[link: ControlLink _ NullLink]; <> <<>> <> IR: TYPE = REF IRRecord; IRRecord: TYPE = RECORD[s: SEQUENCE size: NAT OF PrincOps.ControlLink]; Export: PROC[config: ConfigID]; Bind: PROC[config: ConfigID] RETURNS[unboundImports: LIST OF Loader.IRItem]; GetIR: PROC[ -- either the atom or the version must be non-NIL atom: ATOM _ NIL, version: VersionStamp _ NullVersion, length: CARDINAL _ 0] -- in case a new one must be created RETURNS[name: ATOM, interface: IR, versionStamp: VersionStamp]; GetFrame: PROC[interface: IR, index: CARDINAL] RETURNS[GlobalFrameHandle]; <> IsNullLink: PROC[link: UNSPECIFIED] RETURNS[BOOL] = INLINE { RETURN[ LOOPHOLE[link,CARDINAL]=0 --PrincOps.NullLink OR LOOPHOLE[link,CARDINAL]=1 -- PrincOps.UnboundLink ]; }; OpenLinkSpace: PROC[frame: GlobalFrameHandle, mth: MTHandle, bcd: BcdBase _ NIL]; ReadLink: PROC[offset: CARDINAL] RETURNS [link: ControlLink]; WriteLink: PROC[offset: CARDINAL, link: ControlLink]; CloseLinkSpace: PROC[frame: GlobalFrameHandle]; GetSpace: PROC[nwords: CARDINAL] RETURNS [p: POINTER]; FreeSpace: PROC[p: POINTER]; LinkSegmentLength: PROC[mth: MTHandle, bcd: BcdBase] RETURNS[CARDINAL]; IthLink: PROC[mth: MTHandle, i: CARDINAL, bcd: BcdBase] RETURNS[Link]; <<>> <<>> <> GetPendingList: PRIVATE PROC[interface: ATOM] RETURNS[PendingList] = INLINE {RETURN[NARROW[Atom.GetProp[interface, $pending]]]}; SetPendingList: PRIVATE PROC[interface: ATOM, list: PendingList] = INLINE {Atom.PutProp[interface, $pending, list]}; GetBinding: PROC[bcd: BcdBase] RETURNS[binding: Binding]; -- already filled in FindVariableLink: PROC[config: ConfigID, mx: BcdDefs.ModuleIndex, mthLink: Link] RETURNS [link: PrincOps.ControlLink, frame: PrincOps.GlobalFrameHandle]; pendingModules: PRIVATE LIST OF PendingModule; <<>> <> Binding: TYPE = REF BindingSequence; BindingSequence: TYPE = RECORD[s: SEQUENCE size: NAT OF BindLink]; <<>> <> BindLink: TYPE = RECORD[ whichgfi: BcdDefs.ModuleIndex _ 0, -- if there is more than one gfi for this interface atom: ATOM, -- so we can get and set the pending list interface: IR]; PendingList: TYPE = LIST OF Pending; Pending: TYPE = RECORD[ -- frame, mth, and bcd are parameters to OpenLinkSpace frame: GlobalFrameHandle, mth: MTHandle, bcd: BcdBase, index: CARDINAL, -- index into the links area link: PrincOps.ControlLink]; -- either a) an index into the IR or b) the actual link PendingModule: TYPE = RECORD[ -- frame, mth, and bcd are parameters to OpenLinkSpace frame: PrincOps.GlobalFrameHandle, mth: MTHandle, bcd: BcdBase, index: CARDINAL, -- index into the links area name: Rope.Text, -- name of module we are waiting for version: VersionStamp]; -- version of module we are waiting for END.