<> <> <> <<"h.EnumerateAllModules[oldestFirst," _ "h.EnumerateAllModules[newestFirst,">> <> <<"h.EnumerateAllModules[newestFirst," _ "h.EnumerateAllModules[oldestFirst,">> <> 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] = { < NIL>> < world>> < model>> < prog>> < proc>> 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--] = { < model or prog (TV for a global frame)>> < prog>> < statement>> 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] = { < model or prog (TV for a global frame)>> < model or prog>> <> 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] = { <<... dealing with PartialInterfaceInstances>> <> 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] = { <<[local frame, PC] => FGIndex (wrt prog module bcd)>> 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 }.