-- AMModelContextImpl.mesa -- Last Modified On December 20, 1982 4:07 pm By Paul Rovner -- moduleName, configName should not be source name -- loadstate, UNWIND shoulda oughta use ANY DIRECTORY AMBridge USING [TVForGFHReferent, GFHFromTV, TVToProc, FHFromTV, ContextPC, GetWorld, RemoteGlobalFrameHandle, IsRemote, RemoteGFHFromTV, RemoteFHFromTV, TVToRemoteProc, GetWorldIncarnation, nilRemoteGlobalFrameHandle, TVForRemoteGFHReferent], AMMiniModelPrivate USING [AcquireIRInstanceFromType], AMModel USING [Class, Context, PartialInterfaceInstance], AMModelPrivate USING [FGIndex, FGNull, EPI, PCToFGI, SectionRec, RefTVRec, ConfigContext, ConfigContextObj, StatementContext, StatementContextObj, GetLocalBCD, GetRemoteBCD], AMTypes USING [GlobalParent, Procedure, TVType, Error, TVToName, TypeToName], BBContext USING [FindAction, FindMatchingGlobalFrames], BcdDefs USING [NullVersion, VersionStamp, MTIndex, FTSelf, NameRecord, IMPIndex, EXPIndex, CTIndex, CTNull], BcdOps USING [BcdBase, MTHandle, ProcessModules, NameString, IMPHandle, ProcessImports, EXPHandle, ProcessExports, ProcessConfigs, CTHandle], Convert USING [ValueToRope], ConvertUnsafe USING [ToRope], PilotLoadStateFormat USING [ConfigIndex, NullConfig, ModuleInfo, LoadState, LoadStateObject], PilotLoadStateOps USING [MapRealToConfig, Map, GetMap, ReleaseMap, InputLoadState, ReleaseLoadState, NullConfig, AcquireBcd], PilotLoadStatePrivate USING [InstallLoadState], PrincOps USING [GlobalFrameHandle, ControlLink, GFTIndex, FrameCodeBase, NullGlobalFrame, BytePC], Rope USING [ROPE, Concat, Substr, SkipTo, Index, Length, Match], RTBasic USING [Type, TV], RTSymbols USING [SymbolTableBase, SymbolTableHandle, GetTypeSymbols, AcquireSTB, ReleaseSTB, STBToModuleName, AcquireType, EnumerateCtxIseis, AcquireSTBFromSGI, AcquireSTBFromGFH, SymbolIndex, SymbolIdIndex, SymbolConstructorIndex], RTSymbolsPrivate USING [AcquireBCDFromVersion, ReleaseBCD, GetSTHForModule], RTTypesBasic USING [fhType, gfhType], RTTypesPrivate USING [GFT, UnwindIndirectProcDesc, GetEp], RTTypesRemotePrivate USING [UnwindRemoteIndirectProcDesc, GetRemoteGFHandle, AcquireRemoteBCDAndModule, GetRemoteGFHeader, AcquireRemoteBCD, GetRemoteEp, AcquireSTBFromRemoteGFH, ReleaseRemoteBCD], SafeStorage USING [NewZone], SDDefs USING [sGFTLength, SD], Strings USING [SubStringDescriptor, AppendSubString], Table USING [Base], TimeStamp USING [Stamp], WorldVM USING [LocalWorld, World, WorldName, CurrentIncarnation, Lock, Unlock, Loadstate]; AMModelContextImpl: PROGRAM IMPORTS AMBridge, AMMiniModelPrivate, AMTypes, BBContext, BcdOps, Convert, ConvertUnsafe, PilotLoadStateOps, PilotLoadStatePrivate, Rope, AMModelPrivate, RTSymbols, RTSymbolsPrivate, RTTypesPrivate, RTTypesRemotePrivate, Strings, SafeStorage, WorldVM EXPORTS AMModel, AMModelPrivate = { OPEN AMBridge, AMMiniModelPrivate, AMModel, AMModelPrivate, AMTypes, PilotLoadStateFormat, PrincOps, Rope, RTBasic, RTSymbols, RTTypesBasic, RTTypesPrivate, RTTypesRemotePrivate, WorldVM; -- TYPEs -- either binder output bundle for a config, or compiler output bundle -- for a prog module, DEFs module, proc, or statement Section: TYPE = REF SectionObj; SectionObj: PUBLIC TYPE = SectionRec; z: PUBLIC ZONE _ SafeStorage.NewZone[quantized]; -- PROCs dealing with Contexts (loadstate entries, global or local frames, statements, IR instances) RootContext: PUBLIC PROC[world: World] RETURNS[Context] = -- a "rootContext" represents a Loadstate. -- Immediate children are the Contexts of loadstate configs for -- individually loaded program modules and bound configs. {RETURN[z.NEW[ConfigContextObj _ [world: world, worldIncarnation: CurrentIncarnation[world], configIndex: NullConfig]]]}; ContextClass: PUBLIC PROC[context: Context] RETURNS[Class] = {WITH context SELECT FROM sc: StatementContext => RETURN[statement]; mc: ConfigContext => IF mc.configIndex = NullConfig THEN RETURN[world] ELSE RETURN[model]; tv: RefTVRec => {SELECT TVType[tv] FROM gfhType => RETURN[prog]; fhType => RETURN[proc]; ENDCASE => RETURN[interface]; }; ENDCASE => ERROR AMTypes.Error[reason: notImplemented]; }; ContextWorld: PUBLIC PROC[context: Context] RETURNS[World] = {WITH context SELECT FROM sc: StatementContext => RETURN[GetWorld[sc.localFrameTV]]; cc: ConfigContext => RETURN[cc.world]; ENDCASE => RETURN[GetWorld[context]]; }; -- SectionName with instance info ContextName: PUBLIC PROC[context: Context] RETURNS[ans: ROPE _ NIL] = {WITH context SELECT FROM sc: StatementContext => {ans _ Rope.Concat[Rope.Concat[ContextName[sc.localFrameTV], ":FGT#"], Convert.ValueToRope [[unsigned[NARROW [ContextSection[context], REF statement SectionObj].fgtIndex.fgCard]]] ]}; tv: RefTVRec => {SELECT TVType[tv] FROM gfhType => {gfhBits: CARDINAL = IF GetWorld[tv] # LocalWorld[] THEN LOOPHOLE[RemoteGFHFromTV[tv].gfh, CARDINAL] ELSE LOOPHOLE[GFHFromTV[tv], CARDINAL]; ans _ Rope.Concat[TVToName[tv], Rope.Concat [":gfh#", Convert.ValueToRope [[unsigned[gfhBits]]] ] ]; IF GetWorld[tv] # LocalWorld[] THEN ans _ Rope.Concat[Rope.Concat[ans, ",world:"], WorldName[GetWorld[tv]]]; }; fhType => {fhBits: CARDINAL = IF GetWorld[tv] # LocalWorld[] THEN LOOPHOLE[RemoteFHFromTV[tv].fh, CARDINAL] ELSE LOOPHOLE[FHFromTV[tv], CARDINAL]; ans _ Rope.Concat[TVToName[Procedure[tv]], Rope.Concat [":fh#", Convert.ValueToRope [[unsigned[fhBits]]]] ]; IF GetWorld[tv] # LocalWorld[] THEN ans _ Rope.Concat[Rope.Concat[ans, ",world:"], WorldName[GetWorld[tv]]]; }; ENDCASE => {ans _ TypeToName[TVType[tv]]; ans _ Rope.Concat["Interface:", ans]; IF GetWorld[tv] # LocalWorld[] THEN ans _ Rope.Concat[Rope.Concat[ans, ",world:"], WorldName[GetWorld[tv]]]; }; -- assume an IR }; mc: ConfigContext => IF mc.configIndex = NullConfig THEN ans _ WorldName[mc.world] ELSE {bcd: BcdOps.BcdBase; ctHandle: BcdOps.CTHandle; FindRootConfig: PROC[cth: BcdOps.CTHandle, cti: BcdDefs.CTIndex] RETURNS[stop: BOOL _ FALSE] = {IF cth.config = BcdDefs.CTNull THEN RETURN[TRUE]}; IF mc.world = LocalWorld[] THEN {[] _ PilotLoadStateOps.InputLoadState[]; bcd _ PilotLoadStateOps.AcquireBcd[mc.configIndex]; PilotLoadStateOps.ReleaseLoadState[]; [ctHandle,] _ BcdOps.ProcessConfigs[bcd, FindRootConfig]; ans _ Rope.Concat[BcdNameToRope[bcd, ctHandle.name], Rope.Concat [":ConfigIndex#", Convert.ValueToRope [[signed[mc.configIndex]]] ]]} ELSE { Lock[mc.world]; { ENABLE UNWIND => Unlock[mc.world]; oldState: PilotLoadStateFormat.LoadState; newState: REF PilotLoadStateFormat.LoadStateObject; loadstateHeld: BOOL _ FALSE; newState _ Loadstate[mc.world]; [] _ PilotLoadStateOps.InputLoadState[]; loadstateHeld _ TRUE; oldState _ PilotLoadStatePrivate.InstallLoadState [LOOPHOLE[newState]]; -- no error raised bcd _ AcquireRemoteBCD [mc.world, PilotLoadStateOps.AcquireBcd[mc.configIndex] ! ANY => {[] _ PilotLoadStatePrivate.InstallLoadState [oldState]; PilotLoadStateOps.ReleaseLoadState[]; loadstateHeld _ FALSE}]; IF loadstateHeld THEN {[] _ PilotLoadStatePrivate.InstallLoadState[oldState]; PilotLoadStateOps.ReleaseLoadState[]; loadstateHeld _ FALSE}; IF bcd = NIL THEN ERROR; { ENABLE UNWIND => ReleaseRemoteBCD[bcd]; [ctHandle,] _ BcdOps.ProcessConfigs[bcd, FindRootConfig]; ans _ BcdNameToRope[bcd, ctHandle.name]; }; -- end ENABLE UNWIND => ... FREE ... ReleaseRemoteBCD[bcd]; ans _ Rope.Concat[ans, Rope.Concat [":ConfigIndex#", Convert.ValueToRope [[signed[mc.configIndex]]] ]]; ans _ Rope.Concat[Rope.Concat[ans, ",world:"], WorldName[mc.world]]; }; -- end ENABLE UNWIND => Unlock[mc.world]; Unlock[mc.world]; }; -- end ELSE arm (remote world) }; -- end ELSE arm (mc.configIndex # NullConfig) ENDCASE => ERROR AMTypes.Error[reason: notImplemented]; }; -- end ContextName -- EXAMPLE USAGE: given a module name and a world context, this returns -- a Context for the most recently loaded global frame for a program with that name. -- name must identify -- a model or prog (someday interface) if context identifies a world, or -- a prog (someday interface) if context identifies a model. -- The format of the name should be the same as that produced by ContextName, -- with elided fields meaning "don't care". -- The result will be either a model or prog (someday interface) context. MostRecentNamedContext: PUBLIC PROC[name: ROPE, context: --world or model-- Context] RETURNS[ans: Context _ NIL] = {WITH context SELECT FROM mc: ConfigContext => {IF mc.configIndex = NullConfig -- the model of a world THEN {p: BBContext.FindAction --PROC[gf: TV, name: ROPE] RETURNS[ActionContinuation _ continue]-- = TRUSTED {ans _ gf; RETURN[quit]}; BBContext.FindMatchingGlobalFrames [world: ContextWorld[context], pattern: name, action: p]; IF ans # NIL THEN RETURN}; -- here to look for a named config or a module of a config { p: PROC[c: Context] RETURNS[stop: BOOL _ FALSE] = { n: ROPE = ContextName[c]; len: INT _ Rope.Index[s1: n, s2: ":"]; nPart: ROPE _ IF len = Rope.Length[n] THEN n ELSE Rope.Substr[base: n, len: len]; IF name.Match[nPart, FALSE] --Rope.Equal[name, nPart] THEN {ans _ c; stop _ TRUE}; }; [] _ ContextChildren[context, p]; }; }; ENDCASE => ERROR AMTypes.Error [reason: notImplemented, msg: "MostRecentNamedContext for other than a world or model Context"]; }; -- an enumerator. -- Like MostRecentNamedContext, but gets 'em all. NamedContexts: PUBLIC PROC[name: ROPE, context: --worldRoot or model--Context, proc: PROC[Context] RETURNS[stop: BOOL]] RETURNS[ans: Context _ NIL--NIL if not stopped--] = { lookForNamedContext: PROC[c: Context] RETURNS[stop: BOOL _ FALSE] = {n: ROPE = ContextName[c]; len: INT _ Rope.Index[s1: n, s2: ":"]; nPart: ROPE _ IF len = Rope.Length[n] THEN n ELSE Rope.Substr[base: n, len: len]; IF name.Match[nPart, FALSE] --Rope.Equal[name, nPart] THEN {stop _ proc[c]; IF stop THEN ans _ c} ELSE SELECT ContextClass[c] FROM model => {ans _ NamedContexts[name, c, proc]; IF ans # NIL THEN stop _ TRUE}; ENDCASE; }; -- start HERE [] _ ContextChildren[context, lookForNamedContext]; }; --param to creator of context ContextSection: PUBLIC PROC[context: Context] RETURNS[ans: Section _ NIL] = { WITH context SELECT FROM sc: StatementContext => {parentContext: Context _ ParentContext[context]; UNTIL ContextClass[parentContext] = prog DO parentContext _ ParentContext[parentContext]; ENDLOOP; RETURN[z.NEW[SectionObj _ [statement[prog: NARROW [ContextSection [parentContext], REF prog SectionObj], fgtIndex: StatementContextToFGI [sc]] ]]]}; tv: RefTVRec => {SELECT TVType[tv] FROM gfhType => -- program module RETURN [z.NEW [SectionObj _ [prog [moduleName: TVToName[tv], versionStamp: IF IsRemote[tv] THEN RemoteGFHToVersionStamp [RemoteGFHFromTV[tv]] ELSE GFHToVersionStamp[GFHFromTV[tv]], someGFHTV: tv]]]]; fhType => {procTV: RefTVRec = NARROW[Procedure[tv]]; -- procedure RETURN [z.NEW [SectionObj _ [proc[prog: NARROW[ContextSection[GlobalParent[tv]]], entryPointIndex: IF IsRemote[procTV] THEN LOOPHOLE [UnwindRemoteIndirectProcDesc [TVToRemoteProc[procTV]].pd, PrincOps.ControlLink ].ep ELSE UnwindIndirectProcDesc [LOOPHOLE[TVToProc[procTV], PrincOps.ControlLink] ].ep, procTV: procTV]]]]}; ENDCASE => -- better be a TV for an interface record {type: Type = TVType[tv]; stb: SymbolTableBase; sei: SymbolIndex; mn: ROPE; vs: BcdDefs.VersionStamp; [stb, sei] _ GetTypeSymbols[type]; {ENABLE UNWIND => ReleaseSTB[stb]; csei: SymbolConstructorIndex = stb.UnderType[sei]; WITH ser: stb.seb[csei] SELECT FROM definition => NULL; ENDCASE => ERROR; mn _ RTSymbols.STBToModuleName[stb]; vs _ stb.stHandle.version; ReleaseSTB[stb]}; RETURN[z.NEW[SectionObj _ [interface[moduleName: mn, versionStamp: vs]]]]}; }; mc: ConfigContext => IF mc.world = LocalWorld[] THEN { bcd: BcdOps.BcdBase; IF mc.configIndex = NullConfig THEN RETURN[NIL]; [] _ PilotLoadStateOps.InputLoadState[]; bcd _ PilotLoadStateOps.AcquireBcd[mc.configIndex]; PilotLoadStateOps.ReleaseLoadState[]; IF bcd = NIL THEN ERROR; ans _ z.NEW[SectionObj _ [model[configName: StripExtension [BcdNameToRope [bcd, bcd.source]], versionStamp: bcd.version, configContext: mc]]]; } ELSE { IF mc.configIndex = NullConfig THEN RETURN[NIL]; Lock[mc.world]; { ENABLE UNWIND => Unlock[mc.world]; oldState: PilotLoadStateFormat.LoadState; newState: REF PilotLoadStateFormat.LoadStateObject; bcd: BcdOps.BcdBase; loadstateHeld: BOOL _ FALSE; newState _ Loadstate[mc.world]; [] _ PilotLoadStateOps.InputLoadState[]; loadstateHeld _ TRUE; oldState _ PilotLoadStatePrivate.InstallLoadState[LOOPHOLE[newState]]; -- no error raised bcd _ AcquireRemoteBCD[mc.world, PilotLoadStateOps.AcquireBcd[mc.configIndex] ! ANY => {[] _ PilotLoadStatePrivate.InstallLoadState[oldState]; PilotLoadStateOps.ReleaseLoadState[]; loadstateHeld _ FALSE}]; IF loadstateHeld THEN {[] _ PilotLoadStatePrivate.InstallLoadState[oldState]; PilotLoadStateOps.ReleaseLoadState[]; loadstateHeld _ FALSE}; IF bcd = NIL THEN ERROR; { ENABLE UNWIND => ReleaseRemoteBCD[bcd]; ans _ z.NEW[SectionObj _ [model[configName: StripExtension [BcdNameToRope [bcd, bcd.source]], versionStamp: bcd.version, configContext: mc]]]; }; -- end ENABLE UNWIND => ... FREE ... ReleaseRemoteBCD[bcd]; }; -- end ENABLE UNWIND => Unlock[mc.world]; Unlock[mc.world]; }; ENDCASE => ERROR AMTypes.Error[reason: notImplemented]; }; -- end ContextSection -- world => NIL -- model => world -- prog => model -- proc => prog -- statement => proc ParentContext: PUBLIC PROC[context: Context] RETURNS[Context] = { WITH context SELECT FROM sc: StatementContext => RETURN[sc.localFrameTV]; mc: ConfigContext => IF mc.configIndex = NullConfig THEN RETURN[NIL] ELSE RETURN -- the loadsatate has only one level of structure [z.NEW[ConfigContextObj _ [world: mc.world, worldIncarnation: mc.worldIncarnation, configIndex: NullConfig]]]; tv: RefTVRec => {SELECT TVType[tv] FROM gfhType => IF NOT IsRemote[tv] THEN {ci: ConfigIndex; gfi: PrincOps.GFTIndex; [] _ PilotLoadStateOps.InputLoadState[]; gfi _ GFHFromTV[tv].gfi; ci _ PilotLoadStateOps.MapRealToConfig[gfi].config; PilotLoadStateOps.ReleaseLoadState[]; RETURN[z.NEW[ConfigContextObj _ [world: LocalWorld[], worldIncarnation: GetWorldIncarnation[tv], configIndex: ci]]]} ELSE -- remote case {ci: ConfigIndex; world: World = GetWorld[tv]; Lock[world]; { ENABLE UNWIND => Unlock[world]; oldState: PilotLoadStateFormat.LoadState; newState: REF PilotLoadStateFormat.LoadStateObject; gfi: PrincOps.GFTIndex; loadstateHeld: BOOL _ FALSE; newState _ Loadstate[world]; [] _ PilotLoadStateOps.InputLoadState[]; loadstateHeld _ TRUE; oldState _ PilotLoadStatePrivate.InstallLoadState[LOOPHOLE[newState]]; -- no error raised { ENABLE ANY => {[] _ PilotLoadStatePrivate.InstallLoadState[oldState]; PilotLoadStateOps.ReleaseLoadState[]; loadstateHeld _ FALSE}; gfh: RemoteGlobalFrameHandle = RemoteGFHFromTV[tv]; IF NOT loadstateHeld THEN ERROR; gfi _ GetRemoteGFHeader[gfh].gfi; }; IF NOT loadstateHeld THEN ERROR; ci _ PilotLoadStateOps.MapRealToConfig[gfi].config; [] _ PilotLoadStatePrivate.InstallLoadState[oldState]; PilotLoadStateOps.ReleaseLoadState[]; }; -- end ENABLE UNWIND => Unlock[world]; Unlock[world]; RETURN[z.NEW[ConfigContextObj _ [world: world, worldIncarnation: GetWorldIncarnation[tv], configIndex: ci]]]}; fhType => RETURN[GlobalParent[tv]]; ENDCASE => ERROR AMTypes.Error[reason: typeFault, type: TVType[tv]];}; ENDCASE => ERROR AMTypes.Error[reason: notImplemented]; }; -- end ParentContext -- world -> model or prog (TV for a global frame) -- model -> prog -- proc -> statement ContextChildren: PUBLIC PROC[context: Context, proc: PROC[Context] RETURNS[stop: BOOL]] RETURNS[ans: Context _ NIL--NIL if not stopped--] = {FOR c: Context _ FirstChildContext[context], NextSiblingContext[c] UNTIL c = NIL DO IF proc[c] THEN RETURN[c]; ENDLOOP; }; FirstChildContext: PROC[context: Context] RETURNS[ans: Context] = { WITH context SELECT FROM sc: StatementContext => RETURN[NIL]; -- do statements have substructure? tv: RefTVRec => SELECT TVType[tv] FROM fhType => RETURN[z.NEW[StatementContextObj _ [localFrameTV: tv]]]; gfhType => RETURN[NIL]; ENDCASE => ERROR AMTypes.Error[reason: typeFault, type: TVType[tv]]; mc: ConfigContext => IF mc.configIndex = NullConfig THEN {IF mc.world = LocalWorld[] THEN { nbcds: PilotLoadStateFormat.ConfigIndex _ PilotLoadStateOps.InputLoadState[]; bcd: BcdOps.BcdBase _ PilotLoadStateOps.AcquireBcd[nbcds-1]; composite: BOOL _ IsComposite[bcd]; IF composite THEN {PilotLoadStateOps.ReleaseLoadState[]; RETURN[z.NEW[ConfigContextObj _ [world: mc.world, worldIncarnation: mc.worldIncarnation, configIndex: nbcds-1]]]} ELSE {map: PilotLoadStateOps.Map = PilotLoadStateOps.GetMap[nbcds-1]; gfh: GlobalFrameHandle _ NIL; FOR j: GFTIndex IN [1 .. LENGTH[map]) DO IF map[j] # 0 THEN {gfh _ GFT[map[j]].frame; EXIT}; ENDLOOP; IF gfh = NIL THEN {PilotLoadStateOps.ReleaseMap[map]; PilotLoadStateOps.ReleaseLoadState[]; ERROR}; PilotLoadStateOps.ReleaseMap[map]; PilotLoadStateOps.ReleaseLoadState[]; RETURN[TVForGFHReferent[gfh]]}; } ELSE -- remote world {nbcds: ConfigIndex; Lock[mc.world]; { ENABLE UNWIND => Unlock[mc.world]; oldState: PilotLoadStateFormat.LoadState; newState: REF PilotLoadStateFormat.LoadStateObject; loadstateHeld: BOOL _ FALSE; newState _ Loadstate[mc.world]; [] _ PilotLoadStateOps.InputLoadState[]; loadstateHeld _ TRUE; oldState _ PilotLoadStatePrivate.InstallLoadState[LOOPHOLE[newState]]; nbcds _ newState.nBcds; -- no error raised { ENABLE ANY => IF loadstateHeld THEN {[] _ PilotLoadStatePrivate.InstallLoadState[oldState]; PilotLoadStateOps.ReleaseLoadState[]; loadstateHeld _ FALSE}; {bcd: BcdOps.BcdBase _ AcquireRemoteBCD[mc.world, PilotLoadStateOps.AcquireBcd[nbcds-1]]; { ENABLE UNWIND => ReleaseRemoteBCD[bcd]; IF NOT IsComposite[bcd] -- single module loadstate entry THEN {gfh: RemoteGlobalFrameHandle _ nilRemoteGlobalFrameHandle; map: PilotLoadStateOps.Map; IF NOT loadstateHeld THEN ERROR; map _ PilotLoadStateOps.GetMap[nbcds-1]; { ENABLE UNWIND => PilotLoadStateOps.ReleaseMap[map]; FOR j: GFTIndex IN [1.. LENGTH[map]) DO IF map[j] # 0 THEN {gfh _ GetRemoteGFHandle[mc.world, map[j]]; EXIT}; ENDLOOP; IF gfh = nilRemoteGlobalFrameHandle THEN ERROR; --UNWIND releases the map, bcd, loadstate, and the world lock }; -- end ENABLE UNWIND for releasing the map PilotLoadStateOps.ReleaseMap[map]; ans _ TVForRemoteGFHReferent[gfh]} ELSE ans _ z.NEW[ConfigContextObj _ [world: mc.world, worldIncarnation: mc.worldIncarnation, configIndex: nbcds-1]]; }; -- end ENABLE UNWIND => ... FREE ... ReleaseRemoteBCD[bcd]; }; }; -- end ENABLE UNWIND => ReleaseLoadState IF loadstateHeld THEN {[] _ PilotLoadStatePrivate.InstallLoadState[oldState]; PilotLoadStateOps.ReleaseLoadState[]; loadstateHeld _ FALSE}; }; -- end ENABLE UNWIND => Unlock[mc.world]; Unlock[mc.world]; RETURN}; } -- end world config case ELSE {IF mc.world = LocalWorld[] THEN { map: PilotLoadStateOps.Map; gfh: GlobalFrameHandle; [] _ PilotLoadStateOps.InputLoadState[]; map _ PilotLoadStateOps.GetMap[mc.configIndex]; gfh _ NIL; FOR i: GFTIndex DECREASING IN [1.. LENGTH[map]) DO IF map[i] # 0 THEN {gfh _ GFT[map[i]].frame; EXIT}; ENDLOOP; PilotLoadStateOps.ReleaseMap[map]; PilotLoadStateOps.ReleaseLoadState[]; IF gfh = NIL THEN RETURN[NIL]; RETURN[TVForGFHReferent[gfh]]} ELSE {gfh: RemoteGlobalFrameHandle _ nilRemoteGlobalFrameHandle; Lock[mc.world]; { ENABLE UNWIND => Unlock[mc.world]; oldState: PilotLoadStateFormat.LoadState; newState: REF PilotLoadStateFormat.LoadStateObject; map: PilotLoadStateOps.Map; loadstateHeld: BOOL _ FALSE; newState _ Loadstate[mc.world]; [] _ PilotLoadStateOps.InputLoadState[]; loadstateHeld _ TRUE; oldState _ PilotLoadStatePrivate.InstallLoadState[LOOPHOLE[newState]]; -- no error raised map _ PilotLoadStateOps.GetMap[mc.configIndex]; { ENABLE ANY => {PilotLoadStateOps.ReleaseMap[map]; [] _ PilotLoadStatePrivate.InstallLoadState[oldState]; PilotLoadStateOps.ReleaseLoadState[]; loadstateHeld _ FALSE}; FOR i: GFTIndex DECREASING IN [1 .. LENGTH[map]) DO IF map[i] # 0 THEN {gfh _ GetRemoteGFHandle[mc.world, map[i]]; EXIT}; ENDLOOP; }; -- end ENABLE UNWIND PilotLoadStateOps.ReleaseMap[map]; IF loadstateHeld THEN {[] _ PilotLoadStatePrivate.InstallLoadState[oldState]; PilotLoadStateOps.ReleaseLoadState[]; loadstateHeld _ FALSE}; }; -- end ENABLE UNWIND => Unlock[mc.world]; Unlock[mc.world]; IF gfh = nilRemoteGlobalFrameHandle THEN RETURN[NIL]; RETURN[TVForRemoteGFHReferent[gfh]]}}; ENDCASE => ERROR AMTypes.Error[reason: notImplemented]; }; -- end FirstChildContext -- model -> model or prog (TV for a global frame) -- prog -> model or prog -- returns NIL if nomore NextSiblingContext: PROC[context: Context] RETURNS[ans: Context _ NIL] = { IF context = NIL THEN RETURN[NIL]; WITH context SELECT FROM sc: StatementContext => RETURN[NIL]; -- substructure? mc: ConfigContext => {IF mc.configIndex = NullConfig THEN RETURN[NIL]; IF mc.world = LocalWorld[] THEN {nbcds: ConfigIndex; nbcds _ PilotLoadStateOps.InputLoadState[]; IF mc.configIndex > 0 THEN {bcd: BcdOps.BcdBase = PilotLoadStateOps.AcquireBcd[mc.configIndex-1]; IF NOT IsComposite[bcd] -- single module loadstate entry THEN {map: PilotLoadStateOps.Map = PilotLoadStateOps.GetMap [mc.configIndex-1]; gfh: GlobalFrameHandle _ NIL; FOR j: GFTIndex DECREASING IN [1 .. LENGTH[map]) DO IF map[j] # 0 THEN {gfh _ GFT[map[j]].frame; EXIT}; ENDLOOP; IF gfh = NIL THEN {PilotLoadStateOps.ReleaseMap[map]; PilotLoadStateOps.ReleaseLoadState[]; ERROR}; PilotLoadStateOps.ReleaseMap[map]; ans _ TVForGFHReferent[gfh ! UNWIND => PilotLoadStateOps.ReleaseLoadState[]]} ELSE ans _ z.NEW[ConfigContextObj _ [world: mc.world, worldIncarnation: mc.worldIncarnation, configIndex: mc.configIndex-1]]; }; PilotLoadStateOps.ReleaseLoadState[]; RETURN} ELSE -- remote ConfigContext {nbcds: ConfigIndex; Lock[mc.world]; { ENABLE UNWIND => Unlock[mc.world]; oldState: PilotLoadStateFormat.LoadState; newState: REF PilotLoadStateFormat.LoadStateObject; loadstateHeld: BOOL _ FALSE; newState _ Loadstate[mc.world]; [] _ PilotLoadStateOps.InputLoadState[]; loadstateHeld _ TRUE; oldState _ PilotLoadStatePrivate.InstallLoadState[LOOPHOLE[newState]]; nbcds _ newState.nBcds; -- no error raised { ENABLE ANY => IF loadstateHeld THEN {[] _ PilotLoadStatePrivate.InstallLoadState[oldState]; PilotLoadStateOps.ReleaseLoadState[]; loadstateHeld _ FALSE}; IF mc.configIndex > 0 THEN {bcd: BcdOps.BcdBase _ AcquireRemoteBCD[mc.world, PilotLoadStateOps.AcquireBcd [mc.configIndex-1]]; { ENABLE UNWIND => ReleaseRemoteBCD[bcd]; IF NOT IsComposite[bcd] -- single module loadstate entry THEN {gfh: RemoteGlobalFrameHandle _ nilRemoteGlobalFrameHandle; map: PilotLoadStateOps.Map; IF NOT loadstateHeld THEN ERROR; map _ PilotLoadStateOps.GetMap[mc.configIndex-1]; FOR j: GFTIndex DECREASING IN [1 .. LENGTH[map]) DO IF map[j] # 0 THEN {gfh _ GetRemoteGFHandle[mc.world, map[j]]; EXIT}; ENDLOOP; IF gfh = nilRemoteGlobalFrameHandle THEN {PilotLoadStateOps.ReleaseMap[map]; ERROR--UNWIND releases the bcd, loadstate, and the world lock--}; PilotLoadStateOps.ReleaseMap[map]; ans _ TVForRemoteGFHReferent[gfh]} ELSE ans _ z.NEW[ConfigContextObj _ [world: mc.world, worldIncarnation: mc.worldIncarnation, configIndex: mc.configIndex-1]]; }; -- end ENABLE UNWIND => ... FREE ... ReleaseRemoteBCD[bcd]; }; }; -- end ENABLE UNWIND => ReleaseLoadState IF loadstateHeld THEN {[] _ PilotLoadStatePrivate.InstallLoadState[oldState]; PilotLoadStateOps.ReleaseLoadState[]; loadstateHeld _ FALSE}; }; -- end ENABLE UNWIND => Unlock[mc.world]; Unlock[mc.world]; RETURN}}; tv: RefTVRec => {SELECT TVType[tv] FROM gfhType => IF IsRemote[tv] THEN {gfh: RemoteGlobalFrameHandle = RemoteGFHFromTV[tv]; rgfi: GFTIndex = GetRemoteGFHeader[gfh].gfi; config: ConfigIndex; map: PilotLoadStateOps.Map; siblingGFH: RemoteGlobalFrameHandle _ nilRemoteGlobalFrameHandle; bcd: BcdOps.BcdBase; world: World = GetWorld[tv]; nbcds: ConfigIndex; loadstateHeld: BOOL _ FALSE; Lock[world]; { ENABLE UNWIND => Unlock[world]; oldState: PilotLoadStateFormat.LoadState; newState: REF PilotLoadStateFormat.LoadStateObject; newState _ Loadstate[world]; [] _ PilotLoadStateOps.InputLoadState[]; loadstateHeld _ TRUE; oldState _ PilotLoadStatePrivate.InstallLoadState[LOOPHOLE[newState]]; nbcds _ newState.nBcds; -- no error raised { ENABLE ANY => IF loadstateHeld THEN {[] _ PilotLoadStatePrivate.InstallLoadState[oldState]; PilotLoadStateOps.ReleaseLoadState[]; loadstateHeld _ FALSE}; config _ PilotLoadStateOps.MapRealToConfig[rgfi].config; bcd _ AcquireRemoteBCD[world, PilotLoadStateOps.AcquireBcd[config]]; { ENABLE UNWIND => ReleaseRemoteBCD[bcd]; IF NOT IsComposite[bcd] -- want sibling one level up THEN {siblingBCD: BcdOps.BcdBase; IF config = 0 -- last config in loadstate THEN {IF loadstateHeld THEN {[] _ PilotLoadStatePrivate.InstallLoadState[oldState]; PilotLoadStateOps.ReleaseLoadState[]; loadstateHeld _ FALSE}; ReleaseRemoteBCD[bcd]; Unlock[world]; RETURN[NIL]}; IF NOT loadstateHeld THEN ERROR; siblingBCD _ AcquireRemoteBCD [world, PilotLoadStateOps.AcquireBcd[config-1]]; { ENABLE UNWIND => ReleaseRemoteBCD[siblingBCD]; IF NOT loadstateHeld THEN ERROR; IF NOT IsComposite[siblingBCD] THEN {siblingMap: PilotLoadStateOps.Map = PilotLoadStateOps.GetMap[config-1]; {ENABLE UNWIND => PilotLoadStateOps.ReleaseMap[siblingMap]; FOR i: GFTIndex DECREASING IN [1 .. LENGTH[siblingMap]) DO IF siblingMap[i] # 0 THEN {siblingGFH _ GetRemoteGFHandle[world, siblingMap[i]]; EXIT}; ENDLOOP; }; -- end ENABLE UNWIND => ReleaseMap[siblingMap]; PilotLoadStateOps.ReleaseMap[siblingMap]; IF siblingGFH = nilRemoteGlobalFrameHandle THEN ans _ NIL ELSE ans _ TVForRemoteGFHReferent[siblingGFH]} ELSE ans _ z.NEW[ConfigContextObj _ [world: GetWorld[tv], worldIncarnation: GetWorldIncarnation[tv], configIndex: config-1]]; }; -- end ENABLE UNWIND => ... FREE[@siblingBCD] ReleaseRemoteBCD[siblingBCD]; IF loadstateHeld THEN {[] _ PilotLoadStatePrivate.InstallLoadState[oldState]; PilotLoadStateOps.ReleaseLoadState[]; loadstateHeld _ FALSE}; ReleaseRemoteBCD[bcd]; Unlock[world]; RETURN; }; -- here to get prog sibling of this composite config map _ PilotLoadStateOps.GetMap[config]; { ENABLE UNWIND => PilotLoadStateOps.ReleaseMap[map]; FOR i: GFTIndex DECREASING IN [1 .. LENGTH[map]) DO IF map[i] = rgfi THEN {FOR j: GFTIndex DECREASING IN [1 .. i) DO IF map[j] # 0 AND GetRemoteGFHandle[world, map[j]] # gfh THEN {siblingGFH _ GetRemoteGFHandle[world, map[j]]; EXIT}; ENDLOOP; EXIT}; ENDLOOP; }; -- end ENABLE UNWIND => PilotLoadStateOps.ReleaseMap[map]; PilotLoadStateOps.ReleaseMap[map]; }; -- end ENABLE UNWIND => ... FREE ... ReleaseRemoteBCD[bcd]; }; -- end ENABLE UNWIND => ...ReleaseLoadState[]; [] _ PilotLoadStatePrivate.InstallLoadState[oldState]; PilotLoadStateOps.ReleaseLoadState[]; }; -- end ENABLE UNWIND => Unlock[world]; Unlock[world]; IF siblingGFH = nilRemoteGlobalFrameHandle THEN RETURN[NIL] ELSE RETURN[TVForRemoteGFHReferent[siblingGFH]] } ELSE -- local case {gfh: GlobalFrameHandle = GFHFromTV[tv]; rgfi: GFTIndex = gfh.gfi; config: ConfigIndex; map: PilotLoadStateOps.Map; siblingGFH: GlobalFrameHandle _ NIL; bcd: BcdOps.BcdBase; nbcds: ConfigIndex = PilotLoadStateOps.InputLoadState[]; config _ PilotLoadStateOps.MapRealToConfig[rgfi].config; bcd _ PilotLoadStateOps.AcquireBcd[config]; IF NOT IsComposite[bcd] -- want sibling one level up THEN {siblingBCD: BcdOps.BcdBase; IF config = 0 -- last config in loadstate THEN {PilotLoadStateOps.ReleaseLoadState[]; RETURN[NIL]}; siblingBCD _ PilotLoadStateOps.AcquireBcd[config-1]; IF NOT IsComposite[siblingBCD] THEN { siblingMap: PilotLoadStateOps.Map = PilotLoadStateOps.GetMap[config-1]; FOR i: GFTIndex DECREASING IN [1 .. LENGTH[siblingMap]) DO IF siblingMap[i] # 0 THEN {siblingGFH _ GFT[siblingMap[i]].frame; EXIT}; ENDLOOP; PilotLoadStateOps.ReleaseMap[siblingMap]; PilotLoadStateOps.ReleaseLoadState[]; IF siblingGFH = NIL THEN RETURN[NIL] ELSE RETURN[TVForGFHReferent[siblingGFH]]} ELSE {PilotLoadStateOps.ReleaseLoadState[]; RETURN[z.NEW[ConfigContextObj _ [world: LocalWorld[], worldIncarnation: CurrentIncarnation[LocalWorld[]], configIndex: config-1]]]}}; -- here to get prog sibling of this composite config map _ PilotLoadStateOps.GetMap[config]; FOR i: GFTIndex DECREASING IN [1 .. LENGTH[map]) DO IF map[i] = rgfi THEN {FOR j: GFTIndex DECREASING IN [1 .. i) DO IF map[j] # 0 AND GFT[map[j]].frame # gfh THEN {siblingGFH _ GFT[map[j]].frame; EXIT}; ENDLOOP; EXIT}; ENDLOOP; PilotLoadStateOps.ReleaseMap[map]; PilotLoadStateOps.ReleaseLoadState[]; IF siblingGFH = NIL THEN RETURN[NIL] ELSE RETURN[TVForGFHReferent[siblingGFH]]}; ENDCASE => ERROR AMTypes.Error[reason: typeFault, type: TVType[tv]]; }; ENDCASE => ERROR; }; -- end NextSiblingContext -- ... dealing with PartialInterfaceInstances -- Implemented only for loadstate entries and global frames -- sharing Imports: PUBLIC PROC[context: Context] RETURNS[ans: LIST OF PartialInterfaceInstance _ NIL] = {WITH context SELECT FROM mc: ConfigContext => {bcd: BcdOps.BcdBase; ftb: Table.Base; AcquireIR: PROC [imph: BcdOps.IMPHandle, impi: BcdDefs.IMPIndex] RETURNS [stop: BOOLEAN _ FALSE] = {type: Type; seIndex: SymbolIndex; stb: SymbolTableBase _ AcquireSTB [RTSymbolsPrivate.GetSTHForModule [stamp: ftb[imph.file].version, fileName: BcdNameToRope[bcd, ftb[imph.file].name], moduleName: BcdNameToRope[bcd, imph.name]]]; p: PROC[stb: SymbolTableBase, isei: SymbolIdIndex] RETURNS[stop: BOOLEAN] = {IF stb.seb[isei].public THEN {seIndex _ stb.seb[isei].idType; RETURN[TRUE]} ELSE RETURN[FALSE]}; IF NOT RTSymbols.EnumerateCtxIseis[stb: stb, ctx: stb.stHandle.directoryCtx, proc: p ! UNWIND => ReleaseSTB[stb]] THEN {ReleaseSTB[stb]; ERROR}; type _ AcquireType[stb: stb, seIndex: seIndex ! UNWIND => ReleaseSTB[stb]]; ReleaseSTB[stb]; ans _ z.CONS[[ir: AcquireIRInstanceFromType[type], -- NOTE remote usingList: NIL], -- NOTE ans]; }; IF mc.configIndex = NullConfig THEN RETURN[NIL]; IF mc.world # LocalWorld[] THEN { Lock[mc.world]; { ENABLE UNWIND => Unlock[mc.world]; oldState: PilotLoadStateFormat.LoadState; newState: REF PilotLoadStateFormat.LoadStateObject; bcd: BcdOps.BcdBase; loadstateHeld: BOOL _ FALSE; newState _ Loadstate[mc.world]; [] _ PilotLoadStateOps.InputLoadState[]; loadstateHeld _ TRUE; oldState _ PilotLoadStatePrivate.InstallLoadState[LOOPHOLE[newState]]; -- no error raised bcd _ AcquireRemoteBCD[mc.world, PilotLoadStateOps.AcquireBcd[mc.configIndex] ! UNWIND => {[] _ PilotLoadStatePrivate.InstallLoadState[oldState]; PilotLoadStateOps.ReleaseLoadState[]; loadstateHeld _ FALSE}]; IF loadstateHeld THEN {[] _ PilotLoadStatePrivate.InstallLoadState[oldState]; PilotLoadStateOps.ReleaseLoadState[]; loadstateHeld _ FALSE}; IF bcd = NIL THEN ERROR; { ENABLE UNWIND => ReleaseRemoteBCD[bcd]; ftb _ LOOPHOLE[bcd + bcd.ftOffset]; IF NOT IsComposite[bcd] THEN ERROR; -- single module loadstate entry [] _ BcdOps.ProcessImports[bcd, AcquireIR]; }; -- end ENABLE UNWIND => ... FREE ... ReleaseRemoteBCD[bcd]; }; -- end ENABLE UNWIND => Unlock[mc.world]; Unlock[mc.world]; } ELSE -- local case {[] _ PilotLoadStateOps.InputLoadState[]; bcd _ PilotLoadStateOps.AcquireBcd[mc.configIndex]; PilotLoadStateOps.ReleaseLoadState[]; ftb _ LOOPHOLE[bcd + bcd.ftOffset]; IF NOT IsComposite[bcd] THEN ERROR; -- single module loadstate entry [] _ BcdOps.ProcessImports[bcd, AcquireIR]}; }; tv: RefTVRec => {SELECT TVType[tv] FROM gfhType => -- gets top level imports from the loadstate, via the minimodel -- encapsulation awaits the modeller. {bcd: BcdOps.BcdBase = RTSymbolsPrivate.AcquireBCDFromVersion [versionStamp: GFHToVersionStamp[GFHFromTV[tv]], shortFileNameHint: Rope.Concat[TVToName[tv], ".bcd"]]; ftb: Table.Base = LOOPHOLE[bcd + bcd.ftOffset]; AcquireIR: PROC[imph: BcdOps.IMPHandle, impi: BcdDefs.IMPIndex] RETURNS [stop: BOOLEAN _ FALSE] = {type: Type; seIndex: SymbolIndex; stb: SymbolTableBase _ AcquireSTB [RTSymbolsPrivate.GetSTHForModule [stamp: ftb[imph.file].version, fileName: BcdNameToRope[bcd, ftb[imph.file].name], moduleName: BcdNameToRope[bcd, imph.name]]]; p: PROC[stb: SymbolTableBase, isei: SymbolIdIndex] RETURNS[stop: BOOLEAN] = {IF stb.seb[isei].public THEN {seIndex _ stb.seb[isei].idType; RETURN[TRUE]} ELSE RETURN[FALSE]}; IF NOT RTSymbols.EnumerateCtxIseis[stb: stb, ctx: stb.stHandle.directoryCtx, proc: p ! UNWIND => ReleaseSTB[stb]] THEN {ReleaseSTB[stb]; ERROR}; type _ AcquireType[stb: stb, seIndex: seIndex ! UNWIND => ReleaseSTB[stb]]; ReleaseSTB[stb]; ans _ z.CONS[[ir: AcquireIRInstanceFromType[type], -- NOTE remote usingList: NIL], -- NOTE ans]; }; IF IsComposite[bcd] THEN {RTSymbolsPrivate.ReleaseBCD[bcd]; ERROR}--disaster--; -- single module bcd [] _ BcdOps.ProcessImports[bcd, AcquireIR ! UNWIND => RTSymbolsPrivate.ReleaseBCD[bcd]]; RTSymbolsPrivate.ReleaseBCD[bcd]; }; ENDCASE => ERROR AMTypes.Error[reason: typeFault, type: TVType[tv]]; -- NOTE interface modules import stuff. }; ENDCASE => ERROR; }; -- end Imports -- Implemented only for loadstate entries and global frames -- sharing! Exports: PUBLIC PROC[context: Context] RETURNS[ans: LIST OF PartialInterfaceInstance _ NIL] = { WITH context SELECT FROM mc: ConfigContext => {bcd: BcdOps.BcdBase; ftb: Table.Base; AcquireIR: PROC [exph: BcdOps.EXPHandle, expi: BcdDefs.EXPIndex] RETURNS [stop: BOOLEAN _ FALSE] = {type: Type; seIndex: SymbolIndex; stb: SymbolTableBase _ AcquireSTB [RTSymbolsPrivate.GetSTHForModule [stamp: ftb[exph.file].version, fileName: BcdNameToRope[bcd, ftb[exph.file].name], moduleName: BcdNameToRope[bcd, exph.name]]]; p: PROC[stb: SymbolTableBase, isei: SymbolIdIndex] RETURNS[stop: BOOLEAN] = {IF stb.seb[isei].public THEN {seIndex _ stb.seb[isei].idType; RETURN[TRUE]} ELSE RETURN[FALSE]}; IF NOT RTSymbols.EnumerateCtxIseis[stb: stb, ctx: stb.stHandle.directoryCtx, proc: p ! UNWIND => ReleaseSTB[stb]] THEN {ReleaseSTB[stb]; ERROR}; type _ AcquireType[stb: stb, seIndex: seIndex ! UNWIND => ReleaseSTB[stb]]; ReleaseSTB[stb]; ans _ z.CONS[[ir: AcquireIRInstanceFromType[type], -- NOTE remote usingList: NIL], -- NOTE ans]; }; IF mc.configIndex = NullConfig THEN RETURN[NIL]; IF mc.world # LocalWorld[] THEN { Lock[mc.world]; { ENABLE UNWIND => Unlock[mc.world]; oldState: PilotLoadStateFormat.LoadState; newState: REF PilotLoadStateFormat.LoadStateObject; bcd: BcdOps.BcdBase; loadstateHeld: BOOL _ FALSE; newState _ Loadstate[mc.world]; [] _ PilotLoadStateOps.InputLoadState[]; loadstateHeld _ TRUE; oldState _ PilotLoadStatePrivate.InstallLoadState[LOOPHOLE[newState]]; -- no error raised { ENABLE ANY => {[] _ PilotLoadStatePrivate.InstallLoadState[oldState]; PilotLoadStateOps.ReleaseLoadState[]; loadstateHeld _ FALSE}; bcd _ AcquireRemoteBCD[mc.world, PilotLoadStateOps.AcquireBcd[mc.configIndex]]; }; IF loadstateHeld THEN {[] _ PilotLoadStatePrivate.InstallLoadState[oldState]; PilotLoadStateOps.ReleaseLoadState[]; loadstateHeld _ FALSE}; IF bcd = NIL THEN ERROR; { ENABLE UNWIND => ReleaseRemoteBCD[bcd]; ftb _ LOOPHOLE[bcd + bcd.ftOffset]; IF NOT IsComposite[bcd] THEN ERROR; -- single module loadstate entry [] _ BcdOps.ProcessExports[bcd, AcquireIR]; }; -- end ENABLE UNWIND => ... FREE ... ReleaseRemoteBCD[bcd]; }; -- end ENABLE UNWIND => Unlock[mc.world]; Unlock[mc.world]; } ELSE -- local case {[] _ PilotLoadStateOps.InputLoadState[]; bcd _ PilotLoadStateOps.AcquireBcd[mc.configIndex]; PilotLoadStateOps.ReleaseLoadState[]; ftb _ LOOPHOLE[bcd + bcd.ftOffset]; IF NOT IsComposite[bcd] THEN ERROR; -- single module loadstate entry [] _ BcdOps.ProcessExports[bcd, AcquireIR]}; }; tv: RefTVRec => {SELECT TVType[tv] FROM gfhType => -- gets top level imports from the loadstate, via the minimodel -- encapsulation awaits the modeller. {bcd: BcdOps.BcdBase = RTSymbolsPrivate.AcquireBCDFromVersion [versionStamp: GFHToVersionStamp[GFHFromTV[tv]], shortFileNameHint: Rope.Concat[TVToName[tv], ".bcd"]]; ftb: Table.Base = LOOPHOLE[bcd + bcd.ftOffset]; AcquireIR: PROC[exph: BcdOps.EXPHandle, expi: BcdDefs.EXPIndex] RETURNS [stop: BOOLEAN _ FALSE] = {type: Type; seIndex: SymbolIndex; stb: SymbolTableBase _ AcquireSTB [RTSymbolsPrivate.GetSTHForModule [stamp: ftb[exph.file].version, fileName: BcdNameToRope[bcd, ftb[exph.file].name], moduleName: BcdNameToRope[bcd, exph.name]]]; p: PROC[stb: SymbolTableBase, isei: SymbolIdIndex] RETURNS[stop: BOOLEAN] = {IF stb.seb[isei].public THEN {seIndex _ stb.seb[isei].idType; RETURN[TRUE]} ELSE RETURN[FALSE]}; IF NOT RTSymbols.EnumerateCtxIseis[stb: stb, ctx: stb.stHandle.directoryCtx, proc: p ! UNWIND => ReleaseSTB[stb]] THEN {ReleaseSTB[stb]; ERROR}; type _ AcquireType[stb: stb, seIndex: seIndex ! UNWIND => ReleaseSTB[stb]]; ReleaseSTB[stb]; ans _ z.CONS[[ir: AcquireIRInstanceFromType[type], -- NOTE remote usingList: NIL], -- NOTE ans]; }; IF IsComposite[bcd] THEN {RTSymbolsPrivate.ReleaseBCD[bcd]; ERROR}--disaster--; -- single module bcd [] _ BcdOps.ProcessExports[bcd, AcquireIR ! UNWIND => RTSymbolsPrivate.ReleaseBCD[bcd]]; RTSymbolsPrivate.ReleaseBCD[bcd]; }; ENDCASE => ERROR AMTypes.Error[reason: typeFault, type: TVType[tv]]; }; ENDCASE => ERROR; }; -- end Exports -- Private Procedures StripExtension: PROC[name: ROPE] RETURNS[ROPE] = {RETURN[Rope.Substr[base: name, start: 0, len: Rope.SkipTo[s: name, pos: 0, skip: "."]]]}; IsComposite: PROC[bcd: BcdOps.BcdBase] RETURNS[BOOL] = {RETURN[bcd.nConfigs # 0]}; BcdNameToRope: PROC[bcd: BcdOps.BcdBase, n: BcdDefs.NameRecord] RETURNS[ROPE] = {nameString: STRING = [100]; ssb: BcdOps.NameString = LOOPHOLE[bcd + bcd.ssOffset]; ssd: Strings.SubStringDescriptor _ [base: @ssb.string, offset: n, length: MIN[ssb.size[n], 100]]; nameString.length _ 0; Strings.AppendSubString[nameString, @ssd]; RETURN[ConvertUnsafe.ToRope[LONG[nameString]]]}; RemoteGFHToVersionStamp: PROC[gfh: RemoteGlobalFrameHandle] RETURNS[version: BcdDefs.VersionStamp _ BcdDefs.NullVersion] = { mappedBCD: BcdOps.BcdBase; module: PilotLoadStateFormat.ModuleInfo; -- a loadstate.gft entry mth: BcdOps.MTHandle; ftb: Table.Base; FindModule: PROC [mth: BcdOps.MTHandle, mti: BcdDefs.MTIndex] RETURNS [BOOLEAN] = {RETURN[module.gfi IN [mth.gfi .. mth.gfi + mth.ngfi)]}; [mappedBCD, module] _ AcquireRemoteBCDAndModule[gfh]; -- here with the copied remote BCD. Now poke around in the remote bcd to find -- the version stamp ftb _ LOOPHOLE[LOOPHOLE[mappedBCD, LONG POINTER] + mappedBCD.ftOffset]; [mth, ] _ BcdOps.ProcessModules[LOOPHOLE[mappedBCD], FindModule]; IF mth = NIL THEN {ReleaseRemoteBCD[mappedBCD]; ERROR}--disaster--; version _ IF mth.file = BcdDefs.FTSelf THEN mappedBCD.version ELSE ftb[mth.file].version; ReleaseRemoteBCD[mappedBCD]; }; GFHToVersionStamp: PROC[f: PrincOps.GlobalFrameHandle] RETURNS[version: BcdDefs.VersionStamp _ BcdDefs.NullVersion] = { cgfi: PrincOps.GFTIndex; config: ConfigIndex; bcd: BcdOps.BcdBase; ftb: Table.Base; FindModuleVersion: PROC[mth: BcdOps.MTHandle, mti: BcdDefs.MTIndex] RETURNS[BOOLEAN] = {IF cgfi IN [mth.gfi..mth.gfi + mth.ngfi) THEN {version _ IF mth.file = BcdDefs.FTSelf THEN bcd.version ELSE ftb[mth.file].version; RETURN[TRUE]} ELSE RETURN[FALSE]}; -- start GFHToVersionStamp here [] _ PilotLoadStateOps.InputLoadState[]; [cgfi, config] _ PilotLoadStateOps.MapRealToConfig [(IF f.copied THEN FindOriginal[f] ELSE f).gfi]; IF config = PilotLoadStateOps.NullConfig THEN {PilotLoadStateOps.ReleaseLoadState[]; RETURN}; bcd _ PilotLoadStateOps.AcquireBcd[config]; ftb _ LOOPHOLE[bcd + bcd.ftOffset]; [] _ BcdOps.ProcessModules[bcd, FindModuleVersion]; PilotLoadStateOps.ReleaseLoadState[]; }; FindOriginal: PROC[copy: PrincOps.GlobalFrameHandle] RETURNS [PrincOps.GlobalFrameHandle] = {Original: PROC [f: PrincOps.GlobalFrameHandle] RETURNS [BOOLEAN] = {RETURN[f # copy AND NOT f.copied AND SameModule[copy, f]]}; RETURN [ReverseEnumerateGFT[Original]]}; SameModule: PROC [f1, f2: PrincOps.GlobalFrameHandle] RETURNS [same: BOOLEAN] = {cb1: PrincOps.FrameCodeBase _ f1.code; cb2: PrincOps.FrameCodeBase _ f2.code; cb1.out _ FALSE; cb2.out _ FALSE; RETURN [cb1.longbase = cb2.longbase]}; ReverseEnumerateGFT: PROC[proc: PROC[PrincOps.GlobalFrameHandle] RETURNS[BOOL]] RETURNS [frame: PrincOps.GlobalFrameHandle] = {FOR i: PrincOps.GFTIndex DECREASING IN [0..SDDefs.SD[SDDefs.sGFTLength]) DO ep: CARDINAL; [frame, ep] _ GFT[i]; IF frame # PrincOps.NullGlobalFrame AND ep = 0 AND proc[frame] THEN RETURN ENDLOOP; RETURN [PrincOps.NullGlobalFrame] }; ProgPCToFGI: PUBLIC PROC[prog: RTBasic.TV--globalFrame--, pc: PrincOps.BytePC] RETURNS[ans: FGIndex _ FGNull] = {stb: SymbolTableBase; IF IsRemote[prog] THEN stb _ AcquireSTBFromRemoteGFH[RemoteGFHFromTV[prog]] ELSE stb _ AcquireSTBFromGFH[GFHFromTV[prog]]; {ENABLE UNWIND => RTSymbols.ReleaseSTB[stb]; --now compute the epi and the relative pc epi: EPI; startPC: PrincOps.BytePC; IF IsRemote[prog] THEN [epi, startPC] _ RTTypesRemotePrivate.GetRemoteEp [pc: pc, gf: RemoteGFHFromTV[prog], stb: stb] ELSE [epi, startPC] _ RTTypesPrivate.GetEp [pc: pc, gf: GFHFromTV[prog], stb: stb]; ans _ PCToFGI[stb, epi, pc - startPC]; }; -- end ENABLE UNWIND => RTSymbols.ReleaseSTB[stb]; RTSymbols.ReleaseSTB[stb]; }; -- [local frame, PC] => FGIndex (wrt prog module bcd) StatementContextToFGI: PROC[sc: StatementContext] RETURNS[ans: FGIndex _ FGNull] = {prog: REF prog SectionObj _ NIL; bcd: BcdOps.BcdBase; c: Context _ sc; world: World; local: BOOL _ FALSE; UNTIL ContextClass[c] = prog DO c _ ParentContext[c]; ENDLOOP; world _ GetWorld[c]; prog _ NARROW[ContextSection[c]]; local _ (world = LocalWorld[]); IF local THEN bcd _ GetLocalBCD[rgfi: GFHFromTV[c].gfi] ELSE bcd _ GetRemoteBCD[world: world, rgfi: GetRemoteGFHeader[RemoteGFHFromTV[c]].gfi]; {ENABLE UNWIND => IF NOT local THEN ReleaseRemoteBCD[bcd]; mth: BcdOps.MTHandle; stb: RTSymbols.SymbolTableBase; GetModule: PROC[mth: BcdOps.MTHandle, mti: BcdDefs.MTIndex] RETURNS[BOOL] = {RETURN[TRUE]}; [mth,] _ BcdOps.ProcessModules[bcd, GetModule]; IF mth = NIL THEN ERROR; stb _ RTSymbols.AcquireSTBFromSGI[bcd: bcd, sgi: mth.sseg]; {ENABLE UNWIND => RTSymbols.ReleaseSTB[stb]; --now compute the epi and the relative pc pc: PrincOps.BytePC = AMBridge.ContextPC[sc.localFrameTV]; epi: EPI; startPC: PrincOps.BytePC; IF IsRemote[sc.localFrameTV] THEN [epi, startPC] _ RTTypesRemotePrivate.GetRemoteEp [pc: pc, gf: RemoteGFHFromTV[GlobalParent[sc.localFrameTV]], stb: stb] ELSE [epi, startPC] _ RTTypesPrivate.GetEp [pc: pc, gf: FHFromTV[sc.localFrameTV].accesslink, stb: stb]; ans _ PCToFGI[stb, epi, pc - startPC]; }; -- end ENABLE UNWIND => RTSymbols.ReleaseSTB[stb]; RTSymbols.ReleaseSTB[stb]; }; -- end ENABLE UNWIND => ... ReleaseRemoteBCD; IF NOT local THEN ReleaseRemoteBCD[bcd]; }; -- end StatementContextToFGI }. Ê– "Mesa" style˜Iprocš¨Ïc¸œÏk œ žœÃžœ(žœ>žœžœÍžœMžœ3žœ~žœ¡žœ žœ"žœ|žœŸžœ žœržœžœ;žœžœžœ¸žœFžœ%žœžœ9žœ¬žœžœžœ žœ1žœžœžœ|žœžœžœ žœÒ œGœ6œ žœžœžœžœžœžœ$eœÏn œžœžœžœ+œ@œ:œžœžœÎŸ œžœžœžœžœ žœžœ žœ)žœ>žœžœ)žœžœ4žœ žœ"žœ(žœžœžœ)žœžœ2Ÿ œžœžœžœ žœ žœžœ žœ9žœžœžœ!"Ÿ œžœžœžœžœžœ žœ žœžœæžœ¡žœzžœ žœ(žœ.žœKžœžœžœ0žœžœžœ…žœ?žœÒžœ.žœKžœžœžœ0žœžœžœÏžœ>žœ½žœžœ@žœ¯œ/žœ>žœ<žœ„Ÿœžœ¢žœžœžœ0žœžœžœžœ.žœCžœÄžœkžœžœ¤žœcžœžœãžœ§žœ=œØžœúžœ1žœ=žœÝžœ0žœžœžœžœ0žœžœˆ%œò*œnœ,.œžœžœ0œIœUœœ Iœ =œƒœJœŸœžœžœžœ œžœžœžœ žœžœ-žœœžœHCœ-žœ£žœžœžœžœœœžœ žœžœžœ žœ1žœ?žœžœAžœ.žœ:žœžœœžœžœ{žœžœ³œ7œŸ œžœžœžœ2œ6žœ žœžœ žœžœžœ žœžœžœžœ žœ.žœžœžœžœ)žœžœœ žœžœžœžœžœžœažœžœžœžœžœœHœŸœžœžœžœžœ žœ žœžœvžœJžœTžœ&žœžœVžœ žœ¾žœ žœ#œžœžœÆžœFžœ®žœžœ œ$žœ+žœ®žœªžœPžœžœ¸žœžœ¥žœ*œ°žœ‘žœžœ‚žœžœžœ.žœ žœžœÈžœžœÏžœ-žœDžœžœžœžœ¨žœžœžœžœ!žœÏžœžœžœžœžœAžœžœxžœyžœžœÎžœKžœ=œéžœæžœžœ'žœ±žœžœžœžœžœžœžœ;žœ½%œG*œHžœžœ/œœœœœœŸ œžœžœžœžœ žœžœ žœ=žœ,žœžœžœžœžœ2œžœÀžœ žœ.žœžœ!žœžœžœþžœœ’žœžœsžœzžœžœÈžœJžœ=œ:žœžœÈžœcžœžœžœžœgžœžœžœžœí'œ;žœžœÿžœ#žœžœ>žœžœ/œ 2œœœŸœžœžœžœ žœžœ žœžœ žœGžœžœžœžœ žœžœžœŸœžœžœžœ žœžœ,žœžœ$œ3žœ žœ!žœžœNžœžœžœžœ]žœ)žœžœ.žœâžœHžœ%žœKžœžœÂžœžœ&žœ žœžœ.žœžœ9žœžœFžœ)žœKžœžœ'žœ©žœµžœIžœœWžœžœlžœGžœžœžœEžœfœžœžœžœ5žœÍžœëžœžœ7žœžœ!œžœ£žœžœžœžœvžœžœLžœ žœžœ.žœžœ9žœcžœ)žœMžœ"žœžœ)>œ'+œ¬žœ žœ¦%œa)œžœ!žœ¥žœ*œ4žœœ žœžœ.žœžžœžœ ž œžœžœ"žœžœ,žœžœ9žœžœ–žœžœžœžœžœžœ.žœ™žœžœ~žœ†žœžœªžœNžœ=œ‰žœžœ¢žœžœ ž œžœžœ#žœžœ-žœWžœžœœXžœ*žœ·žœ*œFžœ"žœžœžœžœ<žœžœ/œ 2œœœŸœžœžœžœ žœ žœžœžœžœ žœ žœžœ žœžœœ1žœžœžœžœžœ'žœtžœ&žœcžœžœ!œžœÞžœ(žœ ž œžœžœ.žœžœ9žœžœFžœ)žœMžœžœ'žœ©žœÀžœGžœ žœ÷žœžœœWžœžœlžœGžœžœžœEžœfœžœžœžœ9žœÕžœžœ&žœœžœžœ7žœžœ!œžœ£žœžœžœžœ¥žœ ž œžœžœ.žœžœ9žœcžœ)žœMžœHžœTž:œ¯žœ žœ¯%œa)œžœ!žœ¥žœ*œ4žœ/žœ žœ7žœ%žœ‹žœžœAžœžœyžœÉžœMžœnœžœžœžœ<žœÛžœ…žœžœ5žœžœœžœAžœ œ$žœžœ<žœÛžœ°žœžœ'žœžœžœžœ‹žœžœužœžœžœžœ%žœžœ=žœÌžœžœUžœ ž œžœžœ7žœžœAžœÏžœ+žœ,1œxžœQžœžœ)žœOžœ žœ¯/œdžœ3žœÉžœ’žœZ5œZžœžœ@žœ ž œžœžœ"žœžœ/žœžœ ž œžœ5žœžœ=žœXžœjžœ-žœ+žœžœ<œW%œK/œª'œBžœCžœžœžœžœžœVžœœžœ¿žœžœœžœAžœ œ$žœUžœžœžœžœ=žœÌžœ ž œžœžœ7žœžœAžœžœNžœ+žœÇžœžœ)žœžœžœ*žœžœDžœTžœžœÍ5œtžœ ž œžœžœ"žœžœ/žœžœ ž œžœ5žœžœ=žœžœEžœžœžœ-žœ+žœžœ–žœžœžœžœžœžœžœ6žœžœQžœžœ œ.œ <œ œŸœžœžœžœžœžœžœžœ žœžœeŸ œžœCžœžœžœÛžœGžœžœžœ0žœ"žœžœžœžœžœžœžœúžœ*žœžœGžœWžœ(œ0žœœ]žœžœžœžœžœ%žœ1žœžœjžœkžœžœ¹žœDžœ=œ£žœÒžœžœ žœ£žœžœžœžœžœžœžœ2žœ&žœžœžœžœ!œN%œ9*œ>žœœÅžœ%žœžœžœžœ!œjžœ žœ@œ'œžœ(Ÿ œžœIžœžœžœÛžœGžœžœžœ0žœ"žœžœžœžœžœžœžœúžœ*žœžœGžœWžœ(œ/žœœcžœ%žœ$žœ œœdžœyžœžœB(œžœžœ œ <œ œŸœžœžœžœžœžœžœ žœ žœžœcŸ œžœCžœžœžœüžœGžœžœžœ0žœ"žœžœžœžœžœžœžœúžœ*žœžœGžœWžœ(œ0žœœ]žœžœžœžœžœ%žœ1žœžœjžœkžœžœ¹žœDžœ=œ4žœžœ¼žœ„žœ žœ£žœžœžœžœžœžœžœ2žœ&žœžœžœžœ!œN%œ9*œ>žœœÅžœ%žœžœžœžœ!œižœ žœ@œ&œžœ(Ÿ œžœIžœžœžœüžœGžœžœžœ0žœ"žœžœžœžœžœžœžœúžœ*žœžœGžœWžœ(œ/žœœcžœ%žœ$žœ œœdžœyžœžœGžœžœ œœŸœžœžœžœžœžœWŸ œžœžœžœžœŸ œžœ-žœžœžœ'žœ¾žœcžœžœŸœžœ'žœŒœ4Ÿ œžœ8žœžœžœ žœiNœ œ žœžœ žœžœ>žœžœžœžœ<žœ œžœ,žœ$žœDŸœžœ(žœ¥Ÿœžœ7žœžœ žœžœ'žœ žœ9žœ+žœ)žœžœ žœžœžœ œ‹žœ žœžœžœ,žœ(žœ@žœ…Ÿ œžœ+žœ$Ÿœžœ!žœžœ žœ žœžœ žœžœ'Ÿ œžœ.žœžœkžœžœžœ%Ÿœžœžœžœžœ žœ+žœž œžœ žœžœžœžœžœ"žœžœžœžœžœžœ%Ÿ œžœžœžœžœ8žœžœ;žœ1žœžœ**œ žœ0žœžœðžœ2œ/6Ÿœžœžœ$žœžœQžœžœ žœžœžœ(žœKžœ žœ1žœažœžœžœžœžœkŸ œžœ-žœžœžœžœCžœžœžœžœNžœžœ**œRžœ8žœ%žœžœª2œ--œžœžœžœœ˜Š×J˜—…—+Ž?¬