DIRECTORY Alloc: TYPE USING [Notifier, AddNotify, DropNotify, Words], ComData: TYPE USING [importCtx, interface, moduleCtx, objectStamp, outerCtx, table, textIndex], ConvertUnsafe: TYPE USING [ToRope], Copier: TYPE USING [CreateFileTable, EnterFile, FileVersionMix, FillModule, SearchFileCtx, UnknownModule], LiteralOps: TYPE USING [StringIndex, StringValue], Log: TYPE USING [ErrorHti, ErrorSei, ErrorTree], OSMiscOps: TYPE USING [MergeStamps, TimeToStamp], P3: TYPE USING [mark, EnterIdList, Exp, MakeIdTable, MakeFrameRecord, MakeRefType, PopCtx, PushCtx, RAttr, RPop, Shared, UType], Rope: TYPE USING [ROPE], SourceMap: TYPE USING [Loc], Symbols: TYPE USING [Base, SERecord, CTXRecord, Name, ISEIndex, CSEIndex, CTXIndex, IncludedCTXIndex, MDIndex, CBTIndex, nullName, ISENull, CTXNull, RootBti, BTNull, lG, OwnMdi, typeANY, seType, ctxType, mdType, bodyType], SymbolOps: TYPE USING [FillCtxSe, FirstCtxSe, LinkMode, MakeCtxSe, MakeNonCtxSe, NameClash, NewCtx, NextSe, SearchContext, UnderType], Tree: TYPE USING [Base, Index, Link, Map, Scan, Test, Null, NullIndex, treeType], TreeOps: TYPE USING [GetHash, GetNode, ListLength, ScanList, SearchList, UpdateList]; Pass3B: PROGRAM IMPORTS Alloc, ConvertUnsafe, Copier, LiteralOps, Log, OSMiscOps, P3, SymbolOps, TreeOps, dataPtr: ComData EXPORTS P3 = { OPEN TreeOps, SymbolOps, Symbols, P3; tb: Tree.Base; -- tree base address (local copy) seb: Symbols.Base; -- se table base address (local copy) ctxb: Symbols.Base; -- context table base address (local copy) mdb: Symbols.Base; -- module table base address (local copy) bb: Symbols.Base; -- body table base address (local copy) BCDNotify: Alloc.Notifier = { tb _ base[Tree.treeType]; seb _ base[seType]; ctxb _ base[ctxType]; mdb _ base[mdType]; bb _ base[bodyType]}; GetSe: PROC[t: Tree.Link] RETURNS[ISEIndex] = { RETURN[WITH t SELECT FROM symbol => index, subtree => GetSe[tb[index].son[1]], ENDCASE => ERROR] }; ItemLabel: PROC[node: Tree.Index] RETURNS[ISEIndex] = INLINE { RETURN[GetSe[tb[node].son[1]]]}; MemberId: PROC[id: Name, list: Tree.Link] RETURNS[found: BOOL_FALSE] = { TestItem: Tree.Test = { RETURN[WITH t SELECT FROM hash => IF index = id THEN (found _ TRUE) ELSE FALSE, subtree => TestItem[tb[index].son[1]], ENDCASE => FALSE] }; SearchList[list, TestItem]; RETURN}; HashTest: TYPE = PROC[id: Name] RETURNS[BOOL]; Header: PUBLIC PROC[node: Tree.Index] = { TestShared: HashTest = { RETURN[MemberId[id, tb[node].son[3]] OR MemberId[id, tb[node].son[4]]]}; (dataPtr.table).AddNotify[BCDNotify]; Directory[directory: tb[node].son[1], shared: TestShared]; ScanList[tb[node].son[4], Sharing]; PushCtx[dataPtr.outerCtx]; PushCtx[dataPtr.moduleCtx]; Interfaces[imports: tb[node].son[2], exports: tb[node].son[3]]; PopCtx[]; PopCtx[]; (dataPtr.table).DropNotify[BCDNotify]}; Directory: PROC[directory: Tree.Link, shared: HashTest] = { nIdLists: CARDINAL; mdb[OwnMdi].moduleId _ seb[bb[RootBti].id].hash; nIdLists _ DirectoryScan[directory]; MakeIdTable[nIdLists]; DirectoryDecls[directory, shared]}; MdiMap: TYPE = RECORD[SEQUENCE length: CARDINAL OF MDIndex]; mdiMap: REF MdiMap; DirectoryScan: PROC[t: Tree.Link] RETURNS[nLists: CARDINAL _ 0] = { i: CARDINAL _ 0; FileEntry: Tree.Scan = { node: Tree.Index = GetNode[t]; formalId: Name = seb[ItemLabel[node]].hash; typeId: Name = WITH tb[node].son[2] SELECT FROM hash => index, ENDCASE => formalId; mdiMap[i] _ Copier.EnterFile[formalId, typeId, TreeStringValue[tb[node].son[2]] ! Copier.FileVersionMix => {IF hti = typeId THEN RESUME ELSE REJECT}]; i _ i + 1; IF tb[node].son[3] # Tree.Null THEN nLists _ nLists+1}; n: CARDINAL = ListLength[t]; Copier.CreateFileTable[n]; mdiMap _ NEW[MdiMap[n]]; ScanList[t, FileEntry]; RETURN}; TreeStringValue: PROC[t: Tree.Link] RETURNS[Rope.ROPE] = { RETURN[WITH t SELECT FROM s: Tree.Link.literal => ConvertUnsafe.ToRope[LiteralOps.StringValue[LiteralOps.StringIndex[s.index]]], ENDCASE => NIL] }; DirectoryDecls: PROC[directory: Tree.Link, shared: HashTest] = { i: CARDINAL _ 0; DirectoryItem: Tree.Scan = { node: Tree.Index = GetNode[t]; sei: ISEIndex = ItemLabel[node]; key: Name = WITH tb[node].son[2] SELECT FROM hash => index, ENDCASE => seb[sei].hash; type: CSEIndex; ctx: CTXIndex; bti: CBTIndex; saveIndex: SourceMap.Loc = dataPtr.textIndex; dataPtr.textIndex _ tb[node].info; tb[node].attr2 _ tb[node].attr3 _ P3.mark; Copier.FillModule[sei, key, mdiMap[i] ! Copier.UnknownModule => {Log.ErrorHti[moduleId, hti]; RESUME}]; type _ UnderType[seb[sei].idType]; ctx _ WITH t: seb[type] SELECT FROM definition => t.defCtx, transfer => IF (bti_seb[sei].idInfo) # BTNull THEN bb[bti].localCtx ELSE CTXNull, ENDCASE => CTXNull; IF ctx # CTXNull THEN { WITH c: ctxb[ctx] SELECT FROM included => { dataPtr.objectStamp _ OSMiscOps.MergeStamps[ dataPtr.objectStamp, OSMiscOps.TimeToStamp[mdb[c.module].stamp]]; mdb[c.module].shared _ shared[seb[sei].hash]}; ENDCASE; tb[node].son[3] _ IncludedIds[ctx, tb[node].son[3] ! Copier.FileVersionMix => {IF hti=key THEN RESUME ELSE REJECT}] }; i _ i + 1; dataPtr.textIndex _ saveIndex}; ScanList[directory, DirectoryItem]; mdiMap _ NIL}; IncludedIds: PROC[ctx: CTXIndex, list: Tree.Link] RETURNS[val: Tree.Link] = { includedCtx: IncludedCTXIndex; IncludedId: Tree.Map = { WITH t SELECT FROM hash => { id: Name = index; sei: ISEIndex; found, duplicate, update: BOOL; CheckDuplicate: Tree.Test = { RETURN[WITH t SELECT FROM symbol => IF index = sei THEN (duplicate _ TRUE) ELSE FALSE, ENDCASE => TRUE]}; sei _ SearchContext[id, ctx]; IF sei = ISENull THEN { [found, sei] _ Copier.SearchFileCtx[id, includedCtx]; update _ found} ELSE { found _ TRUE; update _ LinkMode[sei] = manifest; duplicate _ FALSE; SearchList[list, CheckDuplicate]; IF duplicate THEN Log.ErrorHti[duplicateId, id]}; IF found THEN { IF ~seb[sei].public AND ~Shared[includedCtx] THEN { Log.ErrorSei[privateId, sei]; seb[sei].public _ TRUE}; IF update THEN seb[sei].idCtx _ CTXNull; v _ [symbol[index: sei]]} ELSE {Log.ErrorHti[unknownId, id]; v _ t}}; ENDCASE => ERROR; RETURN}; WITH c: ctxb[ctx] SELECT FROM included => IF list # Tree.Null THEN { includedCtx _ LOOPHOLE[ctx]; c.restricted _ TRUE; val _ UpdateList[list, IncludedId]; EnterIdList[includedCtx, val]} ELSE val _ Tree.Null; ENDCASE => ERROR; RETURN}; Sharing: Tree.Scan = { id: Name = GetHash[t]; sei: ISEIndex = SearchContext[id, dataPtr.moduleCtx]; IF sei = ISENull THEN Log.ErrorHti[unknownId, id] ELSE { type: CSEIndex = UnderType[seb[sei].idType]; ctx: CTXIndex _ CTXNull; WITH t: seb[type] SELECT FROM definition => ctx _ t.defCtx; transfer => IF seb[sei].mark4 AND seb[sei].constant AND t.mode = program THEN ctx _ bb[LOOPHOLE[seb[sei].idInfo, CBTIndex]].localCtx; ENDCASE; IF ctx = CTXNull AND type # typeANY THEN Log.ErrorTree[nonInterface, t]} }; ImportType: PROC[mdi: MDIndex] RETURNS[CSEIndex] = { sei: ISEIndex; type: CSEIndex; FOR sei _ FirstCtxSe[dataPtr.moduleCtx], NextSe[sei] UNTIL sei = ISENull DO type _ UnderType[seb[sei].idType]; WITH t: seb[type] SELECT FROM definition => WITH c: ctxb[t.defCtx] SELECT FROM imported => IF ctxb[c.includeLink].module = mdi THEN GO TO Found; ENDCASE; ENDCASE; REPEAT Found => NULL; FINISHED => { sei _ MakeCtxSe[mdb[mdi].moduleId, CTXNull]; Copier.FillModule[sei, seb[sei].hash, mdi]}; ENDLOOP; RETURN[UnderType[seb[sei].idType]]}; Interfaces: PROC[imports, exports: Tree.Link] = INLINE { ScanList[imports, ImportItem]; ScanList[exports, ExportItem]}; ImportItem: Tree.Scan = { node: Tree.Index = GetNode[t]; sei: ISEIndex = ItemLabel[node]; type, vType: CSEIndex; const: BOOL; saveIndex: SourceMap.Loc = dataPtr.textIndex; dataPtr.textIndex _ tb[node].info; tb[node].attr2 _ tb[node].attr3 _ P3.mark; tb[node].son[2] _ Exp[tb[node].son[2], typeANY]; vType _ UType[]; const _ RAttr[].const; RPop[]; WITH v: seb[vType] SELECT FROM definition => SELECT ctxb[v.defCtx].ctxType FROM included => { type _ ImportInstance[iType: vType, named: tb[node].attr1]; IF tb[node].attr1 AND dataPtr.interface THEN Log.ErrorSei[nonDefinition, sei]}; ENDCASE => {type _ typeANY; Log.ErrorTree[notPortable, tb[node].son[2]]}; transfer => { IF v.mode # program OR dataPtr.interface THEN Log.ErrorTree[notPortable, tb[node].son[2]]; seb[sei].immutable _ TRUE; type _ MakeRefType[MakeFrameRecord[tb[node].son[2]], typeANY]; const _ FALSE}; ENDCASE => { IF vType # typeANY THEN Log.ErrorTree[nonInterface, tb[node].son[2]]; type _ typeANY}; seb[sei].idType _ type; seb[sei].immutable _ TRUE; seb[sei].constant _ const; seb[sei].idInfo _ 1; seb[sei].mark3 _ TRUE; dataPtr.textIndex _ saveIndex}; ImportInstance: PROC[iType: CSEIndex, named: BOOL] RETURNS[type: CSEIndex] = { WITH t: seb[iType] SELECT FROM definition => WITH c: ctxb[t.defCtx] SELECT FROM included => { ctx: CTXIndex = NewImportedCtx[LOOPHOLE[t.defCtx]]; type _ MakeNonCtxSe[SERecord.cons.definition.SIZE]; seb[type] _ SERecord[mark3: TRUE, mark4: TRUE, body: cons[definition[ nDummyGfi: t.nDummyGfi, named: named, defCtx: ctx]]]; IF ~named THEN mdb[c.module].defaultImport _ ctx}; ENDCASE => ERROR; ENDCASE => type _ typeANY; RETURN}; NewImportedCtx: PROC[link: IncludedCTXIndex] RETURNS[ctx: CTXIndex] = { ctx _ (dataPtr.table).Words[ctxType, CTXRecord.imported.SIZE]; ctxb[ctx] _ CTXRecord[ levelOrigin: ctxb[link].levelOrigin, levelOffset: ctxb[link].levelOffset, seList: ISENull, varUpdated: FALSE, extension: imported[includeLink: link]]; RETURN}; ExportItem: Tree.Scan = { node: Tree.Index = GetNode[t]; type: CSEIndex; saveIndex: SourceMap.Loc = dataPtr.textIndex; dataPtr.textIndex _ tb[node].info; tb[node].son[2] _ Exp[tb[node].son[2], typeANY]; type _ UType[]; RPop[]; WITH d: seb[type] SELECT FROM definition => { WITH c: ctxb[d.defCtx] SELECT FROM included => mdb[c.module].exported _ TRUE; ENDCASE => Log.ErrorTree[notPortable, tb[node].son[2]]}; ENDCASE => IF type # typeANY THEN Log.ErrorTree[nonInterface, tb[node].son[2]]; dataPtr.textIndex _ saveIndex}; SetDefaultImport: PUBLIC PROC[iCtx: IncludedCTXIndex, implicitOK: BOOL] = { mdi: MDIndex; (dataPtr.table).AddNotify[BCDNotify]; mdi _ ctxb[iCtx].module; IF mdb[mdi].defaultImport = CTXNull THEN { sei: ISEIndex; type: CSEIndex; n: CARDINAL _ 0; IF dataPtr.importCtx = CTXNull THEN dataPtr.importCtx _ NewCtx[lG]; FOR sei _ FirstCtxSe[dataPtr.importCtx], NextSe[sei] UNTIL sei = ISENull DO type _ UnderType[seb[sei].idType]; WITH t: seb[type] SELECT FROM definition => WITH c: ctxb[t.defCtx] SELECT FROM imported => IF ctxb[c.includeLink].module = mdi THEN { mdb[mdi].defaultImport _ t.defCtx; n _ n+1}; ENDCASE; ENDCASE; ENDLOOP; SELECT n FROM 0 => { IF ~implicitOK THEN Log.ErrorHti[missingImport, mdb[mdi].moduleId]; sei _ MakeCtxSe[nullName, dataPtr.importCtx]; FillCtxSe[sei, mdb[mdi].moduleId, FALSE ! NameClash => {Log.ErrorHti[missingImport, name]; RESUME}]; seb[sei].immutable _ seb[sei].constant _ TRUE; seb[sei].linkSpace _ seb[sei].extended _ FALSE; seb[sei].idType _ ImportInstance[iType: ImportType[mdi], named:FALSE]; seb[sei].idInfo _ 1; seb[sei].idValue _ Tree.NullIndex; seb[sei].mark3 _ TRUE; seb[sei].mark4 _ FALSE}; 1 => NULL; ENDCASE => Log.ErrorHti[missingImport, mdb[mdi].moduleId]; IF mdb[mdi].defaultImport = CTXNull THEN mdb[mdi].defaultImport _ NewImportedCtx[iCtx]}; (dataPtr.table).DropNotify[BCDNotify]}; }. dPass3B.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Satterthwaite, April 4, 1986 9:18:48 am PST Maxwell, August 2, 1983 3:17 pm Paul Rovner, September 7, 1983 4:14 pm Russ Atkinson (RRA) March 6, 1985 10:39:44 pm PST called by allocator whenever table area is repacked module header directory processing import/export processing Κ ˜codešœ ™ Kšœ Οmœ1™KšœŸ)˜Kšžœ˜ K˜—Kš  œžœžœžœžœ˜H˜˜šžœžœžœž˜Kš œžœ žœ žœžœžœ˜5K˜&Kšžœžœ˜—šœ˜K˜——K˜Kšžœ˜K˜K˜——Kšœ ™ ˜Kš  œžœžœ žœžœ˜.K˜K˜Kš œžœžœ˜)˜˜Kšžœžœ!˜HK˜—K˜%K˜:K˜#K˜7K˜?K˜K˜'K˜K˜——Kšœ™˜š  œžœ,˜;Kšœ žœ˜K˜0K˜$K˜K˜#K˜K˜—Kš œžœžœžœ žœžœ ˜Kšœžœ˜—šžœ˜ Kšžœžœ.˜EK˜——K˜Kšœžœ1˜JKšœžœ˜K˜K˜—š œžœžœžœ˜Nšžœžœž˜˜ šžœžœž˜"˜ Kšœžœ ˜3Kšœ-žœ˜3šœžœ žœ˜.˜K˜5——Kšžœžœ$˜2—Kšžœžœ˜——Kšžœ˜—Kšžœ˜K˜—š œžœžœ˜GKšœ8žœ˜>˜KšœJ˜JKšœžœ˜$K˜(—Kšžœ˜K˜K˜—˜K˜K˜Kšœ-˜-K˜"K˜Jšžœžœž˜˜šžœžœž˜"Kšœ%žœ˜*Kšžœ1˜8——Kšžœžœžœ.˜O—K˜K˜K˜—š œžœžœ%žœ˜KK˜ K˜%K˜šžœ"žœ˜*K˜K˜Kšœžœ˜Kšžœžœ ˜Cšžœ2žœž˜KK˜"šžœžœž˜˜ šžœžœž˜"˜ šžœ"žœ˜*K˜,——Kšžœ˜——Kšžœ˜—Kšžœ˜—šžœž˜ ˜Kšžœ žœ0˜CK˜-šœ"ž˜'Kšœ3žœ˜<—Kšœ)žœ˜.Kšœ)žœ˜/Kšœ?žœ˜FK˜8Kšœžœžœ˜0—Kšœžœ˜ Kšžœ3˜:—Kšžœ"žœ0˜X—K˜'K˜—˜K˜———…—+φ8χ