<> <> <> <> DIRECTORY AMBridge USING [TVForGFHReferent, TVForRemoteGFHReferent, GFHFromTV, RemoteGFHFromTV, GetWorld, RemoteGlobalFrameHandle, nilRemoteGlobalFrameHandle], AMMiniModel USING [AcquireIRType], AMModel USING [Class, Source, SourceObj, CharIndex], AMModelPrivate USING [FGIndex, FGNull, EPI, EPIToFirstFGI, GetModuleSTB, EPIToLastFGI, FGIToFirstChar, FGIToLastChar, FGIToEPI, NextFGI, SectionRec, RefTVRec, GetLocalBCD, GetRemoteBCD], AMTypes USING [TVType, Error, TVToName, TV], BcdDefs USING [MTIndex, NameRecord, BcdBase, MTHandle, NameString, VersionStamp, ModuleIndex], BcdOps USING [ProcessModules], BrandXSymbolDefs USING[BodyIndex, rootBodyIndex, nullBodyIndex, SymbolTableBase, FineGrainTableHeader], BrandYSymbolDefs USING[BodyIndex, rootBodyIndex, nullBodyIndex, SymbolTableBase, FineGrainTableHeader], ConvertUnsafe USING [ToRope, SubStringToRope, SubString], IO USING [PutR, card], LoadState USING [local, Acquire, Release, Handle, ConfigInfo, ModuleToGlobalFrame, ConfigID, GlobalFrameToModule], PrincOps USING [wordsPerPage, GlobalFrameHandle], Rope USING [ROPE, Concat], RTSymbolDefs USING [SymbolTableBase, SymbolTableHandle], RTSymbolOps USING [AcquireRope, AcquireType, STBSourceVersion], RTSymbols USING [AcquireSTB, ReleaseSTB, GetSTHForModule], RTSymbolsPrivate USING [AcquireBCDFromVersion, ReleaseBCD], RTTypesRemotePrivate USING [AcquireRemoteBCD, ReleaseRemoteBCD], SafeStorage USING [Type], Table USING [Base], WorldVM USING [World, Lock, Unlock, LocalWorld, Loadstate, CurrentIncarnation, Incarnation]; AMModelSectionImpl: PROGRAM IMPORTS AMBridge, AMMiniModel, AMModelPrivate, AMTypes, BcdOps, ConvertUnsafe, IO, LoadState, Rope, RTSymbolOps, RTSymbols, RTSymbolsPrivate, RTTypesRemotePrivate, WorldVM EXPORTS AMModel = { OPEN AMBridge, AMMiniModel, AMTypes, bx: BrandXSymbolDefs, by: BrandYSymbolDefs, PrincOps, Rope, AMModel, AMModelPrivate, RTSymbolDefs, RTSymbolOps, RTSymbols, RTTypesRemotePrivate, WorldVM; <> <> <> Section: TYPE = REF SectionObj; SectionObj: PUBLIC TYPE = SectionRec; <> SectionClass: PUBLIC PROC [section: Section] RETURNS [Class] = { RETURN[section.class]; }; SectionName: PUBLIC PROC [section: Section] RETURNS [ans: ROPE _ NIL] = { WITH s: section SELECT FROM model => RETURN[s.configName]; prog => RETURN[s.moduleName]; interface => RETURN[s.moduleName]; proc => IF s.procTV # NIL THEN RETURN[TVToName[s.procTV]] ELSE { sth: SymbolTableHandle = GetSTHForModule [ stamp: s.prog.versionStamp, fileName: Rope.Concat[s.prog.moduleName, ".bcd"], moduleName: s.prog.moduleName]; stb: SymbolTableBase _ AcquireSTB[sth]; FindProcX: PROC [bti: bx.BodyIndex] RETURNS [stop: BOOLEAN _ FALSE] = { xstb: bx.SymbolTableBase = NARROW[stb, SymbolTableBase.x].e; WITH b: xstb.bb[bti] SELECT FROM Callable => IF ~b.inline AND b.entryIndex = s.entryPointIndex THEN {ans _ AcquireRope[stb, [x[xstb.seb[b.id].hash]]]; RETURN[TRUE]}; ENDCASE}; FindProcY: PROC [bti: by.BodyIndex] RETURNS [stop: BOOLEAN _ FALSE] = { ystb: by.SymbolTableBase = NARROW[stb, SymbolTableBase.y].e; WITH b: ystb.bb[bti] SELECT FROM Callable => IF ~b.inline AND b.entryIndex = s.entryPointIndex THEN {ans _ AcquireRope[stb, [y[ystb.seb[b.id].hash]]]; RETURN[TRUE]}; ENDCASE}; WITH stb SELECT FROM t: SymbolTableBase.x => IF t.e.EnumerateBodies[bx.rootBodyIndex, FindProcX ! UNWIND => ReleaseSTB[stb]] = bx.nullBodyIndex THEN {ReleaseSTB[stb]; ERROR}; t: SymbolTableBase.y => IF t.e.EnumerateBodies[by.rootBodyIndex, FindProcY ! UNWIND => ReleaseSTB[stb]] = by.nullBodyIndex THEN {ReleaseSTB[stb]; ERROR}; ENDCASE => ERROR; ReleaseSTB[stb]; RETURN[ans]}; -- figure it out from the ep# and the prog section statement => RETURN[Rope.Concat[Rope.Concat[s.prog.moduleName, "."], IO.PutR[IO.card[s.fgtIndex.fgCard]]]] ENDCASE => ERROR }; SectionSource: PUBLIC PROC [section: Section] RETURNS [ans: Source] = { <> WITH s: section SELECT FROM model => { name: ROPE _ NIL; version: BcdDefs.VersionStamp; IF s.configContext # NIL THEN { <> IF s.configContext.world = LocalWorld[] THEN { bcd: BcdDefs.BcdBase; LoadState.local.Acquire[]; { ENABLE UNWIND => LoadState.local.Release[]; bcd _ LoadState.local.ConfigInfo[s.configContext.configIndex].bcd; }; -- end ENABLE UNWIND => LoadState.local.Release[]; LoadState.local.Release[]; name _ BcdNameToRope[bcd, bcd.source]; version _ bcd.sourceVersion; } ELSE { world: World = s.configContext.world; Lock[world]; { ENABLE UNWIND => Unlock[world]; h: LoadState.Handle = WorldVM.Loadstate[world]; h.Acquire[]; { ENABLE UNWIND => h.Release[]; bcd: BcdDefs.BcdBase = AcquireRemoteBCD[ world: world, incarnation: CurrentIncarnation[world], bcd: h.ConfigInfo[s.configContext.configIndex].bcd]; IF bcd = NIL THEN ERROR AMTypes.Error[reason: noSymbols]; { ENABLE UNWIND => ReleaseRemoteBCD[bcd]; name _ BcdNameToRope[bcd, bcd.source]; version _ bcd.sourceVersion; }; -- end ENABLE UNWIND => ReleaseRemoteBCD[bcd]; ReleaseRemoteBCD[bcd]; }; -- end ENABLE UNWIND => h.Release[]; h.Release[]; }; -- end ENABLE UNWIND => Unlock[world]; Unlock[world]; } } ELSE { <> bcd: BcdDefs.BcdBase = RTSymbolsPrivate.AcquireBCDFromVersion [ versionStamp: s.versionStamp, shortFileNameHint: Rope.Concat[s.configName, ".bcd"]]; IF bcd = NIL THEN ERROR AMTypes.Error[reason: noSymbols]; name _ BcdNameToRope[bcd, bcd.source]; version _ bcd.sourceVersion; RTSymbolsPrivate.ReleaseBCD[bcd]; }; ans _ NEW[SourceObj _ [fileName: name, class: model, versionStamp: version, sourceRange: entire[]]]; }; prog => { <> name: ROPE _ NIL; version: BcdDefs.VersionStamp; IF s.someGFHTV = NIL THEN { <> bcd: BcdDefs.BcdBase = RTSymbolsPrivate.AcquireBCDFromVersion [ versionStamp: s.versionStamp, shortFileNameHint: Rope.Concat[s.moduleName, ".bcd"]]; IF bcd = NIL THEN ERROR AMTypes.Error[reason: noSymbols]; name _ BcdNameToRope[bcd, bcd.source]; version _ bcd.sourceVersion; RTSymbolsPrivate.ReleaseBCD[bcd]} ELSE { <> ptv: TV = s.someGFHTV; world: World _ GetWorld[ptv]; IF world = LocalWorld[] THEN { bcd: BcdDefs.BcdBase = GetLocalBCD[GFHFromTV[ptv]]; stb: SymbolTableBase _ GetModuleSTB[bcd, s.versionStamp]; { ENABLE UNWIND => ReleaseSTB[stb]; name _ STB2Source[stb]; version _ STBSourceVersion[stb]; }; -- end ENABLE UNWIND => ReleaseSTB[stb] ReleaseSTB[stb]; } ELSE { <> bcd: BcdDefs.BcdBase _ GetRemoteBCD[RemoteGFHFromTV[ptv]]; { ENABLE UNWIND => ReleaseRemoteBCD[bcd]; stb: SymbolTableBase _ GetModuleSTB[bcd, s.versionStamp]; { ENABLE UNWIND => ReleaseSTB[stb]; name _ STB2Source[stb]; version _ STBSourceVersion[stb]; }; -- end ENABLE UNWIND => ReleaseSTB[stb] ReleaseSTB[stb]; }; -- end ENABLE UNWIND => ... FREE[@bcd]; ReleaseRemoteBCD[bcd]; } }; ans _ NEW[SourceObj _ [fileName: name, class: prog, versionStamp: version, sourceRange: entire[]]]; }; interface => { <> bcd: BcdDefs.BcdBase = RTSymbolsPrivate.AcquireBCDFromVersion [ versionStamp: s.versionStamp, shortFileNameHint: Rope.Concat[s.moduleName, ".bcd"]]; IF bcd = NIL THEN ERROR AMTypes.Error[reason: noSymbols]; ans _ NEW[SourceObj _ [fileName: BcdNameToRope[bcd, bcd.source], class: interface, versionStamp: bcd.sourceVersion, sourceRange: entire[]]]; RTSymbolsPrivate.ReleaseBCD[bcd]; }; proc => { nSect: REF proc SectionObj _ NARROW[section]; fci: INT; lci: INT; name: ROPE _ NIL; version: BcdDefs.VersionStamp; [firstCI: fci, lastCI: lci] _ ProcToInfo[nSect]; IF s.prog.someGFHTV = NIL THEN { bcd: BcdDefs.BcdBase = RTSymbolsPrivate.AcquireBCDFromVersion [ versionStamp: s.prog.versionStamp, shortFileNameHint: Rope.Concat[s.prog.moduleName, ".bcd"]]; <> IF bcd = NIL THEN ERROR AMTypes.Error[reason: noSymbols]; name _ BcdNameToRope[bcd, bcd.source]; version _ bcd.sourceVersion; RTSymbolsPrivate.ReleaseBCD[bcd]} ELSE { <> ptv: TV = s.prog.someGFHTV; world: World _ GetWorld[ptv]; IF world = LocalWorld[] THEN { bcd: BcdDefs.BcdBase = GetLocalBCD[GFHFromTV[ptv]]; stb: SymbolTableBase _ GetModuleSTB[bcd, s.prog.versionStamp]; { ENABLE UNWIND => ReleaseSTB[stb]; name _ STB2Source[stb]; version _ STBSourceVersion[stb]; }; -- end ENABLE UNWIND => ReleaseSTB[stb] ReleaseSTB[stb]; } ELSE { bcd: BcdDefs.BcdBase _ GetRemoteBCD[RemoteGFHFromTV[ptv]]; <> { ENABLE UNWIND => ReleaseRemoteBCD[bcd]; stb: SymbolTableBase _ GetModuleSTB[bcd, s.prog.versionStamp]; { ENABLE UNWIND => ReleaseSTB[stb]; name _ STB2Source[stb]; version _ STBSourceVersion[stb]; }; -- end ENABLE UNWIND => ReleaseSTB[stb] ReleaseSTB[stb]; }; -- end ENABLE UNWIND => ... FREE[@bcd]; ReleaseRemoteBCD[bcd]; } }; ans _ NEW[SourceObj _ [fileName: name, class: proc, versionStamp: version, sourceRange: field[firstCharIndex: fci, lastCharIndex: lci]]]; }; statement => { nSect: REF statement SectionObj _ NARROW[section]; fci: INT; lci: INT; name: ROPE _ NIL; version: BcdDefs.VersionStamp; [firstCI: fci, lastCI: fci] _ StatementToInfo[nSect]; IF s.prog.someGFHTV = NIL THEN { <> bcd: BcdDefs.BcdBase = RTSymbolsPrivate.AcquireBCDFromVersion [ versionStamp: s.prog.versionStamp, shortFileNameHint: Rope.Concat[s.prog.moduleName, ".bcd"]]; IF bcd = NIL THEN ERROR AMTypes.Error[reason: noSymbols]; name _ BcdNameToRope[bcd, bcd.source]; version _ bcd.sourceVersion; RTSymbolsPrivate.ReleaseBCD[bcd]} ELSE { <> ptv: TV = s.prog.someGFHTV; world: World _ GetWorld[ptv]; IF world = LocalWorld[] THEN { bcd: BcdDefs.BcdBase = GetLocalBCD[GFHFromTV[ptv]]; stb: SymbolTableBase _ GetModuleSTB[bcd, s.prog.versionStamp]; { ENABLE UNWIND => ReleaseSTB[stb]; name _ STB2Source[stb]; version _ STBSourceVersion[stb]; }; -- end ENABLE UNWIND => ReleaseSTB[stb] ReleaseSTB[stb]; } ELSE { <> bcd: BcdDefs.BcdBase _ GetRemoteBCD[RemoteGFHFromTV[ptv]]; { ENABLE UNWIND => ReleaseRemoteBCD[bcd]; stb: SymbolTableBase _ GetModuleSTB[bcd, s.prog.versionStamp]; { ENABLE UNWIND => ReleaseSTB[stb]; name _ STB2Source[stb]; version _ STBSourceVersion[stb]; }; -- end ENABLE UNWIND => ReleaseSTB[stb] ReleaseSTB[stb]; }; -- end ENABLE UNWIND => ... FREE[@bcd]; ReleaseRemoteBCD[bcd]; } }; ans _ NEW[SourceObj _ [fileName: name, class: statement, versionStamp: version, sourceRange: field[firstCharIndex: fci, lastCharIndex: lci]]]; }; ENDCASE => ERROR }; SectionParams: PUBLIC PROC [section: Section] RETURNS [list: LIST OF SafeStorage.Type _ NIL] = { <> <<(DIRECTORY entries)>> <> WITH s: section SELECT FROM model => ERROR; --NOTE enumerate the directory entries; prog => ERROR; --NOTE enumerate the directory entries; interface => ERROR; --NOTE enumerate the directory entries; proc => ERROR AMTypes.Error[reason: notImplemented]; statement => ERROR AMTypes.Error[reason: notImplemented]; ENDCASE => ERROR }; ParentSection: PUBLIC PROC [section: Section] RETURNS [Section] = { <> <> <> WITH s: section SELECT FROM proc => RETURN[s.prog]; statement => RETURN[NEW[SectionObj _ [proc[prog: s.prog, entryPointIndex: StatementToInfo[NARROW[section]].epi ]]]]; ENDCASE => ERROR AMTypes.Error[reason: notImplemented]; }; -- end ParentSections <> SectionChildren: PUBLIC PROC [section: Section, proc: PROC [Section] RETURNS [stop: BOOL]] RETURNS [ans: Section _ NIL--NIL if not stopped--] = { x: INT _ 0; NextSection: PROC [parent, child: Section] RETURNS [s: Section _ NIL] = { [s, x] _ NextSiblingSection[parent: parent, child: child, indexInParent: x]}; FOR s: Section _ FirstChildSection[section], NextSection[section, s] UNTIL s = NIL DO IF proc[s] THEN RETURN[s]; ENDLOOP; }; <> FirstChildSection: PROC [section: Section] RETURNS [ans: Section] = { WITH s: section SELECT FROM model => IF s.configContext # NIL THEN { IF s.configContext.world = LocalWorld[] THEN { <
> bcd: BcdDefs.BcdBase; ftb: Table.Base; mth: BcdDefs.MTHandle; p: PROC [mth: BcdDefs.MTHandle, mti: BcdDefs.MTIndex] RETURNS [BOOL] = {RETURN[TRUE]}; LoadState.local.Acquire[]; bcd _ LoadState.local.ConfigInfo[s.configContext.configIndex].bcd; IF bcd = NIL THEN {LoadState.local.Release[]; ERROR AMTypes.Error[reason: noSymbols]}; ftb _ LOOPHOLE[bcd + bcd.ftOffset]; mth _ BcdOps.ProcessModules[bcd, p].mth; ans _ NEW [SectionObj _ [prog[moduleName: BcdNameToRope[bcd, mth.name], versionStamp: ftb[mth.file].version, someGFHTV: NARROW [TVForGFHReferent [LoadState.local.ModuleToGlobalFrame [s.configContext.configIndex, mth.gfi] ] ] ] ] ]; LoadState.local.Release[]; RETURN; } ELSE { <
> world: World = s.configContext.world; cx: LoadState.ConfigID = s.configContext.configIndex; moduleName: ROPE; v: BcdDefs.VersionStamp; mx: BcdDefs.ModuleIndex; Lock[world]; { ENABLE UNWIND => Unlock[world]; incarnation: Incarnation _ CurrentIncarnation[world]; rgfh: GlobalFrameHandle; newState: LoadState.Handle = WorldVM.Loadstate[world]; newState.Acquire[]; { ENABLE UNWIND => newState.Release[]; bcd: BcdDefs.BcdBase = AcquireRemoteBCD[ world: world, incarnation: CurrentIncarnation[world], bcd: newState.ConfigInfo[cx].bcd]; IF bcd = NIL THEN ERROR AMTypes.Error[reason: noSymbols]; { ENABLE UNWIND => ReleaseRemoteBCD[bcd]; ftb: Table.Base = LOOPHOLE[bcd + bcd.ftOffset]; p: PROC [mth: BcdDefs.MTHandle, mti: BcdDefs.MTIndex] RETURNS [BOOL] = {RETURN[TRUE]}; mth: BcdDefs.MTHandle = BcdOps.ProcessModules[bcd, p].mth; v _ ftb[mth.file].version; moduleName _ BcdNameToRope[bcd, mth.name]; mx _ mth.gfi; }; -- end ENABLE UNWIND => ReleaseRemoteBCD[bcd] ReleaseRemoteBCD[bcd]; rgfh _ newState.ModuleToGlobalFrame[cx, mx]; }; -- end ENABLE UNWIND => newState.Release[] newState.Release[]; ans _ NEW[SectionObj _ [prog[moduleName: moduleName, versionStamp: v, someGFHTV: NARROW[TVForRemoteGFHReferent[[world: world, worldIncarnation: incarnation, gfh: LOOPHOLE[rgfh]]]] ]]]; }; -- end ENABLE UNWIND => Unlock[world]; Unlock[world]; RETURN; } } ELSE { <> bcd: BcdDefs.BcdBase = RTSymbolsPrivate.AcquireBCDFromVersion [ versionStamp: s.versionStamp, shortFileNameHint: Rope.Concat[s.configName, ".bcd"]]; ftb: Table.Base; mth: BcdDefs.MTHandle; p: PROC [mth: BcdDefs.MTHandle, mti: BcdDefs.MTIndex] RETURNS [BOOLEAN] = { RETURN[TRUE]}; IF bcd = NIL THEN ERROR AMTypes.Error[reason: noSymbols]; ftb _ LOOPHOLE[bcd + bcd.ftOffset]; mth _ BcdOps.ProcessModules[bcd, p].mth; ans _ NEW[SectionObj _ [prog[moduleName: BcdNameToRope [bcd, mth.name], versionStamp: ftb[mth.file].version, someGFHTV: NIL]]]; RTSymbolsPrivate.ReleaseBCD[bcd]; }; prog => RETURN[NEW[SectionObj _ [proc[prog: NARROW[section, REF prog SectionObj], entryPointIndex: 0]]]]; --ep# wizardry: StartProc. interface => RETURN[NIL]; proc => RETURN[NEW[SectionObj _ [statement[prog: s.prog, fgtIndex: ProcToInfo [NARROW[section]].fgi]]]]; statement => RETURN[NIL]; ENDCASE => ERROR }; -- end FirstChildSection NextSiblingSection: PROC [parent, child: Section, indexInParent: INT _ 0] RETURNS [ans: Section _ NIL, newIndexInParent: INT _ 0] = { <> <> <> <> IF parent = NIL THEN RETURN[NIL]; WITH s: child SELECT FROM model => ERROR AMTypes.Error[reason: notImplemented]; prog => { lastWasOldChild: BOOL _ FALSE; ftb: Table.Base _ NIL; FindNextModule: PROC [mth: BcdDefs.MTHandle, mti: BcdDefs.MTIndex] RETURNS [stop: BOOL _ FALSE] = { newIndexInParent _ newIndexInParent + 1; IF lastWasOldChild THEN RETURN[TRUE]; IF (indexInParent = 0 OR newIndexInParent >= indexInParent) AND s.versionStamp = ftb[mth.file].version THEN lastWasOldChild _ TRUE; }; IF s.someGFHTV # NIL THEN { <> world: World = GetWorld[s.someGFHTV]; IF world = LocalWorld[] THEN { gfh: GlobalFrameHandle _ NIL; bcd: BcdDefs.BcdBase; mth: BcdDefs.MTHandle; LoadState.local.Acquire[]; { ENABLE UNWIND => LoadState.local.Release[]; config: LoadState.ConfigID = LoadState.local.GlobalFrameToModule [GFHFromTV[s.someGFHTV]].config; bcd _ LoadState.local.ConfigInfo[config].bcd; ftb _ LOOPHOLE[bcd + bcd.ftOffset]; mth _ BcdOps.ProcessModules[bcd, FindNextModule].mth; IF mth # NIL THEN gfh _ LoadState.local.ModuleToGlobalFrame[config, mth.gfi]; }; -- ENABLE UNWIND => LoadState.local.Release[]; LoadState.local.Release[]; IF gfh # NIL THEN ans _ NEW [SectionObj _ [prog[moduleName: BcdNameToRope[bcd, mth.name], versionStamp: ftb[mth.file].version, someGFHTV: NARROW[TVForGFHReferent[gfh]] ]]]; } ELSE { <> Lock[world]; { ENABLE UNWIND => Unlock[world]; v: BcdDefs.VersionStamp; moduleName: ROPE; rgfh: RemoteGlobalFrameHandle _ nilRemoteGlobalFrameHandle; h: LoadState.Handle = WorldVM.Loadstate[world]; h.Acquire[]; { ENABLE UNWIND => h.Release[]; config: LoadState.ConfigID = h.GlobalFrameToModule [LOOPHOLE[RemoteGFHFromTV[s.someGFHTV].gfh]].config; bcd: BcdDefs.BcdBase = GetRemoteBCD[RemoteGFHFromTV[s.someGFHTV]]; IF bcd = NIL THEN ERROR; ftb _ LOOPHOLE[bcd + bcd.ftOffset]; { ENABLE UNWIND => ReleaseRemoteBCD[bcd]; mth: BcdDefs.MTHandle = BcdOps.ProcessModules[bcd, FindNextModule].mth; IF mth # NIL THEN {gfh: GlobalFrameHandle = h.ModuleToGlobalFrame[config, mth.gfi]; v _ ftb[mth.file].version; moduleName _ BcdNameToRope[bcd, mth.name]; rgfh _ [world, CurrentIncarnation[world], LOOPHOLE[gfh]]}; }; -- ENABLE UNWIND => ReleaseRemoteBCD[bcd]; ReleaseRemoteBCD[bcd]; }; -- ENABLE UNWIND => h.Release[]; h.Release[]; IF rgfh # nilRemoteGlobalFrameHandle THEN ans _ NEW [SectionObj _ [prog[moduleName: moduleName, versionStamp: v, someGFHTV: NARROW[TVForRemoteGFHReferent[rgfh]] ]]]; }; -- ENABLE UNWIND => Unlock[world]; }; -- end ELSE } -- end case where the sections are loaded ELSE { <> <> p: REF model SectionObj = NARROW[parent]; mth: BcdDefs.MTHandle; bcd: BcdDefs.BcdBase _ RTSymbolsPrivate.AcquireBCDFromVersion [ versionStamp: p.versionStamp, shortFileNameHint: Rope.Concat[p.configName, ".bcd"]]; IF bcd = NIL THEN ERROR AMTypes.Error[reason: noSymbols]; { ENABLE UNWIND => RTSymbolsPrivate.ReleaseBCD[bcd]; ftb _ LOOPHOLE[bcd + bcd.ftOffset]; mth _ BcdOps.ProcessModules[bcd, FindNextModule].mth; IF mth # NIL THEN ans _ NEW[SectionObj _ [prog[moduleName: BcdNameToRope[bcd, mth.name], versionStamp: ftb[mth.file].version, someGFHTV: NIL]]]; }; -- end ENABLE UNWIND => RTSymbolsPrivate.ReleaseBCD[bcd]; RTSymbolsPrivate.ReleaseBCD[bcd]; }}; -- end prog child case of NextSiblingSection interface => ERROR AMTypes.Error[reason: notImplemented]; proc => { sth: SymbolTableHandle = GetSTHForModule [ stamp: s.prog.versionStamp, fileName: Rope.Concat[s.prog.moduleName, ".bcd"], moduleName: s.prog.moduleName]; stb: SymbolTableBase _ AcquireSTB[sth]; maxEI: EPI _ 0; GetMaxX: PROC [bti: bx.BodyIndex] RETURNS [stop: BOOL _ FALSE] = { WITH NARROW[stb, SymbolTableBase.x].e.bb[bti] SELECT FROM Callable => IF ~inline THEN maxEI _ MAX[maxEI, entryIndex]; ENDCASE}; GetMaxY: PROC [bti: by.BodyIndex] RETURNS [stop: BOOL _ FALSE] = { WITH NARROW[stb, SymbolTableBase.y].e.bb[bti] SELECT FROM Callable => IF ~inline THEN maxEI _ MAX[maxEI, entryIndex]; ENDCASE}; WITH stb SELECT FROM t: SymbolTableBase.x => [] _ t.e.EnumerateBodies[bx.rootBodyIndex, GetMaxX]; t: SymbolTableBase.y => [] _ t.e.EnumerateBodies[by.rootBodyIndex, GetMaxY]; ENDCASE => ERROR; IF s.entryPointIndex = maxEI THEN ans _ NIL ELSE ans _ NEW[SectionObj _ [proc[prog: NARROW[parent, REF prog SectionObj], entryPointIndex: s.entryPointIndex + 1]]]; ReleaseSTB[stb]}; -- end proc child case of NextSiblingSection statement => { nextFGI: FGIndex = StatementToInfo[NARROW[child, REF statement SectionObj]].nextFgi; IF nextFGI = FGNull THEN RETURN[NIL] ELSE RETURN[NEW[SectionObj _ [statement[prog: NARROW[parent, REF proc SectionObj].prog, fgtIndex: nextFGI]]]]; }; -- end statement child case of NextSiblingSection ENDCASE => ERROR }; -- end NextSiblingSection SectionType: PUBLIC PROC [section: Section] RETURNS [type: SafeStorage.Type] = { <> WITH s: section SELECT FROM model => ERROR AMTypes.Error[reason: notImplemented]; prog => ERROR AMTypes.Error[reason: notImplemented]; interface => RETURN[AcquireIRType[defsName: s.moduleName, version: s.versionStamp]]; proc => IF s.procTV = NIL THEN { sth: SymbolTableHandle = GetSTHForModule [ stamp: s.prog.versionStamp, fileName: Rope.Concat[s.prog.moduleName, ".bcd"], moduleName: s.prog.moduleName]; stb: SymbolTableBase _ AcquireSTB[sth]; FindProcX: PROC [bti: bx.BodyIndex] RETURNS [stop: BOOLEAN _ FALSE] = { WITH b: NARROW[stb, SymbolTableBase.x].e.bb[bti] SELECT FROM Callable => IF ~b.inline AND b.entryIndex = s.entryPointIndex THEN {type _ AcquireType[stb, [x[b.ioType]]]; RETURN[TRUE]}; ENDCASE}; FindProcY: PROC [bti: by.BodyIndex] RETURNS [stop: BOOLEAN _ FALSE] = { WITH b: NARROW[stb, SymbolTableBase.y].e.bb[bti] SELECT FROM Callable => IF ~b.inline AND b.entryIndex = s.entryPointIndex THEN {type _ AcquireType[stb, [y[b.ioType]]]; RETURN[TRUE]}; ENDCASE}; WITH stb SELECT FROM t: SymbolTableBase.x => IF t.e.EnumerateBodies[bx.rootBodyIndex, FindProcX ! UNWIND => ReleaseSTB[stb]] = bx.nullBodyIndex THEN {ReleaseSTB[stb]; ERROR}; t: SymbolTableBase.y => IF t.e.EnumerateBodies[by.rootBodyIndex, FindProcY ! UNWIND => ReleaseSTB[stb]] = by.nullBodyIndex THEN {ReleaseSTB[stb]; ERROR}; ENDCASE => ERROR; ReleaseSTB[stb]; RETURN[type]} -- figure it out from the ep# and the prog section ELSE RETURN[TVType[s.procTV]]; statement => ERROR AMTypes.Error[reason: notImplemented]; ENDCASE => ERROR }; SectionVersion: PUBLIC PROC [section: Section] RETURNS [BcdDefs.VersionStamp] = { WITH s: section SELECT FROM model => RETURN[s.versionStamp]; prog => RETURN[s.versionStamp]; interface => RETURN[s.versionStamp]; proc => RETURN[s.prog.versionStamp]; statement => RETURN[s.prog.versionStamp]; ENDCASE => ERROR; }; <> 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]]}; ProcToInfo: PROC [proc: REF proc SectionObj] RETURNS [fgi: FGIndex _ FGNull, firstCI, lastCI: INT _ 0] = { <<[prog module bcd, entryPointIndex] => FGIndex>> localBCD: BOOL _ FALSE; remoteBCD: BOOL _ FALSE; versionBCD: BOOL _ FALSE; bcd: BcdDefs.BcdBase; ptv: TV = proc.prog.someGFHTV; stb: SymbolTableBase; IF ptv = NIL -- proc not loaded THEN { bcd _ RTSymbolsPrivate.AcquireBCDFromVersion [ versionStamp: proc.prog.versionStamp, shortFileNameHint: Rope.Concat[proc.prog.moduleName, ".bcd"]]; versionBCD _ TRUE} ELSE IF GetWorld[ptv] = LocalWorld[] THEN {bcd _ GetLocalBCD[GFHFromTV[ptv]]; localBCD _ TRUE} ELSE { bcd _ GetRemoteBCD[RemoteGFHFromTV[ptv]]; remoteBCD _ TRUE}; { ENABLE UNWIND => IF versionBCD THEN RTSymbolsPrivate.ReleaseBCD[bcd] ELSE IF remoteBCD THEN ReleaseRemoteBCD[bcd]; stb _ GetModuleSTB[bcd, proc.prog.versionStamp]; }; -- end ENABLE UNWIND => RTSymbolsPrivate.ReleaseBCD[bcd]; { ENABLE UNWIND => ReleaseSTB[stb]; IF versionBCD THEN RTSymbolsPrivate.ReleaseBCD[bcd] ELSE IF remoteBCD THEN ReleaseRemoteBCD[bcd]; fgi _ EPIToFirstFGI[stb, proc.entryPointIndex, TRUE]; firstCI _ FGIToFirstChar[stb, EPIToFirstFGI[stb, proc.entryPointIndex, TRUE]]; lastCI _ FGIToLastChar[stb, EPIToLastFGI[stb, proc.entryPointIndex]]; IF lastCI = firstCI THEN lastCI _ lastCI - 1; }; -- end ENABLE UNWIND => ReleaseSTB[stb]; ReleaseSTB[stb]; }; StatementToInfo: PROC [statement: REF statement SectionObj] RETURNS [epi: EPI _ 0, fgi: FGIndex _ FGNull, nextFgi: FGIndex _ FGNull, firstCI: INT _ 0, lastCI: INT _ 0] = { <<[prog module bcd, FGIndex] => entryPointIndex (maybe 0)>> localBCD: BOOL _ FALSE; remoteBCD: BOOL _ FALSE; versionBCD: BOOL _ FALSE; bcd: BcdDefs.BcdBase; ptv: TV = statement.prog.someGFHTV; stb: SymbolTableBase; IF ptv = NIL -- statement not loaded THEN { bcd _ RTSymbolsPrivate.AcquireBCDFromVersion [ versionStamp: statement.prog.versionStamp, shortFileNameHint: Rope.Concat[statement.prog.moduleName, ".bcd"]]; versionBCD _ TRUE} ELSE IF GetWorld[ptv] = LocalWorld[] THEN {bcd _ GetLocalBCD[GFHFromTV[ptv]]; localBCD _ TRUE} ELSE { bcd _ GetRemoteBCD[RemoteGFHFromTV[ptv]]; remoteBCD _ TRUE}; { ENABLE UNWIND => IF versionBCD THEN RTSymbolsPrivate.ReleaseBCD[bcd] ELSE IF remoteBCD THEN ReleaseRemoteBCD[bcd]; stb _ GetModuleSTB[bcd, statement.prog.versionStamp]; }; -- end ENABLE UNWIND => RTSymbolsPrivate.ReleaseBCD[bcd]; { ENABLE UNWIND => ReleaseSTB[stb]; IF versionBCD THEN RTSymbolsPrivate.ReleaseBCD[bcd] ELSE IF remoteBCD THEN ReleaseRemoteBCD[bcd]; fgi _ statement.fgtIndex; epi _ FGIToEPI[stb, fgi]; nextFgi _ NextFGI[stb, fgi, epi]; firstCI _ FGIToFirstChar[stb, statement.fgtIndex]; lastCI _ FGIToLastChar[stb, statement.fgtIndex]; IF lastCI = firstCI THEN lastCI _ lastCI - 1; }; -- end ENABLE UNWIND => ReleaseSTB[stb]; ReleaseSTB[stb]; }; STB2Source: PROC [stb: SymbolTableBase] RETURNS [nr: ROPE] = { RETURN [ConvertUnsafe.ToRope[ WITH stb SELECT FROM t: SymbolTableBase.x => @LOOPHOLE [ t.e.stHandle + t.e.stHandle.fgRelPgBase*wordsPerPage, LONG POINTER TO bx.FineGrainTableHeader].sourceFile, t: SymbolTableBase.y => @LOOPHOLE [ t.e.stHandle + t.e.stHandle.fgRelPgBase*wordsPerPage, LONG POINTER TO by.FineGrainTableHeader].sourceFile, ENDCASE => ERROR ]]; }; }.