DIRECTORY AMBridge USING [GetWorld, GFHFromTV, RemoteGFHFromTV], AMFiles USING [OpenIt], AMModel USING [Class, Context, Source, SourceObj, CharIndex, SourceFileName, SourceClass, ContextChildren, ContextClass, SectionVersion, SectionSource, ContextSection, MostRecentNamedContext], AMModelPrivate USING [FGIndex, FGNull, EPI, FGIToEPI, GetLocalBCD, GetRemoteBCD, CharIndexToFGI, SectionRec, RefTVRec, ConfigContext], AMTypes USING [Error, TVType, GlobalParent], BasicTime USING [ToNSTime], BcdDefs USING [VersionStamp, MTIndex, FTSelf, BcdBase, MTHandle], BcdOps USING [ProcessModules], FS USING [OpenFile, nullOpenFile, GetInfo, Close], LoadState USING [nullConfig], Rope USING [ROPE, Concat, Equal, Find, Substr, Match], RTSymbolDefs USING [SymbolTableBase, SymbolTableHandle, nullHandle, nullBase], RTSymbols USING [ReleaseSTB, AcquireSTBFromSGI, AcquireSTB, GetSTHForModule], RTSymbolsPrivate USING [AcquireBCDFromVersion, ReleaseBCD], RTTypesRemotePrivate USING [ReleaseRemoteBCD], SafeStorage USING [gfhType, fhType], Table USING [Base], WorldVM USING [LocalWorld, World]; AMModelSourceImpl: PROGRAM IMPORTS AMBridge, AMFiles, AMTypes, BasicTime, BcdOps, AMModel, AMModelPrivate, FS, LoadState, RTSymbols, Rope, RTSymbolsPrivate, RTTypesRemotePrivate, WorldVM EXPORTS AMModel, AMModelPrivate = { OPEN AMBridge, AMModel, AMModelPrivate, AMTypes, Rope, RTSymbolDefs, RTSymbols, RTTypesRemotePrivate, SafeStorage, WorldVM; Section: TYPE = REF SectionObj; SectionObj: PUBLIC TYPE = SectionRec; FileSource: PUBLIC PROC[fileName: ROPE, class: --model, prog, interface--Class] RETURNS[s: Source _ NIL] = { f: FS.OpenFile _ FS.nullOpenFile; IF class = model THEN { IF NOT Rope.Match["*.config*", fileName, FALSE] THEN fileName _ fileName.Concat[".config"]; } ELSE { IF NOT Rope.Match["*.mesa*", fileName, FALSE] THEN fileName _ fileName.Concat[".mesa"]; }; f _ AMFiles.OpenIt[fileName].openFile; IF f # FS.nullOpenFile THEN { s _ NEW[SourceObj _ [fileName: fileName, class: class, versionStamp: [0, 0, BasicTime.ToNSTime[FS.GetInfo[f].created]], sourceRange: entire[]]]; FS.Close[f]; }; }; SourceSection: PUBLIC PROC[source: Source, context: --worldRoot or model--Context] RETURNS[section: Section _ NIL, contexts: LIST OF --prog--Context _ NIL] = {SELECT SourceClass[source] FROM statement => {[section, contexts] _ SourceSection [NEW[SourceObj _ [fileName: source.fileName, class: prog, versionStamp: source.versionStamp, sourceRange: entire[]]], context]; section _ NEW[SectionObj _ [statement[prog: NARROW[section], fgtIndex: SourceToFirstFGI [source, NARROW[section]]]]]; }; proc => {[section, contexts] _ SourceSection [NEW[SourceObj _ [fileName: source.fileName, class: prog, versionStamp: source.versionStamp, sourceRange: entire[]]], context]; section _ NEW[SectionObj _ [proc[prog: NARROW[section], entryPointIndex: SourceToEPI [source, NARROW[section]]]]]; }; prog => { WITH context SELECT FROM tv: RefTVRec => {SELECT TVType[tv] FROM gfhType => { section _ ContextSection[context]; IF Rope.Equal[SourceFileName[source], SourceFileName[SectionSource[section]], FALSE] THEN contexts _ CONS[context, NIL] ELSE section _ NIL; RETURN}; fhType => {[section, contexts] _ SourceSection[source, GlobalParent[tv]]; RETURN}; ENDCASE => ERROR Error[typeFault]; }; mc: ConfigContext => {context: Context; fn: ROPE = SourceFileName[source]; i: INT _ Rope.Find[s1: fn, s2: ".", pos1: 0, case: FALSE]; mn: ROPE _ IF i = -1 THEN fn ELSE Rope.Substr[base: fn, len: i]; context _ MostRecentNamedContext[mn, mc]; IF context = NIL THEN ERROR AMTypes.Error [reason: notImplemented, msg: "Finding an object location for a source not loaded"]; section _ ContextSection[context]; contexts _ CONS[context, contexts]; IF TRUE THEN RETURN; IF mc.configIndex = LoadState.nullConfig THEN {proc: PROC[context: Context] RETURNS[stop: BOOL _ FALSE] = { IF ContextClass[context] = model THEN {s: Section; cl: LIST OF Context; [s, cl] _ SourceSection[source, context]; IF s # NIL THEN { IF section = NIL THEN section _ s ELSE {IF SectionVersion[section] # SectionVersion[s] THEN ERROR Error [reason: notImplemented, msg: "different sections for the same source"]}; UNTIL cl = NIL DO contexts _ CONS[cl.first, contexts]; cl _ cl.rest; ENDLOOP; }; RETURN}; IF Rope.Equal[SourceFileName[source], SourceFileName[SectionSource[ContextSection[context]]], FALSE] THEN {IF section = NIL THEN section _ ContextSection[context] ELSE {IF SectionVersion[ContextSection[context]] # SectionVersion[section] THEN ERROR Error[reason: notImplemented, msg: "different sections for the same source"]}; contexts _ CONS[context, contexts]; }; }; -- end proc defn [] _ ContextChildren[context, proc]; } -- end IF mc.configIndex = LoadState.nullConfig ELSE {proc: PROC[context: Context] RETURNS[stop: BOOL _ FALSE] = { IF Rope.Equal[SourceFileName[source], SourceFileName[SectionSource[ContextSection[context]]], FALSE] THEN {IF section = NIL THEN section _ ContextSection[context] ELSE {IF SectionVersion[ContextSection[context]] # SectionVersion[section] THEN ERROR Error[reason: notImplemented, msg: "different sections for the same source"]}; contexts _ CONS[context, contexts]; }; }; [] _ ContextChildren[context, proc]; }; }; ENDCASE => ERROR }; model => ERROR AMTypes.Error[ reason: notImplemented, msg: "SourceSection[model source]"]; interface => ERROR AMTypes.Error[ reason: notImplemented, msg: "SourceSection[interface source]"]; ENDCASE => ERROR}; -- end SourceSection SourceToFirstFGI: PROC[source: Source, prog: REF prog SectionObj] RETURNS[ans: FGIndex _ FGNull] = {IF prog.someGFHTV # NIL THEN -- prog loaded {world: World = GetWorld[prog.someGFHTV]; local: BOOL _ (world = LocalWorld[]); IF local THEN {bcd: BcdDefs.BcdBase = GetLocalBCD[GFHFromTV[prog.someGFHTV]]; stb: SymbolTableBase _ GetModuleSTB[bcd, prog.versionStamp]; ans _ CharIndexToFGI[stb, (WITH s: source SELECT FROM field => s.firstCharIndex ENDCASE => 0) ! UNWIND => ReleaseSTB[stb]]; ReleaseSTB[stb]} ELSE {bcd: BcdDefs.BcdBase = GetRemoteBCD[RemoteGFHFromTV[prog.someGFHTV]]; stb: SymbolTableBase _ GetModuleSTB[bcd, prog.versionStamp ! UNWIND => ReleaseRemoteBCD[bcd]]; ReleaseRemoteBCD[bcd]; ans _ CharIndexToFGI[stb, (WITH s: source SELECT FROM field => s.firstCharIndex ENDCASE => 0) ! UNWIND => ReleaseSTB[stb]]; ReleaseSTB[stb]}; } ELSE -- prog not loaded {bcd: BcdDefs.BcdBase = RTSymbolsPrivate.AcquireBCDFromVersion [versionStamp: prog.versionStamp, shortFileNameHint: Rope.Concat[prog.moduleName, ".bcd"]]; stb: SymbolTableBase _ GetModuleSTB[bcd, prog.versionStamp ! UNWIND => RTSymbolsPrivate.ReleaseBCD[bcd]]; RTSymbolsPrivate.ReleaseBCD[bcd]; ans _ CharIndexToFGI[stb, (WITH s: source SELECT FROM field => s.firstCharIndex ENDCASE => 0) ! UNWIND => ReleaseSTB[stb]]; ReleaseSTB[stb]}; }; SourceToEPI: PROC[source: Source, prog: REF prog SectionObj] RETURNS[ans: EPI _ 0] = {IF prog.someGFHTV # NIL THEN -- prog loaded {world: World = GetWorld[prog.someGFHTV]; local: BOOL _ (world = LocalWorld[]); IF local THEN {bcd: BcdDefs.BcdBase = GetLocalBCD[GFHFromTV[prog.someGFHTV]]; stb: SymbolTableBase _ GetModuleSTB[bcd, prog.versionStamp]; fgi: FGIndex _ CharIndexToFGI[stb, (WITH s: source SELECT FROM field => s.firstCharIndex ENDCASE => 0) ! UNWIND => ReleaseSTB[stb]]; ans _ FGIToEPI[stb, fgi ! UNWIND => ReleaseSTB[stb]]; ReleaseSTB[stb]; } ELSE {bcd: BcdDefs.BcdBase = GetRemoteBCD[RemoteGFHFromTV[prog.someGFHTV]]; stb: SymbolTableBase _ GetModuleSTB[bcd, prog.versionStamp ! UNWIND => ReleaseRemoteBCD[bcd]]; fgi: FGIndex; ReleaseRemoteBCD[bcd]; fgi _ CharIndexToFGI[stb, (WITH s: source SELECT FROM field => s.firstCharIndex ENDCASE => 0) ! UNWIND => ReleaseSTB[stb]]; ans _ FGIToEPI[stb, fgi ! UNWIND => ReleaseSTB[stb]]; ReleaseSTB[stb]}; } ELSE -- prog not loaded {bcd: BcdDefs.BcdBase = RTSymbolsPrivate.AcquireBCDFromVersion [versionStamp: prog.versionStamp, shortFileNameHint: Rope.Concat[prog.moduleName, ".bcd"]]; stb: SymbolTableBase _ GetModuleSTB[bcd, prog.versionStamp ! UNWIND => RTSymbolsPrivate.ReleaseBCD[bcd]]; fgi: FGIndex; RTSymbolsPrivate.ReleaseBCD[bcd]; fgi _ CharIndexToFGI[stb, (WITH s: source SELECT FROM field => s.firstCharIndex ENDCASE => 0) ! UNWIND => ReleaseSTB[stb]]; ans _ FGIToEPI[stb, fgi ! UNWIND => ReleaseSTB[stb]]; ReleaseSTB[stb]}; }; GetModuleSTB: PUBLIC PROC[bcd: BcdDefs.BcdBase, versionStamp: BcdDefs.VersionStamp] RETURNS[stb: SymbolTableBase _ nullBase] = { FindModule: PROC[mth: BcdDefs.MTHandle, mti: BcdDefs.MTIndex] RETURNS[stop: BOOLEAN _ FALSE] = {version: BcdDefs.VersionStamp _ IF mth.file = BcdDefs.FTSelf THEN bcd.version ELSE ftb[mth.file].version; IF version = versionStamp THEN {stb _ AcquireSTBFromSGI[bcd, mth.sseg]; RETURN[TRUE]}}; sth: SymbolTableHandle _ nullHandle; ftb: Table.Base = LOOPHOLE[bcd + bcd.ftOffset]; sth _ GetSTHForModule[versionStamp, NIL, NIL ! ANY => CONTINUE]; IF sth = nullHandle THEN [] _ BcdOps.ProcessModules[bcd, FindModule] ELSE stb _ AcquireSTB[sth]; }; }. ZAMModelSourceImpl.mesa Last Modified On December 12, 1983 11:12 am By Paul Rovner moduleName, configName should not be source name TYPEs either binder output bundle for a config, or compiler output bundle for a prog module, DEFs module, proc, or statement PROCs ... dealing with Source Use SourceSection to figure out (given a proc or statement source location) where to place a breakpoint. The list of prog Contexts returned by SourceSection is meaningful for prog, proc and statement sources. It will be ordered "most-recently-loaded first". Strictly speaking, a source can have multiple sections: one for each set of "SectionParams". Someday we'll accommodate such, but not this week. NOTE context = NIL oughta mean to find the section even though it's not loaded look thru all global frames in context for ones with the source name. Construct section for the first one found, thereafter check version stamp. For each found, cons onto contexts [prog module bcd, CharIndex] => FGIndex (wrt prog module bcd) [prog module bcd, CharIndex] => entryPointIndex (wrt prog module bcd) start GetModuleSTB here Ê k˜J˜Jšœ™Jšœ:™:Jšœ0™0J˜šÏk ˜ Jšœ œ(˜6Jšœœ ˜šœœ/˜˜MJšœœ%˜;Jšœœ˜.Jšœ œ˜$Jšœœ˜Jšœœ˜"J˜—šœ˜Jšœ˜˜ŸJšœ˜J˜—šœœw˜J˜—šœ™˜Jšœv™v—Jšœ œœ ˜Jšœ œœ˜%J˜—Jšœ™˜Jšœ™˜š Ïn œœœ œ Ïcœ˜OJšœ œ˜Jšœœ œ˜!šœœ˜šœœ#œ˜/Jšœ'˜+—J˜—šœ˜šœœ!œ˜-Jšœ%˜)—J˜—Jšœ&˜&šœœ ˜šœ˜šœœ ˜Jšœ˜J˜Jšœ)œ˜AJ˜—Jšœ ˜ J˜——Jšœ˜˜šœK™KJšœ™—šœE™EJšœW™W—šœ\™\Jšœ2™2—JšœN™N——šž œœœŸœ˜RJš œœ œœŸœ œ˜Jšœœ˜ ˜ ˜˜šœœ(˜,J˜ J˜"J˜J˜ ——šœ œœ ˜<˜˜Jšœ˜————J˜—˜˜˜šœœ(˜,J˜ J˜"J˜J˜ ——šœ œœ ˜7˜Jšœ œ˜———J˜—˜JšœE™EJšœJ™JJšœ"™"šœœ œ˜˜šœœ ˜˜ ˜$šœ#˜%J˜'Jšœ˜Jšœ œ œ˜"Jšœ œ˜—Jšœ˜——˜ ˜?Jšœ˜——Jšœœ˜"—J˜—˜˜Jšœœ˜"Jšœœ-œ˜:Jš œœœœœ˜@J˜)šœ ˜šœœ˜Jšœ˜Jšœ<˜<——Jšœ"˜"Jšœ œ˜#Jšœœœœ˜J˜šœ&˜(š˜š œœœœœ˜;šœœ˜"šœ ˜Jšœœœ ˜J˜)šœ˜ šœœ ˜Jšœ ˜š˜šœœ˜J˜š˜š˜˜˜J˜0——————šœ˜šœ œ˜'J˜ —Jšœ˜ —J˜——Jšœ˜—šœ#˜%J˜7Jšœ˜šœœ ˜Jšœ"˜&šœœ(˜0J˜šœ˜ ˜J˜0———Jšœ œ˜#J˜———JšœŸ˜J˜$—JšœŸ/˜2—š˜š œœœœœ˜;šœœ#˜'J˜7Jšœ˜šœœ ˜Jšœ"˜&šœœ(˜0J˜šœ˜ ˜J˜0———Jšœ œ˜#J˜——J˜J˜$—J˜———J˜—Jšœ˜—J˜—šœ˜šœ˜Jšœ˜J˜$——šœ ˜ šœ˜Jšœ˜J˜(——JšœœŸ˜(J˜J˜Jšœ=™=————šžœœœ˜AJšœ˜ šœœ˜šœŸ˜˜)Jšœœ˜%šœ˜š˜˜?J˜<˜šœœ œ˜J˜Jšœ œ˜+——J˜——šœ ˜˜F˜:Jšœœ˜#—J˜˜šœœ œ˜J˜Jšœ˜ —Jšœœ˜—J˜————J˜—šœŸ˜˜>˜!˜˜J˜ ———˜:Jšœœ&˜.—J˜!˜šœœ œ˜J˜Jšœ˜ —Jšœœ˜—J˜———J˜˜JšœE™E——š ž œœœœœ˜Tšœœ˜šœŸ˜˜)Jšœœ˜%šœ˜š˜˜?J˜<šœ$œ œ˜>J˜Jšœ œ˜+—Jšœœ˜5J˜—J˜—šœ ˜˜F˜:Jšœœ˜#—J˜ J˜šœœ œ˜5J˜Jšœ˜ Jšœœ˜—˜Jšœœ˜—J˜————J˜—šœŸ˜˜>˜!˜˜J˜ ———˜:Jšœœ&˜.—J˜ J˜!šœœ œ˜5J˜Jšœ˜ Jšœœ˜—˜Jšœœ˜—J˜———J˜J˜—šž œœœ:˜SJšœ#˜*šœž œœ-˜?Jšœœœ˜!šœ!œ˜=Jšœ œ˜,šœ˜Jšœ*œœ˜=J˜——Jšœ™J˜$Jšœœ˜/Jš œ$œœœœ˜@šœ˜Jšœ,˜0Jšœ˜——J˜J˜—J˜J˜J˜J˜—…—#1É