DIRECTORY AmpersandContext USING[CreateAnAmpersandContext, MakeNodeFromNode, StripAMNode], BasicTime USING[Now], CCTypes USING[CC, CCError, CCErrorCase, CreateCedarCompilerContext, LocalCedarTargetWorld, LocalCedarTargetWorldBody, RegisterLocalCedarTargetWorld], CedarCode USING[GetNodeRepresentation, GetTypeOfNode, LoadThroughIndirectNode, SelectFieldFromNode, StoreThroughIndirectNode], CirioBackstop USING[Protect], CirioBreakAccess USING[CirioBreakSet, CreateCirioBreakSet, ClearAllBreaks, ClearBreakAtAbsAddr, ClearBreakAtIndex, ListBreaks, QuaBreakSet, SetBreakAtAbsAddr], CirioDeltaFace USING[CallerInfo, GetCallersSPandPC], CirioNubAccess USING[CreateSameWorldNub, DestroyNub, FileEntry, GetFileEntry, Handle, LookupSymEntryByName, LookupSymEntryByValue, LookupSymEntryByID, PCInfo, PCtoInfo, Read32BitsAsCard, SymEntry], CirioTargets USING[Target], CirioTypes USING[CC, CompilerContext, Node, Type], Commander USING[CommandProc, Register], IO USING[PutF1, PutFR1, rope, STREAM], LoadStateAccess USING[CreateLoadStateHandle, GetLoadedModuleInfoFromAbsPC, LoadedModuleInfo, LoadStateHandle], LocalCirio USING[BreakDest, nilBreakDest], LocalCirioWorld USING[], NewAmpersandProcs USING[Handle, HandleBody, InstallItems], NewRMTW USING[CedarModuleSet, CreateCedarModuleSet, CreateRemoteMimosaTargetWorld, FlushUnknownFileCache, FlushUnknownSymbolCache, FlushUnknownTypeCodes, FrameNodeInfo, GetLoadedModuleInfo, GetNodeForCedarFrame, LoadedModuleInfo, RawFrameInfo, RemoteMimosaTargetWorld, ResetSearchPaths, ShowReportByLevel], ObjectFiles USING[CreateParsed, GetLineNumForPC, GetPCForLineNum, Module, ModuleFromParsedAndPC, Parsed], OneCasabaParser USING[ParserTable], PFS USING [RopeFromPath, PathFromRope], PFSNames USING [PATH, Equal], RefTab, Rope USING[Cat, Equal, Substr, ROPE], RopeHash USING[FromRope], SourceFileOps USING [OpenSource, Position], StackCirio USING[OpenDummyStack, OpenStack, ResetStack, Stack], SystemInterface USING [ShowReport, FileSet, CirioFile, CloseFileSet, CreateFileSet, GetCirioFile]; LocalCirioImpl: CEDAR MONITOR LOCKS connection USING connection: Connection IMPORTS AmpersandContext, BasicTime, CCTypes, CedarCode, CirioBackstop, CirioBreakAccess, CirioDeltaFace, CirioNubAccess, Commander, IO, LoadStateAccess, NewAmpersandProcs, NewRMTW, ObjectFiles, PFS, PFSNames, RefTab, Rope, RopeHash, SourceFileOps, StackCirio, SystemInterface EXPORTS LocalCirio, LocalCirioWorld = BEGIN OPEN ObjF: ObjectFiles, LSA: LoadStateAccess; DebugFlag: BOOLEAN ¬ FALSE; ROPE: TYPE = Rope.ROPE; CC: TYPE = CirioTypes.CompilerContext; CCE: ERROR[case: CCTypes.CCErrorCase, msg: ROPE ¬ NIL] ¬ CCTypes.CCError; BreakDest: TYPE = LocalCirio.BreakDest; nilBreakDest: BreakDest = LocalCirio.nilBreakDest; ConnectionList: TYPE ~ LIST OF Connection; Connection: TYPE = REF ConnectionBody; ConnectionBody: PUBLIC TYPE = MONITORED RECORD[ open: BOOLEAN, forRemote: BOOLEAN, -- true if created to provide local ampersand vars for a remoteCirio searchDirectories: REF LIST OF PFSNames.PATH, searchDirectoryLock: Connection, tsOut: IO.STREAM, -- WARNING: this field is very transient. It is only valid during an interpretation of an expression, and was placed here for the convenience of ampersand routines and (local target wrld) user routines called through the interpreter. aph: NewAmpersandProcs.Handle, ampersandContext1: CirioTypes.Node, ampersandContext2: CirioTypes.Node, cc: CC, breakDest: BreakDest, rmtw: NewRMTW.RemoteMimosaTargetWorld, cedarModules: NewRMTW.CedarModuleSet, nub: CirioNubAccess.Handle, target: CirioTargets.Target, breaks: CirioBreakAccess.CirioBreakSet, fileSet: SystemInterface.FileSet, lsh: LoadStateAccess.LoadStateHandle, cParserTable: OneCasabaParser.ParserTable, dbxActive: BOOLEAN ¬ FALSE]; thisWorldLock: Connection ¬ NEW[ConnectionBody]; commonFileSet: SystemInterface.FileSet ¬ NIL; commonCedarModules: NewRMTW.CedarModuleSet ¬ NIL; commonNub: CirioNubAccess.Handle ¬ NIL; commonTarget: CirioTargets.Target ¬ NIL; commonBreaks: RefTab.Ref--BreakDest -> CirioBreakAccess.CirioBreakSet-- ¬ RefTab.Create[equal: BDEqual, hash: BDHash]; commonlsh: LoadStateAccess.LoadStateHandle ¬ NIL; commonSearchDirectories: REF LIST OF PFSNames.PATH ¬ NIL; commonSearchDirectoryLock: Connection ¬ NIL; availConnections: RefTab.Ref--BreakDest -> ConnectionList-- ¬ RefTab.Create[equal: BDEqual, hash: BDHash]; RecreateThisWorldCirioConnection: Commander.CommandProc = BEGIN inner: ENTRY PROC[connection: Connection] = {InstallNewConnectionComponents[cmd.out]}; inner[thisWorldLock]; END; InstallNewConnectionComponents: PROC[reports: IO.STREAM] = BEGIN ENABLE UNWIND => { commonFileSet ¬ NIL; commonCedarModules ¬ NIL; commonCedarModules ¬ NIL; commonBreaks ¬ RefTab.Create[equal: BDEqual, hash: BDHash]; commonlsh ¬ NIL; commonSearchDirectories ¬ NIL; commonSearchDirectoryLock ¬ NIL}; IF commonNub # NIL THEN CirioNubAccess.DestroyNub[commonNub]; IF commonFileSet # NIL THEN SystemInterface.CloseFileSet[commonFileSet]; commonFileSet ¬ SystemInterface.CreateFileSet[]; commonCedarModules ¬ NewRMTW.CreateCedarModuleSet[commonFileSet]; commonNub ¬ CirioNubAccess.CreateSameWorldNub[]; commonTarget ¬ NARROW[commonNub.target]; commonBreaks.Erase[]; commonlsh ¬ LoadStateAccess.CreateLoadStateHandle["sameWorld", commonNub, commonFileSet]; commonSearchDirectories ¬ NEW[LIST OF PFSNames.PATH ¬ NIL]; commonSearchDirectoryLock ¬ NEW[ConnectionBody]; availConnections.Erase[]; END; TryForExistingConnection: ENTRY PROC[connection: Connection, breakDest: BreakDest] RETURNS[Connection] = BEGIN rbd: REF BreakDest ~ NEW [BreakDest ¬ breakDest]; acl: ConnectionList ~ NARROW[availConnections.Fetch[rbd].val]; IF acl#NIL THEN { first: Connection ~ acl.first; IF first.open THEN RETURN WITH ERROR CCE[cirioError, "Locking failure for a local connection"]; first.open ¬ TRUE; [] ¬ availConnections.Store[rbd, acl.rest]; RETURN [first]} ELSE RETURN[NIL]; END; BuildCommon: PROC[cc: CC, breakDest: BreakDest, reports: IO.STREAM, setCTC: BOOL, wdirs: LIST OF ROPE] RETURNS[Connection] = BEGIN makeProtoConnection: ENTRY PROC[connection: Connection] RETURNS[Connection] = BEGIN rbd: REF BreakDest ~ NEW [BreakDest ¬ breakDest]; bs: CirioBreakAccess.CirioBreakSet; IF commonFileSet = NIL THEN InstallNewConnectionComponents[reports]; IF (bs ¬ CirioBreakAccess.QuaBreakSet[commonBreaks.Fetch[rbd].val].it) = NIL THEN { bs ¬ CirioBreakAccess.CreateCirioBreakSet[commonNub, breakDest.fileNameStem, breakDest.breakProcName]; [] ¬ commonBreaks.Store[rbd, bs]}; BEGIN aph: NewAmpersandProcs.Handle ¬ NEW[NewAmpersandProcs.HandleBody¬[ out: NIL, -- only valid during a text line interpretation in StackCirio rmtw: NIL, cedarModules: commonCedarModules, nub: commonNub, target: commonTarget, fileSet: commonFileSet, lsh: commonlsh]]; pc: Connection ¬ NEW[ConnectionBody¬[ open: TRUE, forRemote: FALSE, searchDirectories: commonSearchDirectories, searchDirectoryLock: commonSearchDirectoryLock, aph: aph, ampersandContext1: NIL, ampersandContext2: NIL, cc: cc, breakDest: breakDest, rmtw: NIL, cedarModules: commonCedarModules, nub: commonNub, target: commonTarget, breaks: bs, fileSet: commonFileSet, lsh: commonlsh, cParserTable: NIL]]; RETURN[pc] END; END; pc: Connection ¬ makeProtoConnection[thisWorldLock]; lctw: CCTypes.LocalCedarTargetWorld ¬ NEW[CCTypes.LocalCedarTargetWorldBody¬[ createNodeFromRefAny: NIL, createFrameNodeForSelf: LCTWCreateFrameNodeForSelf, data: pc]]; AddDir[pc, "[PCedar2.0]", reports]; AddDir[pc, "[PCedar2.0]", reports]; AddDir[pc, "[PCedar2.0]", reports]; AddDir[pc, "[PCedar2.0]", reports]; AddDir[pc, "-compiled:/CirioCompiledData", reports]; EnsureDirs[pc, wdirs, reports]; pc.ampersandContext1 ¬ AmpersandContext.CreateAnAmpersandContext[cc]; pc.ampersandContext2 ¬ AmpersandContext.CreateAnAmpersandContext[cc]; pc.rmtw ¬ NewRMTW.CreateRemoteMimosaTargetWorld["sameWorld", pc.nub, cc, pc.cedarModules, pc.lsh, reports, setCTC]; pc.aph.rmtw ¬ pc.rmtw; CCTypes.RegisterLocalCedarTargetWorld[lctw, pc.cc]; RETURN[pc]; END; GetConnection: PUBLIC PROC[breakDest: BreakDest, reports: IO.STREAM, workingDirectories: LIST OF ROPE] RETURNS[Connection] = { ENABLE SystemInterface.ShowReport => {NewRMTW.ShowReportByLevel[reports, msgText, priority]; RESUME}; ans: Connection ¬ TryForExistingConnection[thisWorldLock, breakDest]; IF ans # NIL THEN EnsureDirs[ans, workingDirectories, reports] ELSE { cc: CC ¬ CCTypes.CreateCedarCompilerContext[]; ans ¬ BuildCommon[cc, breakDest, reports, TRUE, workingDirectories]; NewAmpersandProcs.InstallItems[ans.ampersandContext2, ans.aph, ans.cc]; }; RETURN [ans]}; EnsureDirs: PROC [c: Connection, wdirs: LIST OF ROPE, reports: IO.STREAM] ~ { IF wdirs#NIL THEN { EnsureDirs[c, wdirs.rest, reports]; AddDir[c, wdirs.first, reports, FALSE]}; RETURN}; ExtractCcFromConnection: PUBLIC PROC [c: Connection] RETURNS [CirioTypes.CC] ~ {RETURN [c.cc]}; CreateAndRegisterNominalLocalCirioTW: PUBLIC PROC[cc: CCTypes.CC, reports: IO.STREAM] = BEGIN ENABLE SystemInterface.ShowReport => {NewRMTW.ShowReportByLevel[reports, msgText, priority]; RESUME}; connection: Connection ¬ BuildCommon[cc, nilBreakDest, reports, FALSE, NIL]; connection.forRemote ¬ TRUE; END; LCTWCreateFrameNodeForSelf: PROC[lctw: CCTypes.LocalCedarTargetWorld, cc: CCTypes.CC] RETURNS[CirioTypes.Node] = BEGIN connection: Connection ¬ NARROW[lctw.data]; ourInfo: CirioDeltaFace.CallerInfo ¬ CirioDeltaFace.GetCallersSPandPC[connection.nub]; ourSP: CARD ¬ ourInfo.callersStackPointer; callerPC: CARD ¬ CirioNubAccess.Read32BitsAsCard[[connection.nub, ourSP+(15*4), 0, FALSE, TRUE]]; callerLedo: REF LSA.LoadedModuleInfo ¬ LSA.GetLoadedModuleInfoFromAbsPC[connection.lsh, callerPC]; callerLoadedCedarModule: REF NewRMTW.LoadedModuleInfo ¬ NewRMTW.GetLoadedModuleInfo[connection.cedarModules, callerLedo]; ourFP: CARD ¬ CirioNubAccess.Read32BitsAsCard[[connection.nub, ourSP+(14*4), 0, FALSE, TRUE]]; callerSP: CARD ¬ ourFP; callerFP: CARD ¬ CirioNubAccess.Read32BitsAsCard[[connection.nub, callerSP+(14*4), 0, FALSE, TRUE]]; callerRawFrameInfo: REF NewRMTW.RawFrameInfo ¬ NEW[NewRMTW.RawFrameInfo ¬ [ callerPC, callerFP, callerSP]]; callerInfo: REF NewRMTW.FrameNodeInfo; IF callerLoadedCedarModule=NIL THEN CCE[cirioError, "Cirio can't NewRMTW.GetLoadedModuleInfo for itself"]; callerInfo ¬ NewRMTW.GetNodeForCedarFrame[connection.rmtw, callerLoadedCedarModule, callerRawFrameInfo]; RETURN[callerInfo.node]; END; FlushUnknownFileCache: PUBLIC ENTRY PROC[connection: Connection, reports: IO.STREAM] = BEGIN ENABLE UNWIND => NULL; IF NOT connection.open THEN RETURN; NewRMTW.FlushUnknownFileCache[connection.cedarModules, BasicTime.Now[]]; NewRMTW.FlushUnknownSymbolCache[connection.rmtw, BasicTime.Now[], reports]; NewRMTW.FlushUnknownTypeCodes[connection.rmtw]; END; ReleaseConnection: PUBLIC ENTRY PROC[connection: Connection, reports: IO.STREAM] = BEGIN ENABLE UNWIND => NULL; renamed: Connection ¬ connection; PutBack: PROC[connection: Connection] = { ENABLE UNWIND => NULL; rbd: REF BreakDest ~ NEW [BreakDest ¬ renamed.breakDest]; acl: ConnectionList ¬ NARROW[availConnections.Fetch[rbd].val]; acl ¬ CONS[renamed, acl]; [] ¬ availConnections.Store[rbd, acl]; RETURN}; IF NOT connection.open THEN RETURN WITH ERROR CCE[cirioError, "some fool released a local connection that wasn't open"]; connection.open ¬ FALSE; IF NOT connection.forRemote THEN PutBack[thisWorldLock]; RETURN; END; DoUnderMonitorLock: PUBLIC ENTRY PROC[connection: Connection, toDo: PROC] = BEGIN ENABLE UNWIND => NULL; toDo[]; END; GetStackForSelf: PUBLIC ENTRY PROC[connection: Connection, reports: IO.STREAM]RETURNS[StackCirio.Stack] = BEGIN callerInfo: CirioDeltaFace.CallerInfo¬ CirioDeltaFace.GetCallersSPandPC[connection.nub]; stack: StackCirio.Stack ¬ StackCirio.OpenStack[ ampersandContext1: connection.ampersandContext1, ampersandContext2: connection.ampersandContext2, cc: connection.cc, rmtw: connection.rmtw, cedarModules: connection.cedarModules, nub: connection.nub, target: connection.target, fileSet: connection.fileSet, breaks: connection.breaks, lsh: connection.lsh, aph: connection.aph, cParserTable: connection.cParserTable, hotFramePC: callerInfo.callersPC, hotFrameSP: callerInfo.callersStackPointer, skipKFrames: 1, ShowSource: SourceFileOps.OpenSource, reports: reports]; frameIndex: CARD ¬ StackCirio.ResetStack[stack, reports]; RETURN[stack] END; GetDummyStack: PUBLIC ENTRY PROC[connection: Connection, reports: IO.STREAM]RETURNS[StackCirio.Stack] = BEGIN stack: StackCirio.Stack ¬ StackCirio.OpenDummyStack[ ampersandContext1: connection.ampersandContext1, ampersandContext2: connection.ampersandContext2, cc: connection.cc, rmtw: connection.rmtw, cedarModules: connection.cedarModules, nub: connection.nub, target: connection.target, fileSet: connection.fileSet, breaks: connection.breaks, lsh: connection.lsh, aph: connection.aph, cParserTable: connection.cParserTable, ShowSource: SourceFileOps.OpenSource, reports: reports]; RETURN[stack] END; InstallOneAmpersandItem: PROC[ampersandContext: CirioTypes.Node, name: ROPE, item: CirioTypes.Node, cc: CC] = BEGIN IF NOT Rope.Equal[Rope.Substr[name, 0, 2], "&&"] THEN ERROR ELSE BEGIN ampersandContextType: CirioTypes.Type ¬ CedarCode.GetTypeOfNode[ampersandContext]; indirect: CirioTypes.Node ¬ CedarCode.SelectFieldFromNode[name, ampersandContextType, ampersandContext, cc]; indirectType: CirioTypes.Type ¬ CedarCode.GetTypeOfNode[indirect]; encapsulatedItem: CirioTypes.Node ¬ AmpersandContext.MakeNodeFromNode[item, cc]; encapsulatedType: CirioTypes.Type ¬ CedarCode.GetTypeOfNode[encapsulatedItem]; CedarCode.StoreThroughIndirectNode[encapsulatedType, encapsulatedItem, indirectType, indirect, cc]; END END; ReadOneAmpersandItem: PROC[name: ROPE, nameScope: CirioTypes.Node, cc: CC] RETURNS[CirioTypes.Node] = BEGIN IF NOT Rope.Equal[Rope.Substr[name, 0, 2], "&&"] THEN ERROR ELSE BEGIN nameScopeType: CirioTypes.Type ¬ CedarCode.GetTypeOfNode[nameScope]; indirect: CirioTypes.Node ¬ CedarCode.SelectFieldFromNode[name, nameScopeType, nameScope, cc]; indirectType: CirioTypes.Type ¬ CedarCode.GetTypeOfNode[indirect]; encapsulatedItem: CirioTypes.Node ¬ CedarCode.LoadThroughIndirectNode[indirectType, indirect, cc]; RETURN[AmpersandContext.StripAMNode[encapsulatedItem]] END; END; ReadOneAmpersandInt: PROC[name: ROPE, defaultVal: INT, nameScope: CirioTypes.Node, cc: CC] RETURNS[INT] = BEGIN valNode: CirioTypes.Node ¬ NIL; valNode ¬ ReadOneAmpersandItem[name, nameScope, cc ! CCE => {valNode ¬ NIL; CONTINUE}]; IF valNode = NIL THEN RETURN[defaultVal] ELSE BEGIN val: REF INT ¬ NARROW[CedarCode.GetNodeRepresentation[valNode, cc]]; RETURN[val­]; END; END; AddSearchDirectory: PUBLIC PROC [connection: Connection, dirName: ROPE, reports: IO.STREAM] = BEGIN inner: PROC RETURNS[ROPE] = BEGIN AddDir[connection, dirName, reports]; IO.PutF1[reports, " %g added to search directories\n", IO.rope[dirName]]; RETURN [NIL]; END; eMsg: ROPE; eMsg ¬ CirioBackstop.Protect[inner, reports]; IF eMsg # NIL THEN IO.PutF1[reports, "%g\N", [rope[eMsg]]]; END; RemoveSearchDirectory: PUBLIC PROC [connection: Connection, dirName: ROPE, reports: IO.STREAM] = BEGIN inner: PROC RETURNS[ROPE] = BEGIN RemoveDir[connection, dirName, reports]; IO.PutF1[reports, " %g removed from search directories\n", IO.rope[dirName]]; RETURN [NIL]; END; eMsg: ROPE; eMsg ¬ CirioBackstop.Protect[inner, reports]; IF eMsg # NIL THEN IO.PutF1[reports, "%g\N", [rope[eMsg]]]; END; ListSearchDirectory: PUBLIC PROC [connection: Connection, reports: IO.STREAM] = BEGIN inner: PROC RETURNS [ROPE] = BEGIN ListDir[connection]; RETURN [NIL] END; eMsg: ROPE; eMsg ¬ CirioBackstop.Protect[inner, reports]; IF eMsg # NIL THEN IO.PutF1[reports, "%g\N", [rope[eMsg]]]; END; ClearSearchDirectory: PUBLIC PROC [connection: Connection, reports: IO.STREAM] = BEGIN inner: PROC RETURNS [ROPE] = BEGIN ClearDir[connection]; RETURN [NIL] END; eMsg: ROPE; eMsg ¬ CirioBackstop.Protect[inner, reports]; IF eMsg # NIL THEN IO.PutF1[reports, "%g\N", [rope[eMsg]]]; END; SetBreakAtAbsAddr: PROC[h: Connection, absAddr: CARD32, mesaPos: SourceFileOps.Position, stopAll: BOOLEAN] = {CirioBreakAccess.SetBreakAtAbsAddr[h.breaks, absAddr, mesaPos, stopAll]}; ListBreaks: PROC[h: Connection] = {CirioBreakAccess.ListBreaks[h.breaks]}; ClearBreakAtAbsAddr: PROC[h: Connection, absAddr: CARD32] = {CirioBreakAccess.ClearBreakAtAbsAddr[h.breaks, absAddr]}; ClearBreakAtIndex: PROC[h: Connection, index: CARD] = {CirioBreakAccess.ClearBreakAtIndex[h.breaks, index]}; ClearAllBreaks: PROC[h: Connection] = {CirioBreakAccess.ClearAllBreaks[h.breaks]}; AddDir: PROC [h: Connection, dirName: ROPE, reports: IO.STREAM, toFront: BOOL ¬ TRUE] = { inner: ENTRY PROC[connection: Connection] = { ENABLE UNWIND => NULL; dirPath: PFSNames.PATH ¬ PFS.PathFromRope[dirName]; prev: LIST OF PFSNames.PATH ¬ NIL; WHILE TRUE DO current: LIST OF PFSNames.PATH ¬ IF prev # NIL THEN prev.rest ELSE h.searchDirectories­; IF current = NIL THEN EXIT; SELECT TRUE FROM NOT dirPath.Equal[current.first] => NULL; toFront => { IF prev = NIL THEN h.searchDirectories­ ¬ current.rest ELSE prev.rest ¬ current.rest; EXIT; }; ENDCASE => RETURN--already present--; prev ¬ current; ENDLOOP; h.searchDirectories­ ¬ CONS[dirPath, h.searchDirectories­]; NewRMTW.ResetSearchPaths[h.cedarModules, h.searchDirectories­, BasicTime.Now[]]; IF h.rmtw#NIL THEN NewRMTW.FlushUnknownSymbolCache[h.rmtw, BasicTime.Now[], reports]; }; inner[h.searchDirectoryLock]; }; RemoveDir: PROC [h: Connection, dirName: ROPE, reports: IO.STREAM] = BEGIN inner: ENTRY PROC[connection: Connection] = BEGIN ENABLE UNWIND => NULL; dirPath: PFSNames.PATH ¬ PFS.PathFromRope[dirName]; prev: LIST OF PFSNames.PATH ¬ NIL; WHILE TRUE DO current: LIST OF PFSNames.PATH ¬ IF prev # NIL THEN prev.rest ELSE h.searchDirectories­; IF current = NIL THEN EXIT; IF dirPath.Equal[current.first] THEN BEGIN IF prev = NIL THEN h.searchDirectories­ ¬ current.rest ELSE prev.rest ¬ current.rest; EXIT; END; prev ¬ current; ENDLOOP; NewRMTW.ResetSearchPaths[h.cedarModules, h.searchDirectories­, BasicTime.Now[]]; NewRMTW.FlushUnknownSymbolCache[h.rmtw, BasicTime.Now[], reports]; END; inner[h.searchDirectoryLock]; END; ListDir: PROC [h: Connection] = BEGIN inner: ENTRY PROC[connection: Connection] = BEGIN ENABLE UNWIND => NULL; searchDirectories: ROPE ¬ NIL; FOR paths: LIST OF PFSNames.PATH ¬ h.searchDirectories­, paths.rest WHILE paths # NIL DO searchDirectories ¬ Rope.Cat[searchDirectories, PFS.RopeFromPath[paths.first], " "]; ENDLOOP; SystemInterface.ShowReport[IO.PutFR1["%g", IO.rope[searchDirectories]], $urgent]; END; inner[h.searchDirectoryLock]; END; ClearDir: PROC [h: Connection] = BEGIN inner: ENTRY PROC[connection: Connection] = BEGIN ENABLE UNWIND => NULL; SystemInterface.ShowReport["Clearing search directory list", $urgent]; SystemInterface.ShowReport["Was: ", $urgent]; ListDir[h]; h.searchDirectories­ ¬ NIL; NewRMTW.ResetSearchPaths[h.cedarModules, h.searchDirectories­, BasicTime.Now[]]; END; inner[h.searchDirectoryLock]; END; LookupSym: PROC[h: Connection, name: ROPE, numToSkip: INT ¬ 0, externOnly: BOOL ¬ TRUE] RETURNS[CirioNubAccess.SymEntry] = {RETURN[CirioNubAccess.LookupSymEntryByName[h.nub, name, FALSE, externOnly, numToSkip]]}; LookupAddr: PROC[h: Connection, val: CARD, numToSkip: INT ¬ 0] RETURNS[CirioNubAccess.SymEntry] = {RETURN[CirioNubAccess.LookupSymEntryByValue[h.nub, val, numToSkip]]}; LookupID: PROC[h: Connection, symID: CARD] RETURNS[CirioNubAccess.SymEntry] = {RETURN[CirioNubAccess.LookupSymEntryByID[h.nub, symID]]}; LookupFile: PROC[h: Connection, seqNum: CARD] RETURNS[entry: CirioNubAccess.FileEntry] = {RETURN[CirioNubAccess.GetFileEntry[h.nub, seqNum]]}; GetPCInfo: PROC[h: Connection, absPC: CARD] RETURNS[CirioNubAccess.PCInfo] = {RETURN[CirioNubAccess.PCtoInfo[h.nub, absPC]]}; DebugOn: PROC = BEGIN DebugFlag ¬ TRUE; END; DebugOff: PROC = BEGIN DebugFlag ¬ FALSE; END; GetRelPCForCLine: PROC[dotOName: PFSNames.PATH, cLineNum: CARD, h: Connection] RETURNS[CARD] = BEGIN file: SystemInterface.CirioFile ¬ SystemInterface.GetCirioFile[h.fileSet, dotOName]; container: ObjF.Parsed ¬ ObjF.CreateParsed[file]; AcquireModule: PROC RETURNS[ObjF.Module] = BEGIN RETURN[ObjF.ModuleFromParsedAndPC[container, [[0, ""], 1]]]; END; dotO: ObjF.Module ¬ AcquireModule[]; relPC: CARD ¬ ObjF.GetPCForLineNum[dotO, cLineNum].relPC; RETURN[relPC]; END; GetCLineForRelPC: PROC[dotOName: PFSNames.PATH, relPC: CARD, h: Connection] RETURNS[CARD] = BEGIN file: SystemInterface.CirioFile ¬ SystemInterface.GetCirioFile[h.fileSet, dotOName]; container: ObjF.Parsed ¬ ObjF.CreateParsed[file]; AcquireModule: PROC RETURNS[ObjF.Module] = BEGIN RETURN[ObjF.ModuleFromParsedAndPC[container, [[0, ""], 1]]]; END; dotO: ObjF.Module ¬ AcquireModule[]; cLine: CARD ¬ ObjF.GetLineNumForPC[dotO, [[0, ""], relPC]]; RETURN[cLine]; END; BDEqual: PROC [key1, key2: REF ANY] RETURNS [BOOL] ~ { bd1: REF BreakDest ~ NARROW[key1]; bd2: REF BreakDest ~ NARROW[key2]; RETURN [bd1.fileNameStem.Equal[bd2.fileNameStem] AND bd1.breakProcName.Equal[bd2.breakProcName]]}; BDHash: PROC [key: REF ANY] RETURNS [CARDINAL] ~ { bd: REF BreakDest ~ NARROW[key]; RETURN [RopeHash.FromRope[bd.fileNameStem] + RopeHash.FromRope[bd.breakProcName]]}; Commander.Register["RecreateThisWorldCirioConnection", RecreateThisWorldCirioConnection]; END.. ” LocalCirioImpl.mesa Copyright Σ 1990, 1991, 1992 by Xerox Corporation. All rights reserved. Sturgis, April 20, 1990 3:25 pm PDT Last changed by Theimer on November 28, 1989 3:36:23 pm PST Last tweaked by Mike Spreitzer on July 24, 1992 6:14 pm PDT Linda Howe January 3, 1990 4:09:35 pm PST Coolidge, July 18, 1990 10:21 am PDT Laurie Horton, March 31, 1992 12:48 pm PST Philip James, February 24, 1992 11:42 am PST Udagawa, February 12, 1991 9:03 pm PST Willie-s, July 27, 1992 5:48 pm PDT Debugging aids This variable can be set/reset by the ampersand routines &&DebugOn and &&DebugOff. Types Connections serves as a monitor lock for the following Note: we delay creating any worlds until all modules have been started, because the nominal creation code will be calling procedures in those modules. There are more than one world so that we can have multiple independent cirios active at one time, e.g. if an error is raised during an interpreted procedure call, while at the same time avoiding monitor deadlocks. However, they will all share common CedarModuleSet, CirioNubAccess.Handle, CirioBreakAccess.CirioBreakSet (per break dest), SystemInterface.FileSet, and LoadStateAccess.LoadStateHandle. I assume these modules will suitably protect themselves, and that none of them will be holding a monitor lock during an interpreted procedure call. "thisWorldLock" must be held during a call to this procedure commonTarget _ CirioTargets.CreateTarget[commonNub]; connection param must be "thisWorldLock" connection param must be "thisWorldLock" designed not to do anything dangerous while the lock is held simply collects common stuff into some records Add the directories in REVERSE ORDER because AddDir adds to the front of the list!! We include these directories so that examination of "navel" will procede correctly for a released Cirio. This is done before CreateRemoteMimosaTargetWorld so that the studying of CirioRopeHelper done therein will succeed on first try. The following files are needed (on August 17, 1991): CirioThings/CirioRopeHelper.mob Cirio/CCTypesImpl.mob Cirio/CirioTypes.mob Cirio/NewAmpersandProcs.mob Cirio/NewAmpersandProcsImpl.mob Rope/Rope.mob Atom/AtomPrivate.mob all local connections register themselves with their cc BUT, outside the monitor lock IO.PutF[reports, "%g\N", IO.rope[msgText]]; note: connection argument will be thisWorldLock this procedure is exported to LocalCirioWorld, and is called by RemoteCirioImpl to permit construction of ampersand routines. parallels GetConnection, except that registration is with supplied cc, we always create a connection, we let the caller install the ampersand procs, and breakpoints cannot be set through this connection. IO.PutF[reports, "%g\N", IO.rope[msgText]]; in this case, "self" is the caller of this procedure This procedure duplicates assorted activity in StackCirioImpl note: In CirioDeltaFace.GetCallersSPandPC, "caller" refers to the caller of CirioDeltaFace.GetCallersSPandPC, i.e., ourselves. In LCTWCreateFrameNodeForSelf, "self" refers to the caller of LCTWCreateFrameNodeForSelf, i.e., our caller. note: in the following var names, "caller" refers to the same frame as "Self" in our procedure name, that is, our caller. the nomenclature is such that ourInfo.callersStackPointer is really our stack pointer. This constant (14*4) exists in several places. They should be combined. This constant (14*4) exists in several places. They should be combined. to be visible inside putBack putBack has to reuse the identifier: connection so as to be able to lock Stack examination need to install a catch phrase for NARROW fault source and break positions Set the search directory. Remove the search directory. List the set of search directories Clear the set of search directories breakpoints (tentative, using ampersand procedures) properDirName: ROPE _ CirioDeltaFace.ConvertToLocalDirectoryFormat[dirName]; first, we remove any existing entry for the path now we install the path at the front of the list now we inform those who need to know first, we remove any existing entry for the path now we inform those who need to know now we inform those who need to know note: we need not do a NewRMTW.FlushUnknownSymbolCache[h.rmtw, BasicTime.Now[]], because that need only be called when new definition mobs become accessible, not when some become inaccessible. symbols these procedures are expected to become ampersand procedures. During the interpreted call on them the connection will be locked, so there is no need to lock it here. In fact, that would cause a monitor deadlock. misc stabRange _ ObjF.AlternativeFindModuleStabRange[container, 1]; another Kludge stabRange _ ObjF.AlternativeFindModuleStabRange[container, 1]; main code Κ;•NewlineDelimiter –"cedarcode" style™codešœ™Kšœ Οeœ=™HKšœ#™#K™;K™;K™)K™$K™*K™,K™&K™#—K˜šΟk ˜ Kšœžœ:˜PKšœ žœ˜Kšœžœžœ…˜•Kšœ žœo˜~Kšœžœ ˜Kšœžœ‰˜ŸKšœžœ ˜4Kšœžœ±˜ΕKšœ žœ ˜Kšœ žœžœ˜2Kšœ žœ˜'Kšžœžœžœ˜&KšœžœY˜nKšœ žœ˜*Kšœžœ˜Kšœžœ#˜:Kšœžœ₯˜²Kšœ žœX˜iKšœžœ˜#Kšžœžœ˜'Kšœ žœžœ ˜K˜Kšœžœžœ˜%Kšœ žœ ˜Kšœžœ˜+Kšœ žœ/˜?KšœžœM˜bK˜—šΟnœžœž˜Kšžœ žœ˜-Kšžœžœ<žœN˜•Kšžœ˜%—KšžœžœŸœžœ˜3K˜™K˜šŸ œžœžœ˜K™R——K˜K™™Kšžœžœžœ˜Kšžœžœ˜&Kšžœžœ!žœžœ˜I—˜Kšœ žœ˜'Kšœ2˜2K™Kšœžœžœžœ ˜*Kšœ žœžœ˜&š œžœžœž œžœ˜/Kšœžœ˜Kšœ žœΟcE˜YKš œžœžœžœ žœ˜-Kšœ ˜ Kšœžœžœ κ˜όK˜K˜#K˜#Kšœžœ˜K˜Kšœ&˜&Kšœ%˜%Kšœ˜K˜Kšœ'˜'K˜!K˜%Kšœ*˜*Kšœ žœžœ˜—˜K˜——™ K˜šœžœ˜0K™*—K˜Kšœ)žœ˜-Kšœ-žœ˜1Kšœ#žœ˜'Kšœ$žœ˜(Kšœ /œ/˜vKšœ-žœ˜1Kš œžœžœžœ žœžœ˜9Kšœ(žœ˜,K˜Kšœ œ/˜j˜K™–K™ΥKšœΞ™ΞK™K˜—K˜K˜šŸ œ˜9Kšž˜KšœžœžœE˜VKšœ˜šžœ˜K˜K™<——šŸœžœ žœžœ˜:Kšž˜šžœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜K˜;Kšœ žœ˜Kšœžœ˜Kšœžœ˜!K˜—K˜Kšžœ žœžœ&˜=Kšžœžœžœ-˜HK˜K˜0K˜AK˜0Kšœ4™4Kšœžœ˜(K™Kšœ˜K˜YKš œžœžœžœ žœžœ˜;Kšœžœ˜0Kšœ˜Kšžœ˜—˜K™(—šŸœžœžœ/žœ˜hKšž˜Kšœžœ žœ˜1Kšœžœ"˜>šžœžœžœ˜K˜Kš žœ žœžœžœžœžœ7˜_Kšœ žœ˜K˜+Kšžœ ˜—Kšœžœžœžœ˜Kšžœ˜—K˜šŸ œžœžœ!žœžœ žœ žœžœžœžœ˜|Kšž˜˜K™(™šžœ˜Kšœžœ(˜.Kšœ*žœ˜DKšœG˜GKšœ˜—Kšžœ˜—K˜šŸ œžœžœžœžœ žœžœ˜Mšžœžœžœ˜Kšœ#˜#Kšœ žœ˜(—Kšžœ˜—K˜š Ÿœžœžœžœ žœ˜LKšœžœ ˜—˜K™}KšœΛ™Λ—š Ÿ$œžœžœ žœ žœžœ˜WKšž˜šžœ˜$Kšœ7˜7Kšžœžœ™,Kšžœ˜—Kšœ@žœžœ˜LKšœžœ˜Kšžœ˜—˜K™4K™=—šŸœžœ2žœžœ˜pKšž˜Kšœžœ ˜+˜VKšœλ™λ—K˜K™yK™šœžœ˜*KšœV™V—K˜Kšœ žœEžœžœ˜aK˜Kšœ žœžœžœ8˜bK˜Kšœžœ]˜yK˜šœžœEžœžœ˜^KšœH™H—K˜Kšœ žœ ˜šœ žœHžœžœ˜dKšœH™H—K˜šœžœžœ˜KKšœ ˜ Kšœ ˜ Kšœ ˜ —K˜Kšœ žœ˜&K˜KšžœžœžœžœC˜jK˜K˜hK˜Kšžœ˜Kšžœ˜—K˜š Ÿœžœžœžœ"žœžœ˜VKšž˜Kšžœžœžœ˜Kšžœžœžœžœ˜#KšœH˜HKšœK˜KKšœ/˜/Kšžœ˜—K˜š Ÿœžœžœžœ"žœžœ˜RKšžœžœžœžœ˜˜!K™K™H—šŸœžœ˜)Kšžœžœžœ˜Kšœžœ žœ!˜9Kšœžœ"˜>Kšœžœ˜K˜&Kšžœ˜—KšžœžœžœžœžœžœžœG˜xKšœžœ˜Kšžœžœžœ˜8Kšžœžœ˜ —K˜š Ÿœžœžœžœžœ˜KKšž˜Kšžœžœžœ˜K˜Kšžœ˜—K˜K˜—™K˜K˜šŸœžœžœžœ"žœžœžœ˜jKšž˜K˜XK˜˜/Kšœ0˜0Kšœ0˜0Kšœ˜Kšœ˜Kšœ&˜&Kšœ˜Kšœ˜Kšœ˜K˜Kšœ˜Kšœ˜Kšœ&˜&Kšœ!˜!Kšœ+˜+Kšœ˜KšŸ œ˜%Kšœ˜—Kšœ žœ)˜9K˜Kšžœ˜ Kšžœ˜—K˜šŸ œžœžœžœ"žœžœžœ˜hKšž˜˜4Kšœ0˜0Kšœ0˜0Kšœ˜Kšœ˜Kšœ&˜&Kšœ˜Kšœ˜Kšœ˜K˜Kšœ˜K˜Kšœ&˜&KšŸ œ˜%Kšœ˜—K˜Kšžœ˜ Kšžœ˜—K˜—K˜™šŸœžœ*žœžœ˜mKšž˜šžœžœ+žœž˜;šž˜Kšž˜K˜RK˜lK˜BK˜PK˜NK˜cKšž˜——Kšžœ˜—K˜š Ÿœžœžœ"žœžœ˜eKšž˜šžœžœ+žœž˜;šž˜Kšž˜K˜DK˜^K˜BK˜bKšžœ0˜6Kšžœ˜——Kšžœ˜—K˜šŸœžœžœžœ"žœžœžœ˜iKšž˜Kšœžœ˜˜2Kšœžœžœžœ˜$—šžœ žœžœžœ ˜(šž˜Kšž˜šœžœžœžœ/˜DKšœ/™/—Kšžœ˜ Kšžœ˜——Kšžœ˜—K™—K™K™™š Ÿœžœžœ#žœ žœžœ˜^Kšž˜K˜šœžœžœžœ˜Kšž˜™Kšœ%˜%Kšžœ5žœ˜I—Kšžœžœ˜ Kšžœ˜—K˜Kšœžœ˜ K˜-Kšžœžœžœžœ&˜;Kšžœ˜K˜—š Ÿœžœžœ#žœ žœžœ˜aKšž˜K˜šœžœžœžœ˜Kšž˜™Kšœ(˜(Kšžœ9žœ˜M—Kšžœžœ˜ Kšžœ˜—K˜Kšœžœ˜ K˜-Kšžœžœžœžœ&˜;Kšžœ˜K˜—š Ÿœžœžœ#žœžœ˜OKšž˜K˜šœžœžœžœ˜Kšž˜K™"K˜Kšžœžœ˜ Kšžœ˜K˜—Kšœžœ˜ K˜-Kšžœžœžœžœ&˜;Kšžœ˜K˜—š Ÿœžœžœ#žœžœ˜PKšž˜K˜šœžœžœžœ˜Kšž˜K™#K˜Kšžœžœ˜ Kšžœ˜K˜—Kšœžœ˜ K˜-Kšžœžœžœžœ&˜;Kšžœ˜K˜——K˜™4K˜šŸœžœžœ,žœ˜lKšœJ˜JK˜—šŸ œžœ˜!Kšœ(˜(K˜—šŸœžœžœ˜;Kšœ:˜:K˜—šŸœžœžœ˜5Kšœ6˜6—K˜šŸœžœ˜%Kšœ,˜,—K˜šŸœžœžœ žœžœ žœžœ˜Yšœžœžœ˜-Kšžœžœžœ˜KšœL™LKšœžœžœ˜3š œžœžœ žœžœ˜"K™0—šžœžœž˜ Kšœ žœžœ žœžœžœžœ žœ˜XKšžœ žœžœžœ˜šžœžœž˜Kšžœ!žœ˜)šœ ˜ Kšžœžœžœ%žœ˜UKšžœ˜Kšœ˜—Kšžœž œ˜%—K˜Kšžœ˜—K™0Kšœžœ ˜;K™$K˜PKšžœžœžœC˜UKšœ˜—Kšœ˜Kšœ˜—K˜š Ÿ œžœžœ žœžœ˜DKšž˜šœžœžœ˜+Kšž˜Kšžœžœžœ˜Kšœžœžœ˜3š œžœžœ žœžœ˜"K™0—šžœžœž˜ Kšœ žœžœ žœžœžœžœ žœ˜XKšžœ žœžœžœ˜šžœž˜$Kšž˜Kšžœžœžœ%žœ˜UKšžœ˜Kšžœ˜—K˜Kšžœ˜—K™$K˜PKšœB˜BKšžœ˜—Kšœ˜Kšžœ˜K˜—šΠbnœžœ˜Kšž˜šœžœžœ˜+Kšž˜Kšžœžœžœ˜Kšœžœžœ˜š žœžœžœ žœ$žœ žœž˜XKšœ0žœ"˜UKšžœ˜—Kšœžœžœ$˜QKšžœ˜—Kšœ˜Kšžœ˜—K˜š‘œžœ˜ Kšž˜šœžœžœ˜+Kšž˜Kšžœžœžœ˜K˜FK˜-K˜ Kšœžœ˜K™$K˜PKšœΐ™ΐKšžœ˜—Kšœ˜Kšžœ˜K˜——K˜™K™ΥK™šŸ œžœžœ žœžœžœžœ˜zKšœžœ2žœ˜Y—K˜š Ÿ œžœžœ žœžœ˜aKšœžœ?˜F—K˜šŸœžœžœžœ˜MKšœžœ3˜:—K˜šŸ œžœžœžœ#˜XKšœžœ.˜5—K˜šŸ œžœžœžœ˜LKšœžœ)˜0—K˜K™K˜šŸœžœ˜Kšž˜Kšœ žœ˜Kšžœ˜—K˜šŸœžœ˜Kšž˜Kšœ žœ˜Kšžœ˜—˜K˜—š Ÿœžœžœ žœžœžœ˜^Kšž˜K˜TK˜1šŸ œžœžœ˜*Kšž˜Kšœ žœ-™>Kšžœ6˜Kšžœ6˜