-- AMModelSourceImpl.mesa -- Last Modified On December 21, 1982 2:54 pm By Paul Rovner -- moduleName, configName should not be source name DIRECTORY AMBridge USING [GetWorld, GFHFromTV, RemoteGFHFromTV], AMModel USING [Class, Context, Source, SourceObj, CharIndex, SourceFileName, SourceClass, ContextChildren, ContextClass, SectionVersion, SectionSource, ContextSection], AMModelPrivate USING [FGIndex, FGNull, EPI, FGIToEPI, GetLocalBCD, GetRemoteBCD, CharIndexToFGI, SectionRec, RefTVRec, ConfigContext, z], AMTypes USING [Error, TVType, GlobalParent], BcdDefs USING [VersionStamp, MTIndex, FTSelf], BcdOps USING [BcdBase, MTHandle, ProcessModules], TimeStamp USING [Stamp], PilotLoadStateFormat USING [NullConfig], Rope USING [ROPE, Concat, Equal], RTSymbolDefs USING [SymbolTableBase, SymbolTableHandle, nullHandle], RTSymbols USING [ReleaseSTB, AcquireSTBFromSGI, AcquireSTB], RTSymbolsPrivate USING [AcquireBCDFromVersion, ReleaseBCD, GetSTHForModule], RTTypesBasic USING [gfhType, fhType], RTTypesRemotePrivate USING [GetRemoteGFHeader, ReleaseRemoteBCD], Table USING [Base], WorldVM USING [LocalWorld, World]; AMModelSourceImpl: PROGRAM IMPORTS AMBridge, AMTypes, BcdOps, Rope, AMModel, AMModelPrivate, RTSymbols, RTSymbolsPrivate, RTTypesRemotePrivate, WorldVM EXPORTS AMModel, AMModelPrivate = { OPEN AMBridge, AMModel, AMModelPrivate, AMTypes, PilotLoadStateFormat, Rope, RTSymbolDefs, RTSymbols, RTTypesBasic, RTTypesRemotePrivate, WorldVM; -- TYPEs -- either binder output bundle for a config, or compiler output bundle -- for a prog module, DEFs module, proc, or statement Section: TYPE = REF SectionObj; SectionObj: PUBLIC TYPE = SectionRec; -- 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 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 [z.NEW[SourceObj _ [fileName: source.fileName, class: prog, versionStamp: source.versionStamp, sourceRange: entire[]]], context]; section _ z.NEW[SectionObj _ [statement[prog: NARROW[section], fgtIndex: SourceToFirstFGI [source, NARROW[section]]]]]; }; proc => {[section, contexts] _ SourceSection [z.NEW[SourceObj _ [fileName: source.fileName, class: prog, versionStamp: source.versionStamp, sourceRange: entire[]]], context]; section _ z.NEW[SectionObj _ [proc[prog: NARROW[section], entryPointIndex: SourceToEPI [source, NARROW[section]]]]]; }; prog => -- 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 { 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 _ z.CONS[context, NIL] ELSE section _ NIL; RETURN}; fhType => {[section, contexts] _ SourceSection[source, GlobalParent[tv]]; RETURN}; ENDCASE => ERROR Error[typeFault]; }; mc: ConfigContext => {IF mc.configIndex = 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 _ z.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 _ z.CONS[context, contexts]; }; }; [] _ ContextChildren[context, proc]; } 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 _ z.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 -- [prog module bcd, CharIndex] => FGIndex (wrt prog module bcd) 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: BcdOps.BcdBase = GetLocalBCD[rgfi: GFHFromTV[prog.someGFHTV].gfi]; 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: BcdOps.BcdBase _ GetRemoteBCD[world: world, rgfi: GetRemoteGFHeader [RemoteGFHFromTV[prog.someGFHTV]].gfi]; 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: BcdOps.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]}; }; -- [prog module bcd, CharIndex] => entryPointIndex (wrt prog module bcd) 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: BcdOps.BcdBase = GetLocalBCD[rgfi: GFHFromTV[prog.someGFHTV].gfi]; 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: BcdOps.BcdBase _ GetRemoteBCD[world: world, rgfi: GetRemoteGFHeader [RemoteGFHFromTV[prog.someGFHTV]].gfi]; 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: BcdOps.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: BcdOps.BcdBase, versionStamp: BcdDefs.VersionStamp] RETURNS[stb: SymbolTableBase _ NIL] = { FindModule: PROC[mth: BcdOps.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]}}; -- start GetModuleSTB here sth: SymbolTableHandle _ nullHandle; ftb: Table.Base = LOOPHOLE[bcd + bcd.ftOffset]; sth _ RTSymbolsPrivate.GetSTHForModule[versionStamp, NIL, NIL ! ANY => CONTINUE]; IF sth = nullHandle THEN [] _ BcdOps.ProcessModules[bcd, FindModule] ELSE stb _ AcquireSTB[sth]; }; }. Κ– "Mesa" style˜IprocšΠΟc‹œΟk œ žœ3žœέžœžœˆžœ*žœ+žœ2žœ!žœžœžœ!žœ?žœAžœFžœ+žœ0žœžœ,žœžœ…žœ žœ œGœ6œ žœžœžœžœ œœOœ œIœ[œ`œ6œRœΟn œžœžœœžœžœ žœžœœ žœžœžœmžœ»žœžœ…žœƒžœ»žœžœ΄žœ5Iœ Nœ &œ žœ žœžœ0žœ žœyžœ’žœžœžœ žœžœ žœžœ˜žœžœžœZžœ0žœžœžœžœžœžœ;žœ7žœžœ~žœžœ'žœžœ žœ2žœ>žœ4žœ˜žœ8žœ΄žœžœ3žœžœ‹žœYžœ$žœ²žœžœžœ žœ&žœHžœžœ žœžœτžœΊžœžœžœžœžœžœ²žœžœžœ žœ&žœHžœžœ žœžœτžœΘžœžœžœŽžœ‡žœžœœAŸœžœžœžœžœžœžœœCžœ%žœžœχžœ žœžœtžœ žœAžœζžœ–žœ žœžœtžœ%žœGžœœφžœšžœ žœžœhžœžœ=IŸ œžœžœžœžœ žœžœžœœCžœ%žœžœΦžœ žœžœ”žœ žœ?žœPžœζžœ‰žœ žœžœ”žœ%žœ[žœGžœœφžœžœ žœžœˆžœ%žœUžœ8Ÿ œžœžœ@žœžœŸ œžœ7žœžœžœ+žœIžœ žœžœ žœ*žœžœ œ?žœOžœžœžœžœžœžœ2žœ#˜ΉwJ˜—…—;Ό?Β