DIRECTORY AMBridge USING [TVForGFHReferent, GFHFromTV, TVToProc, FHFromTV, ContextPC, GetWorld, RemoteGlobalFrameHandle, IsRemote, RemoteGFHFromTV, RemoteFHFromTV, TVToRemoteProc, GetWorldIncarnation, nilRemoteGlobalFrameHandle, TVForRemoteGFHReferent, RemotePD], AMMiniModel USING [GetInterfaceRecordFromType, GetInterfaceRecordNames, GetInterfaceRecord], 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, TV], BcdDefs USING [NullVersion, VersionStamp, MTIndex, FTSelf, NameRecord, IMPIndex, EXPIndex, CTIndex, CTNull, BcdBase, MTHandle, NameString, IMPHandle, EXPHandle, CTHandle], BcdOps USING [ProcessModules, ProcessImports, ProcessExports, ProcessConfigs], ConvertUnsafe USING [SubString, SubStringToRope], IO USING [PutFR], LoadState USING [Acquire, local, ConfigInfo, Release, Handle, nullConfig, GetChangeCount, GlobalFrameToModule, ConfigID, ModuleIndex, EnumerateAllModules, ModuleToGlobalFrame, EnumerateModulesInConfig, EnumerateConfigs, nullModule, CopiesList, ModuleInfo], PrincOps USING [GlobalFrameHandle, BytePC], PrincOpsUtils USING [GlobalFrameAndEntryPoint], RemotePrincOpsUtils USING [RemoteGlobalFrameAndEntryPoint], Rope USING [ROPE, Concat, Substr, SkipTo, Index, Length, Match, Cat], RTSymbolDefs USING [SymbolTableBase, SymbolTableHandle, SymbolIndex, SymbolIdIndex, SymbolConstructorIndex], RTSymbolOps USING [EnumerateCtxIseis, STBToModuleName, AcquireType, SEUnderType, STBDirectoryCtx, ISEPublic, ISEType], RTSymbols USING [GetTypeSymbols, AcquireSTB, ReleaseSTB, AcquireSTBFromSGI, AcquireSTBFromGFH, GetSTHForModule], RTSymbolsPrivate USING [AcquireBCDFromVersion, ReleaseBCD], RTTypesPrivate USING [GetEp], RTTypesRemotePrivate USING [AcquireRemoteBCD, GetRemoteEp, AcquireSTBFromRemoteGFH, ReleaseRemoteBCD], SafeStorage USING [Type, fhType, gfhType], Table USING [Base], WorldVM USING [LocalWorld, World, WorldName, CurrentIncarnation, Lock, Unlock, Loadstate, Incarnation, Read, Address]; AMModelContextImpl: MONITOR -- protects WorldGFNameLists IMPORTS AMBridge, AMModelPrivate, AMTypes, BcdOps, IO, ConvertUnsafe, LoadState, PrincOpsUtils, RemotePrincOpsUtils, Rope, AMMiniModel, RTSymbolOps, RTSymbols, RTSymbolsPrivate, RTTypesPrivate, RTTypesRemotePrivate, WorldVM EXPORTS AMModel, AMModelPrivate = { OPEN AMBridge, AMMiniModel, AMModel, AMModelPrivate, AMTypes, PrincOps, RemotePrincOpsUtils, Rope, RTSymbolDefs, RTSymbolOps, RTSymbols, RTTypesPrivate, RTTypesRemotePrivate, SafeStorage, WorldVM; Section: TYPE = REF SectionObj; SectionObj: PUBLIC TYPE = SectionRec; WorldGFNameList: TYPE = LIST OF WorldGFNames; WorldGFNames: TYPE = REF WorldGFNameListRec; WorldGFNameListRec: TYPE = RECORD[ world: World, incarnation: Incarnation, loadStateChangeCount: INT, gfList: LIST OF GFContextRec]; GFContextRec: TYPE = RECORD[name: ROPE, context: Context]; worldGFNameList: WorldGFNameList _ NIL; RootContext: PUBLIC PROC [world: World] RETURNS [Context] = { IF world = NIL THEN world _ WorldVM.LocalWorld[]; RETURN[NEW[ConfigContextObj _ [world: world, worldIncarnation: CurrentIncarnation[world], configIndex: LoadState.nullConfig]]]; }; ContextClass: PUBLIC PROC [context: Context] RETURNS [Class] = { WITH context SELECT FROM sc: StatementContext => RETURN[statement]; mc: ConfigContext => IF mc.configIndex = LoadState.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]]; }; ContextName: PUBLIC PROC [context: Context] RETURNS [ans: ROPE _ NIL] = { IF context = NIL THEN RETURN[NIL]; WITH context SELECT FROM sc: StatementContext => { ans _ IO.PutFR["%g:FGT#%g", [rope[ContextName[sc.localFrameTV]]], [cardinal[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 _ TVToName[tv ! AMTypes.Error => CONTINUE]; ans _ IO.PutFR["%g:gfh#%b", [rope[ans]], [cardinal[gfhBits]]]; }; fhType => { fhBits: CARDINAL = IF GetWorld[tv] # LocalWorld[] THEN LOOPHOLE[RemoteFHFromTV[tv].fh, CARDINAL] ELSE LOOPHOLE[FHFromTV[tv], CARDINAL]; ans _ TVToName[Procedure[tv ! AMTypes.Error => CONTINUE] ! AMTypes.Error => CONTINUE]; ans _ IO.PutFR["%g:fh#%b", [rope[ans]], [cardinal[fhBits]]]; }; ENDCASE => { ans _ Cat["Interface:", TypeToName[TVType[tv]]]; }; -- assume an IR IF GetWorld[tv] # LocalWorld[] THEN ans _ Cat[ans, ",world:", WorldName[GetWorld[tv]]]; }; mc: ConfigContext => IF mc.configIndex = LoadState.nullConfig THEN ans _ Rope.Cat["World:", WorldName[mc.world]] ELSE { FindRootConfig: PROC [cth: BcdDefs.CTHandle, cti: BcdDefs.CTIndex] RETURNS [stop: BOOL _ FALSE] = { IF cth.config = BcdDefs.CTNull THEN RETURN[TRUE]; }; IF mc.world = LocalWorld[] THEN { bcd: BcdDefs.BcdBase; ctHandle: BcdDefs.CTHandle; LoadState.local.Acquire[]; bcd _ LoadState.local.ConfigInfo[mc.configIndex ! UNWIND => LoadState.local.Release[]].bcd; LoadState.local.Release[]; IF bcd = NIL THEN ERROR; [ctHandle,] _ BcdOps.ProcessConfigs[bcd, FindRootConfig]; ans _ IO.PutFR[ "%g:ConfigIndex#%g", [rope[BcdNameToRope[bcd, ctHandle.name]]], [cardinal[LOOPHOLE[mc.configIndex, CARDINAL]]] ]; } ELSE { bcd: BcdDefs.BcdBase; ctHandle: BcdDefs.CTHandle; Lock[mc.world]; { ENABLE UNWIND => Unlock[mc.world]; h: LoadState.Handle = WorldVM.Loadstate[mc.world]; h.Acquire[]; { ENABLE UNWIND => h.Release[]; bcd _ AcquireRemoteBCD [mc.world, mc.worldIncarnation, h.ConfigInfo[mc.configIndex].bcd]; }; h.Release[]; }; Unlock[mc.world]; IF bcd = NIL THEN ERROR; { ENABLE UNWIND => ReleaseRemoteBCD[bcd]; [ctHandle,] _ BcdOps.ProcessConfigs[bcd, FindRootConfig]; ans _ IO.PutFR["%g:ConfigIndex#%g,world:%g", [rope[BcdNameToRope[bcd, ctHandle.name]]], [cardinal[LOOPHOLE[mc.configIndex, CARDINAL]]], [rope[WorldName[mc.world]]] ]; }; ReleaseRemoteBCD[bcd]; }; }; -- end ELSE arm (mc.configIndex # LoadState.nullConfig) ENDCASE => ERROR AMTypes.Error[reason: notImplemented]; }; MostRecentNamedContext: PUBLIC PROC [name: ROPE, context: --world or model-- Context] RETURNS [ans: Context _ NIL] = { WITH context SELECT FROM mc: ConfigContext => { IF mc.configIndex = LoadState.nullConfig -- the model of a world THEN { p: PROC [name: ROPE, gf: TV] RETURNS [stop: BOOL _ TRUE] = {NULL}; ans _ FindMatchingGlobalFrames[ContextWorld[context], name, p]; IF ans # NIL THEN RETURN; }; { 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] THEN {ans _ c; stop _ TRUE}; }; [] _ ContextChildren[context, p]; }; }; ENDCASE => ERROR AMTypes.Error [reason: notImplemented, msg: "MostRecentNamedContext for other than a world or model Context"]; }; LoadStateChangeCount: INTERNAL PROC [world: World] RETURNS [ans: INT] = { h: LoadState.Handle = WorldVM.Loadstate[world]; h.Acquire[]; ans _ LoadState.GetChangeCount[h]; h.Release[]; }; FindWorldGFNames: INTERNAL PROC [world: World] RETURNS [WorldGFNames] = { FOR wgfnl: WorldGFNameList _ worldGFNameList, wgfnl.rest UNTIL wgfnl = NIL DO IF world = wgfnl.first.world THEN { IF (CurrentIncarnation[world] # wgfnl.first.incarnation) OR (LoadStateChangeCount[world] # wgfnl.first.loadStateChangeCount) THEN { wgfnl.first.gfList _ NIL; wgfnl.first.incarnation _ CurrentIncarnation[world]; wgfnl.first.loadStateChangeCount _ LoadStateChangeCount[world]; }; RETURN[wgfnl.first]; }; ENDLOOP; worldGFNameList _ CONS[NEW[WorldGFNameListRec _ [world: world, incarnation: CurrentIncarnation[world], loadStateChangeCount: LoadStateChangeCount[world], gfList: NIL]], worldGFNameList]; RETURN[worldGFNameList.first]; }; FindMatchingGlobalFrames: PUBLIC ENTRY PROC [ world: World, name: ROPE, proc: PROC [ROPE, Context] RETURNS [--stop:-- BOOL] ] RETURNS [ans: Context _ NIL] = { ENABLE UNWIND => NULL; gfNames: WorldGFNames; WorldVM.Lock[world]; { ENABLE UNWIND => WorldVM.Unlock[world]; gfNames _ FindWorldGFNames[world]; IF gfNames.gfList = NIL THEN { h: LoadState.Handle = WorldVM.Loadstate[world]; p: PROC [ci: LoadState.ConfigID, mx: LoadState.ModuleIndex] RETURNS [stop: BOOL _ FALSE] = { rgfh: RemoteGlobalFrameHandle = [world: world, worldIncarnation: CurrentIncarnation[world], gfh: LOOPHOLE[h.ModuleToGlobalFrame[ci, mx]]]; gfNames.gfList _ CONS[[name: NIL, context: TVForRemoteGFHReferent[rgfh]], gfNames.gfList]; }; h.Acquire[]; [] _ h.EnumerateAllModules[oldestFirst, p ! UNWIND => h.Release[]]; h.Release[]; }; }; -- ENABLE UNWIND => WorldVM.Unlock[world]; WorldVM.Unlock[world]; FOR gfList: LIST OF GFContextRec _ gfNames.gfList, gfList.rest UNTIL gfList = NIL DO IF gfList.first.name = NIL THEN gfList.first.name _ AMTypes.TVToName[gfList.first.context]; IF name.Match[gfList.first.name, FALSE] AND proc[gfList.first.name, gfList.first.context ! AMTypes.Error => LOOP] THEN RETURN[gfList.first.context]; ENDLOOP; }; NamedContexts: PUBLIC PROC [name: ROPE, context: Context, proc: PROC [Context] RETURNS [stop: BOOL]] RETURNS [ans: Context _ NIL] = { 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; }; [] _ ContextChildren[context, lookForNamedContext]; }; 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[NEW[SectionObj _ [statement[prog: NARROW[ContextSection[parentContext], REF prog SectionObj], fgtIndex: StatementContextToFGI[sc]]]]]; }; tv: RefTVRec => { SELECT TVType[tv] FROM gfhType => -- program module RETURN[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 ep: CARDINAL; IF IsRemote[procTV] THEN { rpd: AMBridge.RemotePD = AMBridge.TVToRemoteProc[procTV]; ep _ RemoteGlobalFrameAndEntryPoint[rpd.world, rpd.pd].ep; } ELSE ep _ PrincOpsUtils.GlobalFrameAndEntryPoint[ LOOPHOLE[TVToProc[procTV]]].ep; RETURN[NEW[SectionObj _ [proc[prog: NARROW[ContextSection[GlobalParent[tv]]], entryPointIndex: 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 = SEUnderType[stb, sei]; WITH stb SELECT FROM t: SymbolTableBase.x => WITH ser: t.e.seb[NARROW[csei, SymbolConstructorIndex.x].e] SELECT FROM definition => vs _ t.e.stHandle.version; ENDCASE => ERROR; t: SymbolTableBase.y => WITH ser: t.e.seb[NARROW[csei, SymbolConstructorIndex.y].e] SELECT FROM definition => vs _ t.e.stHandle.version; ENDCASE => ERROR; ENDCASE => ERROR; mn _ STBToModuleName[stb]; }; ReleaseSTB[stb]; RETURN[NEW[SectionObj _ [interface[moduleName: mn, versionStamp: vs]]]]; }; }; mc: ConfigContext => IF mc.world = LocalWorld[] THEN { bcd: BcdDefs.BcdBase; IF mc.configIndex = LoadState.nullConfig THEN RETURN[NIL]; LoadState.local.Acquire[]; bcd _ LoadState.local.ConfigInfo[mc.configIndex ! UNWIND => LoadState.local.Release[]].bcd; LoadState.local.Release[]; IF bcd = NIL THEN ERROR; ans _ NEW[SectionObj _ [model[configName: StripExtension[BcdNameToRope[bcd, bcd.source]], versionStamp: bcd.version, configContext: mc]]]; } ELSE { bcd: BcdDefs.BcdBase; IF mc.configIndex = LoadState.nullConfig THEN RETURN[NIL]; Lock[mc.world]; { ENABLE UNWIND => Unlock[mc.world]; h: LoadState.Handle = WorldVM.Loadstate[mc.world]; h.Acquire[]; { ENABLE UNWIND => h.Release[]; bcd _ AcquireRemoteBCD [mc.world, mc.worldIncarnation, h.ConfigInfo[mc.configIndex].bcd]; }; h.Release[]; }; Unlock[mc.world]; IF bcd = NIL THEN ERROR; { ENABLE UNWIND => ReleaseRemoteBCD[bcd]; ans _ NEW[SectionObj _ [model[configName: StripExtension[BcdNameToRope[bcd, bcd.source]], versionStamp: bcd.version, configContext: mc]]]; }; ReleaseRemoteBCD[bcd]; }; ENDCASE => ERROR AMTypes.Error[reason: notImplemented]; }; ParentContext: PUBLIC PROC [context: Context] RETURNS [Context] = { WITH context SELECT FROM sc: StatementContext => RETURN[sc.localFrameTV]; mc: ConfigContext => IF mc.configIndex = LoadState.nullConfig THEN RETURN[NIL] ELSE -- the loadstate has only one level of structure RETURN[NEW[ConfigContextObj _ [world: mc.world, worldIncarnation: mc.worldIncarnation, configIndex: LoadState.nullConfig]]]; tv: RefTVRec => { SELECT TVType[tv] FROM gfhType => { world: World _ GetWorld[tv]; ci: LoadState.ConfigID; IF NOT IsRemote[tv] THEN { gfh: PrincOps.GlobalFrameHandle = GFHFromTV[tv]; LoadState.local.Acquire[]; ci _ LoadState.local.GlobalFrameToModule[gfh].config; LoadState.local.Release[]; } ELSE { -- remote case rgfh: RemoteGlobalFrameHandle = RemoteGFHFromTV[tv]; Lock[world]; { ENABLE UNWIND => Unlock[world]; h: LoadState.Handle _ WorldVM.Loadstate[world]; h.Acquire[]; ci _ h.GlobalFrameToModule[LOOPHOLE[rgfh.gfh] ! UNWIND => h.Release[]].config; h.Release[]; }; -- end ENABLE UNWIND => Unlock[world]; Unlock[world]; }; RETURN[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]; }; 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[NEW[StatementContextObj _ [localFrameTV: tv]]]; gfhType => RETURN[NIL]; ENDCASE => ERROR AMTypes.Error[reason: typeFault, type: TVType[tv]]; mc: ConfigContext => IF mc.configIndex = LoadState.nullConfig THEN { IF mc.world = LocalWorld[] THEN { config: LoadState.ConfigID; gfh: GlobalFrameHandle; composite: BOOL; LoadState.local.Acquire[]; { ENABLE UNWIND => LoadState.local.Release[]; mx: LoadState.ModuleIndex; p: PROC [LoadState.ConfigID, LoadState.ModuleIndex] RETURNS [BOOL] = {RETURN[TRUE]}; [config, mx] _ LoadState.local.EnumerateAllModules[newestFirst, p]; composite _ IsComposite[LoadState.local.ConfigInfo[config].bcd]; gfh _ LoadState.local.ModuleToGlobalFrame[config, mx]; IF gfh = NIL THEN ERROR; }; -- ENABLE UNWIND => LoadState.local.Release[]; LoadState.local.Release[]; IF composite THEN RETURN[NEW[ConfigContextObj _ [world: mc.world, worldIncarnation: mc.worldIncarnation, configIndex: config]]] ELSE RETURN[TVForGFHReferent[gfh]]; } ELSE { -- remote world config: LoadState.ConfigID; gfh: GlobalFrameHandle; rgfh: RemoteGlobalFrameHandle _ nilRemoteGlobalFrameHandle; composite: BOOL; Lock[mc.world]; { ENABLE UNWIND => Unlock[mc.world]; h: LoadState.Handle = WorldVM.Loadstate[mc.world]; h.Acquire[]; { ENABLE UNWIND => h.Release[]; mx: LoadState.ModuleIndex; p: PROC [LoadState.ConfigID, LoadState.ModuleIndex] RETURNS [BOOL] = {RETURN[TRUE]}; [config, mx] _ h.EnumerateAllModules[newestFirst, p]; composite _ IsRemoteBCDComposite[mc.world, h.ConfigInfo[config].bcd]; gfh _ h.ModuleToGlobalFrame[config, mx]; IF gfh = NIL THEN ERROR; rgfh _ [mc.world, mc.worldIncarnation, LOOPHOLE[gfh]]; }; -- ENABLE UNWIND => h.Release[]; h.Release[]; }; -- end ENABLE UNWIND => Unlock[mc.world]; Unlock[mc.world]; IF composite THEN RETURN[NEW[ConfigContextObj _ [ world: mc.world, worldIncarnation: mc.worldIncarnation, configIndex: config]]] ELSE RETURN[TVForRemoteGFHReferent[rgfh]]; }; } -- end world config case ELSE { IF mc.world = LocalWorld[] THEN { gfh: GlobalFrameHandle; p: PROC [LoadState.ModuleIndex] RETURNS [BOOL] = {RETURN[TRUE]}; LoadState.local.Acquire[]; [gfh: gfh] _ LoadState.local.EnumerateModulesInConfig[mc.configIndex, p ! UNWIND => LoadState.local.Release[]]; LoadState.local.Release[]; RETURN[TVForGFHReferent[gfh]]; } ELSE { gfh: GlobalFrameHandle; rgfh: RemoteGlobalFrameHandle _ nilRemoteGlobalFrameHandle; Lock[mc.world]; { ENABLE UNWIND => Unlock[mc.world]; h: LoadState.Handle = WorldVM.Loadstate[mc.world]; p: PROC [LoadState.ModuleIndex] RETURNS [BOOL] = {RETURN[TRUE]}; h.Acquire[]; [gfh: gfh] _ h.EnumerateModulesInConfig[mc.configIndex, p ! UNWIND => h.Release[]]; h.Release[]; }; -- end ENABLE UNWIND => Unlock[mc.world]; Unlock[mc.world]; rgfh _ [mc.world, mc.worldIncarnation, LOOPHOLE[gfh]]; RETURN[TVForRemoteGFHReferent[rgfh]]; }; }; ENDCASE => ERROR AMTypes.Error[reason: notImplemented]; }; 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 = LoadState.nullConfig THEN RETURN[NIL]; IF mc.world = LocalWorld[] THEN { nextIsIt: BOOL _ FALSE; composite: BOOL; config: LoadState.ConfigID; gfh: GlobalFrameHandle; LoadState.local.Acquire[]; { ENABLE UNWIND => LoadState.local.Release[]; p: PROC [config: LoadState.ConfigID] RETURNS [BOOL] = { IF nextIsIt THEN RETURN[TRUE]; IF config = mc.configIndex THEN nextIsIt _ TRUE; RETURN[FALSE]; }; q: PROC [LoadState.ModuleIndex] RETURNS [BOOL] = {RETURN[TRUE]}; config _ LoadState.local.EnumerateConfigs[newestFirst, p]; IF config = LoadState.nullConfig THEN {LoadState.local.Release[]; RETURN[NIL]}; composite _ IsComposite[LoadState.local.ConfigInfo[config].bcd]; [gfh: gfh] _ LoadState.local.EnumerateModulesInConfig[config, q]; }; LoadState.local.Release[]; IF composite THEN RETURN[NEW[ConfigContextObj _ [ world: mc.world, worldIncarnation: mc.worldIncarnation, configIndex: config]]] ELSE RETURN[TVForGFHReferent[gfh]]; } ELSE { nextIsIt: BOOL _ FALSE; composite: BOOL; config: LoadState.ConfigID; gfh: GlobalFrameHandle; Lock[mc.world]; { ENABLE UNWIND => Unlock[mc.world]; h: LoadState.Handle = WorldVM.Loadstate[mc.world]; h.Acquire[]; { ENABLE UNWIND => h.Release[]; p: PROC [config: LoadState.ConfigID] RETURNS [BOOL] = { IF nextIsIt THEN RETURN[TRUE]; IF config = mc.configIndex THEN nextIsIt _ TRUE; RETURN[FALSE]; }; q: PROC [LoadState.ModuleIndex] RETURNS [BOOL] = {RETURN[TRUE]}; config _ h.EnumerateConfigs[newestFirst, p]; IF config = LoadState.nullConfig THEN {h.Release[]; WorldVM.Unlock[mc.world]; RETURN[NIL]}; composite _ IsRemoteBCDComposite[mc.world, h.ConfigInfo[config].bcd]; IF NOT composite THEN [gfh: gfh] _ h.EnumerateModulesInConfig[config, q]; }; h.Release[]; }; -- end ENABLE UNWIND => Unlock[mc.world]; Unlock[mc.world]; IF composite THEN RETURN[NEW[ConfigContextObj _ [ world: mc.world, worldIncarnation: mc.worldIncarnation, configIndex: config]]] ELSE { rgfh: RemoteGlobalFrameHandle _ [mc.world, mc.worldIncarnation, LOOPHOLE[gfh]]; RETURN[TVForRemoteGFHReferent[rgfh]]; }; }; }; tv: RefTVRec => { SELECT TVType[tv] FROM gfhType => IF IsRemote[tv] THEN { -- remote case world: World = GetWorld[tv]; WorldVM.Lock[world]; { ENABLE UNWIND => WorldVM.Unlock[world]; h: LoadState.Handle = WorldVM.Loadstate[world]; h.Acquire[]; { ENABLE UNWIND => h.Release[]; gfh: GlobalFrameHandle = LOOPHOLE[RemoteGFHFromTV[tv].gfh]; config: LoadState.ConfigID _ h.GlobalFrameToModule[gfh].config; IF IsRemoteBCDComposite[world, h.ConfigInfo[config].bcd] THEN { nextGFH: GlobalFrameHandle; rgfh: RemoteGlobalFrameHandle _ nilRemoteGlobalFrameHandle; lastWasIt: BOOL _ FALSE; q: PROC [mx: LoadState.ModuleIndex] RETURNS [stop: BOOL _ FALSE] = { mgfh: GlobalFrameHandle; copies: LoadState.CopiesList; [gfh: mgfh, copies: copies] _ h.ModuleInfo[config, mx]; IF lastWasIt THEN {nextGFH _ mgfh; RETURN[TRUE]}; IF gfh = mgfh THEN {IF copies = NIL THEN {lastWasIt _ TRUE; RETURN[FALSE]} ELSE {nextGFH _ copies.first; RETURN[TRUE]}} ELSE IF copies # NIL THEN { FOR x: LoadState.CopiesList _ copies, x.rest UNTIL x = NIL DO IF lastWasIt THEN {nextGFH _ x.first; RETURN[TRUE]}; IF x.first = gfh THEN lastWasIt _ TRUE; ENDLOOP; }; }; nextModule: LoadState.ModuleIndex _ h.EnumerateModulesInConfig[config, q].module; rgfh _ [world, CurrentIncarnation[world], LOOPHOLE[nextGFH]]; ans _ IF nextModule = LoadState.nullModule THEN NIL ELSE TVForRemoteGFHReferent[rgfh]; } ELSE { -- not a composite config lastWasIt: BOOL _ FALSE; p: PROC [ci: LoadState.ConfigID] RETURNS [BOOL] = { IF lastWasIt THEN RETURN[TRUE]; IF ci = config THEN lastWasIt _ TRUE; RETURN[FALSE]; }; nextConfig: LoadState.ConfigID _ h.EnumerateConfigs[newestFirst, p]; IF nextConfig = LoadState.nullConfig THEN ans _ NIL ELSE { r: PROC [LoadState.ModuleIndex] RETURNS [BOOL] = {RETURN[TRUE]}; IF IsRemoteBCDComposite[world, h.ConfigInfo[nextConfig].bcd] THEN { ans _ NEW[ConfigContextObj _ [world: world, worldIncarnation: CurrentIncarnation[world], configIndex: nextConfig]]; } ELSE ans _ TVForRemoteGFHReferent [[ world, CurrentIncarnation[world], LOOPHOLE[h.EnumerateModulesInConfig[nextConfig, r].gfh]]]; }; }; }; -- end ENABLE UNWIND => h.Release[] h.Release[]; }; -- end ENABLE UNWIND => WorldVM.Unlock[world]; WorldVM.Unlock[world]; } ELSE { -- local case LoadState.local.Acquire[]; { ENABLE UNWIND => LoadState.local.Release[]; gfh: GlobalFrameHandle = GFHFromTV[tv]; config: LoadState.ConfigID _ LoadState.local.GlobalFrameToModule[gfh].config; IF IsComposite[LoadState.local.ConfigInfo[config].bcd] THEN { nextGFH: GlobalFrameHandle; lastWasIt: BOOL _ FALSE; q: PROC [mx: LoadState.ModuleIndex] RETURNS [stop: BOOL _ FALSE] = { mgfh: GlobalFrameHandle; copies: LoadState.CopiesList; [gfh: mgfh, copies: copies] _ LoadState.local.ModuleInfo[config, mx]; IF lastWasIt THEN {nextGFH _ mgfh; RETURN[TRUE]}; IF gfh = mgfh THEN { IF copies = NIL THEN {lastWasIt _ TRUE; RETURN[FALSE]} ELSE {nextGFH _ copies.first; RETURN[TRUE]}} ELSE IF copies # NIL THEN { FOR x: LoadState.CopiesList _ copies, x.rest UNTIL x = NIL DO IF lastWasIt THEN {nextGFH _ x.first; RETURN[TRUE]}; IF x.first = gfh THEN lastWasIt _ TRUE; ENDLOOP; }; }; nextModule: LoadState.ModuleIndex _ LoadState.local.EnumerateModulesInConfig[config, q].module; ans _ IF nextModule = LoadState.nullModule THEN NIL ELSE TVForGFHReferent[nextGFH]; } ELSE { -- not a composite config lastWasIt: BOOL _ FALSE; p: PROC [ci: LoadState.ConfigID] RETURNS [BOOL] = { IF lastWasIt THEN RETURN[TRUE]; IF ci = config THEN lastWasIt _ TRUE; RETURN[FALSE]; }; nextConfig: LoadState.ConfigID _ LoadState.local.EnumerateConfigs[newestFirst, p]; IF nextConfig = LoadState.nullConfig THEN ans _ NIL ELSE { r: PROC [LoadState.ModuleIndex] RETURNS [BOOL] = {RETURN[TRUE]}; IF IsComposite[LoadState.local.ConfigInfo[nextConfig].bcd] THEN { ans _ NEW[ConfigContextObj _ [ world: LocalWorld[], worldIncarnation: CurrentIncarnation[LocalWorld[]], configIndex: nextConfig]]; } ELSE ans _ TVForGFHReferent [ LoadState.local.EnumerateModulesInConfig[nextConfig, r].gfh]; }; }; }; -- end ENABLE UNWIND => LoadState.local.Release[] LoadState.local.Release[]; }; ENDCASE => ERROR AMTypes.Error[reason: typeFault, type: TVType[tv]]; }; ENDCASE => ERROR; }; -- end NextSiblingContext Imports: PUBLIC PROC [context: Context] RETURNS [ans: LIST OF PartialInterfaceInstance _ NIL] = { WITH context SELECT FROM mc: ConfigContext => { bcd: BcdDefs.BcdBase; ftb: Table.Base; AcquireIR: PROC [imph: BcdDefs.IMPHandle, impi: BcdDefs.IMPIndex] RETURNS [stop: BOOL _ FALSE] = { type: Type; seIndex: SymbolIndex; stb: SymbolTableBase _ AcquireSTB[ 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: BOOL] = { IF ISEPublic[stb, isei] THEN {seIndex _ ISEType[stb, isei]; RETURN[TRUE]} ELSE RETURN[FALSE]; }; IF NOT EnumerateCtxIseis[stb: stb, ctx: STBDirectoryCtx[stb], proc: p ! UNWIND => ReleaseSTB[stb]] THEN {ReleaseSTB[stb]; ERROR}; type _ AcquireType[stb: stb, seIndex: seIndex ! UNWIND => ReleaseSTB[stb]]; ReleaseSTB[stb]; ans _ CONS[[ir: GetInterfaceRecordFromType[type, mc.world], usingList: NIL], ans]; -- NOTE }; IF mc.configIndex = LoadState.nullConfig THEN RETURN[NIL]; IF mc.world # LocalWorld[] THEN { Lock[mc.world]; { ENABLE UNWIND => Unlock[mc.world]; h: LoadState.Handle = WorldVM.Loadstate[mc.world]; h.Acquire[]; { ENABLE UNWIND => h.Release[]; bcd _ h.ConfigInfo[mc.configIndex].bcd; IF bcd = NIL THEN ERROR; bcd _ AcquireRemoteBCD[mc.world, mc.worldIncarnation, bcd]; IF bcd = NIL THEN ERROR; }; -- end ENABLE UNWIND => h.Release[]; h.Release[]; { 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 => ... ReleaseRemoteBCD ... ReleaseRemoteBCD[bcd]; }; -- end ENABLE UNWIND => Unlock[mc.world]; Unlock[mc.world]; } ELSE { -- local case LoadState.local.Acquire[]; bcd _ LoadState.local.ConfigInfo[mc.configIndex].bcd; LoadState.local.Release[]; 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 => { bcd: BcdDefs.BcdBase = RTSymbolsPrivate.AcquireBCDFromVersion [versionStamp: IF IsRemote[tv] THEN RemoteGFHToVersionStamp[RemoteGFHFromTV[tv]] ELSE GFHToVersionStamp[GFHFromTV[tv]], shortFileNameHint: Rope.Concat[TVToName[tv], ".bcd"] ]; ftb: Table.Base = LOOPHOLE[bcd + bcd.ftOffset]; AcquireIR: PROC [imph: BcdDefs.IMPHandle, impi: BcdDefs.IMPIndex] RETURNS [stop: BOOL _ FALSE] = { type: Type; seIndex: SymbolIndex; stb: SymbolTableBase _ AcquireSTB [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: BOOL] = { IF ISEPublic[stb, isei] THEN {seIndex _ ISEType[stb, isei]; RETURN[TRUE]} ELSE RETURN[FALSE]; }; IF NOT EnumerateCtxIseis[stb: stb, ctx: STBDirectoryCtx[stb], proc: p ! UNWIND => ReleaseSTB[stb]] THEN {ReleaseSTB[stb]; ERROR}; type _ AcquireType[stb: stb, seIndex: seIndex ! UNWIND => ReleaseSTB[stb]]; ReleaseSTB[stb]; ans _ CONS[[ir: GetInterfaceRecordFromType[type, GetWorld[tv]], usingList: NIL], ans]; }; IF IsComposite[bcd] THEN {RTSymbolsPrivate.ReleaseBCD[bcd]; ERROR};--disaster [] _ BcdOps.ProcessImports[bcd, AcquireIR ! UNWIND => RTSymbolsPrivate.ReleaseBCD[bcd]]; RTSymbolsPrivate.ReleaseBCD[bcd]; }; ENDCASE => ERROR AMTypes.Error[reason: typeFault, type: TVType[tv]]; }; ENDCASE => ERROR; }; Exports: PUBLIC PROC [context: Context] RETURNS [ans: LIST OF PartialInterfaceInstance _ NIL] = { WITH context SELECT FROM mc: ConfigContext => { bcd: BcdDefs.BcdBase; ftb: Table.Base; AcquireIR: PROC [exph: BcdDefs.EXPHandle, expi: BcdDefs.EXPIndex] RETURNS [stop: BOOL _ FALSE] = { type: Type; seIndex: SymbolIndex; stb: SymbolTableBase _ AcquireSTB [ 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: BOOL] = { IF ISEPublic[stb, isei] THEN {seIndex _ ISEType[stb, isei]; RETURN[TRUE]} ELSE RETURN[FALSE]; }; IF NOT EnumerateCtxIseis[stb: stb, ctx: STBDirectoryCtx[stb], proc: p ! UNWIND => ReleaseSTB[stb]] THEN {ReleaseSTB[stb]; ERROR}; type _ AcquireType[stb: stb, seIndex: seIndex ! UNWIND => ReleaseSTB[stb]]; ReleaseSTB[stb]; ans _ CONS[[ir: GetInterfaceRecordFromType[type, mc.world], usingList: NIL], ans]; }; IF mc.configIndex = LoadState.nullConfig THEN { FOR irNames: LIST OF ROPE _ GetInterfaceRecordNames[mc.world], irNames.rest UNTIL irNames = NIL DO ans _ CONS[[ir: GetInterfaceRecord[irNames.first, mc.world], usingList: NIL], ans]; ENDLOOP; RETURN; }; IF mc.world # LocalWorld[] THEN { Lock[mc.world]; { ENABLE UNWIND => Unlock[mc.world]; h: LoadState.Handle = WorldVM.Loadstate[mc.world]; h.Acquire[]; { ENABLE UNWIND => h.Release[]; bcd _ h.ConfigInfo[mc.configIndex].bcd; IF bcd = NIL THEN ERROR; bcd _ AcquireRemoteBCD[mc.world, mc.worldIncarnation, bcd]; IF bcd = NIL THEN ERROR; }; -- end ENABLE UNWIND => h.Release[]; h.Release[]; { 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 => ... ReleaseRemoteBCD ... ReleaseRemoteBCD[bcd]; }; -- end ENABLE UNWIND => Unlock[mc.world]; Unlock[mc.world]; } ELSE { -- local case LoadState.local.Acquire[]; bcd _ LoadState.local.ConfigInfo[mc.configIndex].bcd; LoadState.local.Release[]; 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 => { bcd: BcdDefs.BcdBase = RTSymbolsPrivate.AcquireBCDFromVersion [ versionStamp: IF IsRemote[tv] THEN RemoteGFHToVersionStamp[RemoteGFHFromTV[tv]] ELSE GFHToVersionStamp[GFHFromTV[tv]], shortFileNameHint: Rope.Concat[TVToName[tv], ".bcd"]]; ftb: Table.Base = LOOPHOLE[bcd + bcd.ftOffset]; AcquireIR: PROC [exph: BcdDefs.EXPHandle, expi: BcdDefs.EXPIndex] RETURNS [stop: BOOL _ FALSE] = { type: Type; seIndex: SymbolIndex; stb: SymbolTableBase _ AcquireSTB [ 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: BOOL] = { IF ISEPublic[stb, isei] THEN {seIndex _ ISEType[stb, isei]; RETURN[TRUE]} ELSE RETURN[FALSE]; }; IF NOT EnumerateCtxIseis[stb: stb, ctx: STBDirectoryCtx[stb], proc: p ! UNWIND => ReleaseSTB[stb]] THEN {ReleaseSTB[stb]; ERROR}; type _ AcquireType[stb: stb, seIndex: seIndex ! UNWIND => ReleaseSTB[stb]]; ReleaseSTB[stb]; ans _ CONS[[ir: GetInterfaceRecordFromType[type, GetWorld[tv]], usingList: NIL], ans]; }; IF IsComposite[bcd] THEN {RTSymbolsPrivate.ReleaseBCD[bcd]; ERROR};--disaster [] _ BcdOps.ProcessExports[bcd, AcquireIR ! UNWIND => RTSymbolsPrivate.ReleaseBCD[bcd]]; RTSymbolsPrivate.ReleaseBCD[bcd]; }; ENDCASE => ERROR AMTypes.Error[reason: typeFault, type: TVType[tv]]; }; ENDCASE => ERROR; }; StripExtension: PROC [name: ROPE] RETURNS [ROPE] = { RETURN[Rope.Substr[base: name, start: 0, len: Rope.SkipTo[s: name, pos: 0, skip: "."]]]; }; IsComposite: PROC [bcd: BcdDefs.BcdBase] RETURNS [BOOL] = {RETURN[bcd.nConfigs # 0]}; IsRemoteBCDComposite: PROC [world: World, bcd: BcdDefs.BcdBase] RETURNS [BOOL] = { RETURN[WorldVM.Read[world, LOOPHOLE[@bcd.nConfigs, WorldVM.Address]] # 0]; }; BcdNameToRope: PROC [bcd: BcdDefs.BcdBase, n: BcdDefs.NameRecord] RETURNS [ROPE] = { ssb: BcdDefs.NameString = LOOPHOLE[bcd + bcd.ssOffset]; ssd: ConvertUnsafe.SubString _ [base: @ssb.string, offset: n, length: ssb.size[n]]; RETURN[ConvertUnsafe.SubStringToRope[ssd]]; }; RemoteGFHToVersionStamp: PROC [gfh: RemoteGlobalFrameHandle] RETURNS [version: BcdDefs.VersionStamp _ BcdDefs.NullVersion] = { mx: LoadState.ModuleIndex; config: LoadState.ConfigID; bcd: BcdDefs.BcdBase; ftb: Table.Base; h: LoadState.Handle; FindModuleVersion: PROC [mth: BcdDefs.MTHandle, mti: BcdDefs.MTIndex] RETURNS [stop: BOOL _ FALSE] = { IF mx IN [mth.gfi .. mth.gfi + mth.ngfi) THEN { version _ IF mth.file = BcdDefs.FTSelf THEN bcd.version ELSE ftb[mth.file].version; RETURN[TRUE]; }; }; IF gfh = nilRemoteGlobalFrameHandle THEN RETURN; h _ WorldVM.Loadstate[gfh.world]; h.Acquire[]; { ENABLE UNWIND => h.Release[]; [config, mx] _ h.GlobalFrameToModule[LOOPHOLE[gfh.gfh]]; IF config = LoadState.nullConfig THEN {h.Release[]; RETURN}; bcd _ AcquireRemoteBCD[gfh.world, gfh.worldIncarnation, h.ConfigInfo[config].bcd]; { ENABLE UNWIND => ReleaseRemoteBCD[bcd]; ftb _ LOOPHOLE[bcd + bcd.ftOffset]; [] _ BcdOps.ProcessModules[bcd, FindModuleVersion]; }; -- end ENABLE UNWIND => ReleaseRemoteBCD[bcd]; ReleaseRemoteBCD[bcd]; }; -- end ENABLE UNWIND => h.Release[]; h.Release[]; }; GFHToVersionStamp: PROC [gfh: PrincOps.GlobalFrameHandle] RETURNS [version: BcdDefs.VersionStamp _ BcdDefs.NullVersion] = { mx: LoadState.ModuleIndex; config: LoadState.ConfigID; bcd: BcdDefs.BcdBase; ftb: Table.Base; FindModuleVersion: PROC [mth: BcdDefs.MTHandle, mti: BcdDefs.MTIndex] RETURNS [stop: BOOL _ FALSE] = { IF mx IN [mth.gfi .. mth.gfi + mth.ngfi) THEN { version _ IF mth.file = BcdDefs.FTSelf THEN bcd.version ELSE ftb[mth.file].version; RETURN[TRUE]; }; }; IF gfh = NIL THEN RETURN; LoadState.local.Acquire[]; { ENABLE UNWIND => LoadState.local.Release[]; [config, mx] _ LoadState.local.GlobalFrameToModule[gfh]; IF config = LoadState.nullConfig THEN {LoadState.local.Release[]; RETURN}; bcd _ LoadState.local.ConfigInfo[config].bcd; ftb _ LOOPHOLE[bcd + bcd.ftOffset]; [] _ BcdOps.ProcessModules[bcd, FindModuleVersion]; }; -- end ENABLE UNWIND => LoadState.local.Release[]; LoadState.local.Release[]; }; ProgPCToFGI: PUBLIC PROC [prog: AMTypes.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 => ReleaseSTB[stb]; 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 => ReleaseSTB[stb]; ReleaseSTB[stb]; }; StatementContextToFGI: PROC [sc: StatementContext] RETURNS [ans: FGIndex _ FGNull] = { prog: REF prog SectionObj _ NIL; bcd: BcdDefs.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[GFHFromTV[c]] ELSE bcd _ GetRemoteBCD[RemoteGFHFromTV[c]]; { ENABLE UNWIND => IF NOT local THEN ReleaseRemoteBCD[bcd]; mth: BcdDefs.MTHandle; stb: SymbolTableBase; GetModule: PROC [mth: BcdDefs.MTHandle, mti: BcdDefs.MTIndex] RETURNS [BOOL] = {RETURN[TRUE]}; [mth,] _ BcdOps.ProcessModules[bcd, GetModule]; IF mth = NIL THEN ERROR; stb _ AcquireSTBFromSGI[bcd: bcd, sgi: mth.sseg]; { ENABLE UNWIND => ReleaseSTB[stb]; 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 => ReleaseSTB[stb]; ReleaseSTB[stb]; }; -- end ENABLE UNWIND => ... ReleaseRemoteBCD; IF NOT local THEN ReleaseRemoteBCD[bcd]; }; -- end StatementContextToFGI }. AMModelContextImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Russ Atkinson, April 18, 1985 12:24:38 pm PST "h.EnumerateAllModules[oldestFirst," _ "h.EnumerateAllModules[newestFirst," Last Modified On October 18, 1983 2:12 pm By Paul Rovner "h.EnumerateAllModules[newestFirst," _ "h.EnumerateAllModules[oldestFirst," Last Modified On December 8, 1983 8:38 am By Paul Rovner TYPEs either binder output bundle for a config, or compiler output bundle for a prog module, DEFs module, proc, or statement PROCs dealing with Contexts (loadstate entries, global or local frames, statements, IR instances) a "rootContext" represents a Loadstate. Immediate children are the Contexts of loadstate configs for individually loaded program modules and bound configs. SectionName with instance info 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. here to look for a named config or a module of a config RRA: In all cases where we do not already have the name we should fill in the name. If we get an AMTypes.Error when trying to execute the caller's proc we just go on to the next frame. an enumerator. Like MostRecentNamedContext, but gets 'em all. start HERE param to creator of context world => NIL model => world prog => model proc => prog statement => proc world -> model or prog (TV for a global frame) model -> prog proc -> statement model -> model or prog (TV for a global frame) prog -> model or prog returns NIL if nomore ... dealing with PartialInterfaceInstances Implemented only for loadstate entries and global frames sharing gets top level imports from the loadstate, via the minimodel. Encapsulation awaits the modeller. single module bcd NOTE interface modules import stuff. Implemented only for loadstate entries and global frames; sharing! gets top level imports from the loadstate, via the minimodel; Encapsulation awaits the modeller. single module bcd Private Procedures start RemoteGFHToVersionStamp here start GFHToVersionStamp here now compute the epi and the relative pc [local frame, PC] => FGIndex (wrt prog module bcd) now compute the epi and the relative pc Ê-K– "cedar" style˜codešœ™Kšœ Ïmœ1™<™-KšœK™K—šœ8™8KšœK™K—Kšœ8™8—K˜šÏk ˜ Kšœ žœï˜ýKšœ žœK˜\Kšœžœ,˜9Kšœžœžœ„˜®Kšœžœ@žœ˜QKšœžœž˜«KšœžœB˜NKšœžœ˜1Kšžœžœ ˜Kšœ žœñ˜€Kšœ žœ˜+Kšœžœ˜/Kšœžœ"˜;Kšœžœžœ5˜EKšœ žœZ˜lKšœ žœe˜vKšœ žœa˜pKšœžœ%˜;Kšœžœ ˜KšœžœL˜fKšœ žœ˜*Kšœžœ˜Kšœžœi˜v—K˜šœžœÏc˜9Kšžœ,žœª˜ßKšžœ˜KšœžœÀ˜È—™šœ™Kšœv™vKšœ žœžœ ˜Kšœ žœžœ˜%—™Kšœžœžœžœ˜-Kšœžœžœ˜,šœžœžœ˜"Kšœ ˜ Kšœ˜Kšœžœ˜Kšœžœžœ˜—Kšœžœžœžœ˜:Kšœ#žœ˜'K™—Kšœa™aK˜šÏn œžœžœžœ˜=Kšœ›™›Kšžœ žœžœ˜1šžœžœ˜šœ˜Kšœ-˜-Kšœ&˜&——Kšœ˜—K˜š  œžœžœžœ ˜@šžœ žœž˜Kšœžœ ˜*šœ˜šžœ&˜(Kšžœžœ˜Kšžœžœ˜——šœ˜šžœ ž˜Kšœ žœ˜Kšœ žœ˜Kšžœžœ ˜—Kšœ˜—Kšžœžœ'˜7—Kšœ˜—K˜š  œžœžœžœ ˜@šžœ žœž˜Kšœžœ˜:Kšœžœ ˜&Kšžœžœ˜%—Kšœ˜—K™š   œžœžœžœžœžœ˜IKšœ™Kš žœ žœžœžœžœ˜"šžœ žœž˜šœ˜šœžœ˜Kšœ%˜%Kšœ žœžœ*˜W—Kšœ˜—šœ˜šžœ ž˜šœ ˜ šœ žœ˜šžœ˜Kšžœžœžœ˜0Kšžœžœžœ˜'——Kšœ%žœ˜/Kšœžœ6˜>Kšœ˜—šœ ˜ šœžœ˜šžœ˜Kšžœžœžœ˜.Kšžœžœžœ˜&——šœ/žœ˜8Kšœžœ˜—Kšœžœ4˜˜HKšœ˜——Kšœ˜—šœ˜šžœ˜šžœ˜Kšœ˜Kšžœ'žœžœžœ˜:Kšœ˜šœ/˜/Kšœžœ#˜+—Kšœ˜Kšžœžœžœžœ˜šœžœ ˜šœB˜BKšœ˜Kšœ˜——Kšœ˜—šžœ˜Kšœ˜Kšžœ'žœžœžœ˜:Kšœ˜šœžœžœ˜$Kšœ2˜2Kšœ ˜ šœžœžœ˜šœ˜KšœB˜B——Kšœ˜Kšœ ˜ Kšœ˜—Kšœ˜Kšžœžœžœžœ˜šœžœžœ˜)Kšœžœ˜ŠKšœ˜—Kšœ˜Kšœ˜———Kšžœžœ'˜7—Kšœ˜—K™š  œžœžœžœ˜CKšœ ™ Kšœ™Kšœ ™ Kšœ ™ Kšœ™šžœ žœž˜Kšœžœ˜0šœ˜šžœ&˜(Kšžœžœžœ˜šžœŸ0˜6šžœžœ˜Kšœ^˜^————šœ˜šžœ ž˜šœ ˜ K˜Kšœ˜šžœžœ ˜šžœ˜Kšœ0˜0Kšœ˜Kšœ5˜5Kšœ˜Kšœ˜—šžœŸ˜Kšœ4˜4Kšœ ˜ šœžœžœ˜!Kšœ/˜/Kšœ ˜ šœžœ ˜-Kšœžœ˜ —Kšœ ˜ KšœŸ&˜*—Kšœ˜Kšœ˜——šžœžœ˜Kšœ ˜ Kšœ*˜*Kšœ˜—K˜—Kšœ žœ˜#Kšžœžœ4˜D—Kšœ˜—Kšžœžœ'˜7—Kšœ˜—K™š œžœžœžœ žœžœžœžŸœ˜‘Kšœ.™.Kšœ ™ Kšœ™šžœ?˜BKšžœžœžœžœ žœžœžœ˜4—Kšœ˜—K˜š œžœžœ˜Ešžœ žœž˜KšœŸžœžœŸ#˜Išœ˜šžœ ž˜Kšœ žœžœ,˜@Kšœ žœžœ˜Kšžœžœ4˜D——šœ˜šžœ&˜(šžœ˜šžœ˜šžœ˜Kšœ˜Kšœ˜Kšœ žœ˜Kšœ˜šœžœžœ˜-Kšœ˜Kš œžœ-žœžœžœžœ˜TKšœC˜CKšœ@˜@Kšœ6˜6Kšžœžœžœžœ˜KšœŸ.˜2—Kšœ˜šžœ ˜ šž˜šžœžœ˜Kšœ˜Kšœ&˜&Kšœ˜——Kšžœžœ˜#—Kšœ˜—šžœŸ˜Kšœ˜Kšœ˜Kšœ;˜;Kšœ žœ˜Kšœ˜šœžœžœ˜$Kšœ2˜2Kšœ ˜ šœžœžœ˜Kšœ˜Kš œžœ-žœžœžœžœ˜TKšœ5˜5KšœE˜EKšœ(˜(Kšžœžœžœžœ˜Kšœ'žœ˜6KšœŸ ˜$—Kšœ ˜ KšœŸ)˜-—Kšœ˜šžœ ˜ šžœžœžœ˜$Kšœ˜Kšœ&˜&Kšœ˜—Kšžœžœ˜*—Kšœ˜——KšœŸ˜—šžœ˜Kšžœ˜šžœ˜Kšœ˜Kš œžœžœžœžœžœ˜@Kšœ˜šœG˜GKšœžœ˜'—Kšœ˜Kšžœ˜Kšœ˜—šžœ˜Kšœ˜Kšœ;˜;Kšœ˜šœžœžœ˜$Kšœ2˜2Kš œžœžœžœžœžœ˜@Kšœ ˜ šœ9˜9Kšœžœ˜—Kšœ ˜ KšœŸ)˜-—Kšœ˜Kšœ'žœ˜6Kšžœ˜%Kšœ˜—Kšœ˜———Kšžœžœ'˜7—Kšœ˜—K™š œžœžœžœ˜MKšœ.™.Kšœ™Kšœ™Kš žœ žœžœžœžœ˜"šžœ žœž˜KšœžœžœŸ˜6šœ˜Kšžœ'žœžœžœ˜:Kšžœ˜šžœ˜Kšœ žœžœ˜Kšœ žœ˜Kšœ˜Kšœ˜Kšœ˜šœžœžœ˜-šœžœžœžœ˜7Kšžœ žœžœžœ˜Kšžœžœ žœ˜0Kšžœžœ˜Kšœ˜—Kš œžœžœžœžœžœ˜@Kšœ:˜:šžœ˜ Kšžœžœžœ˜.—Kšœ@˜@KšœA˜AKšœ˜—Kšœ˜šžœ ˜ šžœžœžœ˜$Kšœ˜Kšœ&˜&Kšœ˜—Kšžœžœ˜#—Kšœ˜—šžœ˜Kšœ žœžœ˜Kšœ žœ˜Kšœ˜Kšœ˜Kšœ˜šœžœžœ˜$Kšœ2˜2Kšœ ˜ šœžœžœ˜šœžœžœžœ˜7Kšžœ žœžœžœ˜Kšžœžœ žœ˜0Kšžœžœ˜Kšœ˜—Kš œžœžœžœžœžœ˜@Kšœ,˜,šžœ˜ Kšžœ)žœžœ˜:—KšœE˜EKšžœžœ žœ4˜IKšœ˜—Kšœ ˜ KšœŸ)˜-—Kšœ˜šžœ ˜ šžœžœžœ˜$Kšœ˜Kšœ&˜&Kšœ˜—šžœ˜šœ˜Kšœ"žœ˜1—Kšžœ˜%K˜——Kšœ˜—Kšœ˜—šœ˜šžœ ž˜šœ ˜ Kšžœ ˜šžœŸ˜K˜K˜šœžœžœ˜)Kšœ/˜/K˜ šœžœžœ˜Kšœžœ˜;Kšœ?˜?šžœ7žœ˜?Kšœ˜Kšœ;˜;Kšœ žœžœ˜š œžœžœžœžœ˜DKšœž˜Kšœ˜Kšœžœ˜7Kš žœ žœ žœžœžœ˜1šžœ ž˜šœžœ ž˜Kšžœžœžœžœ˜&Kšžœžœžœ˜,——šžœžœ žœžœ˜šžœ*žœž˜:šž˜Kš žœ žœ žœ žœžœ˜4Kšžœžœ žœ˜'—Kšžœ˜—K˜—Kšœ˜—šœ#˜#Kšœ-˜-—Kšœ*žœ ˜=šœžœ#žœž˜3Kšœžœ˜#—Kšœ˜—šžœŸ˜!Kšœ žœžœ˜šœžœžœžœ˜3Kšžœ žœžœžœ˜Kšžœ žœ žœ˜%Kšžœžœ˜K˜—šœ ˜ Kšœ#˜#—šžœ#žœž˜3šžœ˜šœžœžœžœ˜0Kšœžœžœ˜—šžœ;žœ˜Cšœžœ˜Kšœ˜Kšœ-˜-Kšœ˜—K˜—šžœ˜!šœ ˜ Kšœ˜Kšžœ2˜:——Kšœ˜——Kšœ˜——KšœŸ#˜'K˜ —KšœŸ.˜2Kšœ˜Kšœ˜—šžœŸ ˜K˜šœžœžœ˜-Kšœ'˜'KšœM˜Mšžœ5žœ˜=Kšœ˜Kšœ žœžœ˜š œžœžœžœžœ˜DKšœž˜Kšœ˜Kšœžœ'˜EKš žœ žœ žœžœžœ˜1šžœ ˜ šžœ˜šžœ ž˜Kšžœžœžœžœ˜&Kšžœžœžœ˜,——šžœžœ žœžœ˜šžœ*žœž˜=Kš žœ žœ žœ žœžœ˜4Kšžœžœ žœ˜'Kšžœ˜—K˜——Kšœ˜—šœ#˜#Kšœ;˜;—šœžœ#žœž˜3Kšœžœ˜ —Kšœ˜—šžœŸ˜!Kšœ žœžœ˜šœžœžœžœ˜3Kšžœ žœžœžœ˜Kšžœ žœ žœ˜%Kšžœžœ˜K˜—šœ ˜ Kšœ1˜1—šžœ#žœž˜3šžœ˜Kš œžœžœžœžœžœžœ˜@šžœ9žœ˜Ašœžœ˜Kšœ˜Kšœ3˜3Kšœ˜—K˜—šžœ˜Kšœ=˜=—Kšœ˜——Kšœ˜—KšœŸ1˜5—K˜Kšœ˜——Kšžœžœ4˜D—Kšœ˜—Kšžœžœ˜—KšœŸ˜—K™š œžœžœžœžœžœžœ˜aKšœ*™*Kšœ@™@šžœ žœž˜šœ˜Kšœ˜Kšœ˜š  œžœ2˜AKšžœžœžœ˜ Kšœ ˜ Kšœ˜šœ˜šœ ˜ šœ˜Kšœ˜Kšœ3˜3Kšœ-˜-———šœžœ-žœžœ˜Lšžœ˜Kš žœ žœžœžœžœžœ˜E—Kšœ˜—šžœžœ?˜EKšœžœ˜Kšžœžœ˜—Kšœ0žœ˜KKšœ˜Kšœžœ1Ÿœ žœ Ÿ˜[Kšœ˜—Kšžœ'žœžœžœ˜:šžœžœ˜!Kšœ˜šœžœžœ˜$Kšœ2˜2Kšœ ˜ šœžœžœ˜ Kšœ'˜'Kšžœžœžœžœ˜Kšœ;˜;Kšžœžœžœžœ˜—KšœŸ$˜(Kšœ ˜ šœžœžœ˜*Kšœžœ˜#Kš žœžœžœžœŸ ˜DKšœ+˜+—KšœŸ0˜4Kšœ˜—KšœŸ)˜-Kšœ˜Kšœ˜—šžœŸ ˜Kšœ˜Kšœ5˜5Kšœ˜Kšœžœ˜#Kš žœžœžœžœŸ ˜DKšœ+˜+Kšœ˜—Kšœ˜—šœ˜šžœ ž˜šœ ˜ Kšœa™ašœ=˜=šœ˜šžœžœ-˜AKšžœ"˜&——Kšœ5˜5Kšœ˜—Kšœžœ˜/Kš  œžœ2˜Ašžœžœžœ˜ Kšœ ˜ Kšœ˜šœ!˜!šœ˜Kšœ˜Kšœ3˜3Kšœ*˜*Kšœ˜—Kšœ˜—šœžœ-žœžœ˜Lšžœ˜Kšžœ žœžœ˜1Kšžœžœžœ˜—Kšœ˜—šžœžœ?˜EKšœžœ˜Kšžœžœ˜—Kšœ0žœ˜KKšœ˜Kšœžœ5Ÿœ žœ˜VKšœ˜—Kšžœžœ$žœŸ ˜MKšœ™šœ)˜)Kšœžœ&˜.—Kšœ!˜!Kšœ˜—Kšžœžœ4˜D—Kšœ$™$Kšœ˜—Kšžœžœ˜—Kšœ˜—K™š œžœžœžœžœžœžœ˜aKšœC™Cšžœ žœž˜šœ˜Kšœ˜Kšœ˜š   œžœ2žœžœžœ˜bKšœ ˜ Kšœ˜šœ#˜#šœ˜Kšœ˜Kšœ2˜2Kšœ,˜,——šœžœ-žœžœ˜Lšžœ˜Kšžœ žœžœ˜1Kšžœžœžœ˜—Kšœ˜—šžœžœ?˜EKšœžœ˜Kšžœžœ˜—Kšœ0žœ˜KKšœ˜Kšœžœ1Ÿœ žœ˜RKšœ˜—šžœ&žœ˜/šžœ žœžœžœ2˜KKšžœ žœž˜Kšœžœ>žœ˜SKšžœ˜—Kšžœ˜K˜—šžœžœ˜!Kšœ˜šœžœžœ˜$Kšœ2˜2Kšœ ˜ šœžœžœ˜ Kšœ'˜'Kšžœžœžœžœ˜Kšœ;˜;Kšžœžœžœžœ˜—KšœŸ$˜(Kšœ ˜ šœžœžœ˜*Kšœžœ˜#Kš žœžœžœžœŸ ˜DKšœ+˜+—KšœŸ0˜4Kšœ˜—KšœŸ)˜-Kšœ˜Kšœ˜šžœŸ ˜Kšœ˜Kšœ5˜5Kšœ˜Kšœžœ˜#Kš žœžœžœžœŸ ˜DKšœ+˜+Kšœ˜——Kšœ˜—šœ˜šžœ ž˜šœ ˜ Kšœa™ašœ?˜?šœ ˜ šžœ ˜Kšžœ-˜1Kšžœ"˜&——Kšœ7˜7—Kšœžœ˜/š  œžœ2˜AKšžœžœžœ˜ Kšœ ˜ Kšœ˜šœ#˜#šœ˜Kšœ˜Kšœ2˜2Kšœ,˜,——šœžœ,žœžœ˜Lšžœ˜Kšžœ žœžœ˜1Kšžœžœžœ˜—Kšœ˜—šžœžœ?˜EKšœžœ˜Kšžœžœ˜—Kšœ0žœ˜KKšœ˜KšœžœAžœ˜VKšœ˜—Kšžœžœ$žœŸ ˜MKšœ™šœ)˜)Kšœžœ&˜.—Kšœ!˜!Kšœ˜—Kšžœžœ4˜D—Kšœ˜—Kšžœžœ˜—Kšœ˜—K™—šœ™K™š  œžœžœžœžœ˜4KšžœR˜XKšœ˜—K˜Kš   œžœžœžœžœ˜UK˜š œžœ&žœžœ˜RKšžœžœ'˜JKšœ˜—K˜š  œžœ/žœžœ˜UKšœžœ˜7KšœS˜SKšžœ%˜+Kšœ˜—K˜š œžœžœ:˜~Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜š  œžœ.žœžœžœ˜fšžœžœ žœ˜/Kšœ žœžœ žœ˜SKšžœžœ˜ Kšœ˜—Kšœ˜—Kšœ"™"Kšžœ"žœžœ˜0Kšœ!˜!Kšœ ˜ šœžœžœ˜ Kšœ%žœ ˜8Kšžœžœžœ˜=KšœS˜Sšœžœžœ˜*Kšœžœ˜#Kšœ4˜4KšœŸœŸ˜3—Kšœ˜KšœŸ%˜)—Kšœ ˜ Kšœ˜—K˜š œžœ"žœ:˜{Kšœ˜Kšœ˜Kšœ˜Kšœ˜š  œžœ.žœžœžœ˜fšžœžœ!žœ˜/Kšœ žœžœ žœ˜SKšžœžœ˜ Kšœ˜—Kšœ˜—Kšœ™Kšžœžœžœžœ˜Kšœ˜šœžœžœ˜.Kšœ8˜8Kšžœžœžœ˜KKšœ.˜.Kšœžœ˜#Kšœ4˜4KšœŸ3˜7—Kšœ˜Kšœ˜—K˜š   œžœžœžŸœžœ˜sKšœ˜šžœ˜Kšžœ5˜9Kšžœ*˜.—šœžœžœ˜#Kšœ'™'Kšœžœ˜ Kšœ˜šžœ˜Kšžœ`˜dKšžœO˜S—Kšœ&˜&KšœŸ(˜,—Kšœ˜Kšœ˜—K™š œžœžœ˜VKšœ2™2Kšœžœžœ˜ Kšœ˜Kšœ˜Kšœ ˜ Kšœžœžœ˜Kšžœžœžœ˜>Kšœ˜Kšœžœ˜!Kšœ˜šžœ˜Kšžœ ˜$Kšžœ(˜,—š œžœžœžœžœžœ˜;Kšœ˜Kšœ˜Kš  œžœ/žœžœžœžœžœ˜_Kšœ/˜/Kšžœžœžœžœ˜Kšœ1˜1šœžœžœ˜#Kšœ'™'Kšœ:˜:Kšœžœ˜ Kšœ˜šžœ˜šžœ2˜6KšœF˜F—šžœ&˜*Kšœ=˜=——Kšœ&˜&KšœŸ(˜,—Kšœ˜KšœŸ-˜1—Kšžœžœžœ˜(KšœŸ˜ ——K˜Kšœ˜K˜K˜K˜—…—HÄ“