DIRECTORY
Basics: TYPE USING [BITXOR],
BcdDefs: TYPE USING [Base, BcdBase, FTNull, MTIndex],
CompilerOps: TYPE USING [Transaction],
CS: TYPE USING [EndsIn, PartialName, z],
FS: TYPE USING [Close, Error, GetInfo, Open, OpenFile, nullOpenFile, Read],
HashTable: TYPE USING [Table, Create, Erase, ForEach, Fetch, Store],
Rope: TYPE USING [Concat, --Equal,-- ROPE],
SMProj: TYPE USING [Proj, ProjInfo],
TimeStamp: TYPE USING [Stamp],
VM: TYPE USING [AddressForPageNumber, Allocate, Free, Interval, nullInterval];
SMProjImpl:
CEDAR
MONITOR
IMPORTS Basics, CS, FS, HashTable, Rope, VM
EXPORTS SMProj ~ {
Proj: TYPE ~ SMProj.Proj; -- can't be opaque with current RedBlackTree impl
Fill:
PUBLIC
ENTRY
PROC[proj: Proj, localName, wDir: Rope.
ROPE, new:
BOOL] ~ {
ENABLE UNWIND => {NULL};
IF proj.state < $opened
THEN {
proj.localName ←
(IF CS.EndsIn[localName, ".bcd"] THEN localName ELSE localName.Concat[".bcd"]);
proj.wDir ← (IF CS.PartialName[localName] THEN wDir ELSE NIL);
IF ~new AND ~proj.cantOpen THEN OpenProj[proj]};
};
Find:
PUBLIC
ENTRY
PROC[stamp: TimeStamp.Stamp]
RETURNS[proj: Proj] ~ {
ENABLE UNWIND => {NULL};
proj ← table.Fetch[stamp].value;
IF proj =
NIL
THEN {
proj ← (CS.z).NEW[SMProj.ProjInfo ← [stamp~stamp, state~$empty]];
[] ← table.Store[stamp, proj]};
RETURN};
Read:
PUBLIC
ENTRY
PROC[proj: Proj]
RETURNS[pages: VM.Interval, base: BcdDefs.BcdBase] ~ {
ENABLE UNWIND => {NULL};
RETURN (
IF proj =
NIL
OR proj.file =
FS.nullOpenFile
THEN [VM.nullInterval, NIL] ELSE LoadUpBcd[proj.file])
};
FindFile:
PROC[proj: Proj]
RETURNS[file:
FS.OpenFile] ~ {
file ←
FS.Open[name~proj.localName, wDir~proj.wDir
! FS.Error => {file ← FS.nullOpenFile; CONTINUE}];
RETURN};
OpenProj:
PROC[proj: Proj] ~ {
file: FS.OpenFile ~ FindFile[proj];
IF file = FS.nullOpenFile THEN proj.cantOpen ← TRUE
ELSE
IF proj.state = $analyzed
THEN {
proj.file ← file; proj.state ← $opened}
ELSE
TRUSTED {
bcdBase: BcdDefs.BcdBase;
interval: VM.Interval;
[interval, bcdBase] ← LoadUpBcd[file];
IF bcdBase.version ~= proj.stamp THEN proj.cantOpen ← TRUE
ELSE {
-- should reject configs, etc.
firstMti: BcdDefs.MTIndex ~ BcdDefs.MTIndex.FIRST;
mtb: BcdDefs.Base ~ LOOPHOLE[bcdBase + bcdBase.mtOffset];
sgb: BcdDefs.Base ~ LOOPHOLE[bcdBase + bcdBase.sgOffset];
proj.interface ← bcdBase.definitions;
proj.symbolPages ← (
IF sgb[mtb[firstMti].sseg].file = BcdDefs.FTNull
THEN [base~0, pages~0]
ELSE [base~sgb[mtb[firstMti].sseg].base-1, pages~sgb[mtb[firstMti].sseg].pages]);
proj.file ← file;
proj.state ← $opened};
VM.Free[interval]};
};
for proj info provided by the compiler
Update:
PUBLIC
ENTRY
PROC[
proj: Proj, parms: REF READONLY CompilerOps.Transaction] ~ {
ENABLE UNWIND => {NULL};
IF proj.stamp # parms.objectVersion THEN ERROR;
proj.interface ← parms.interface;
IF ~(proj.localName).Equal[parms.objectName, FALSE] THEN
proj.localName ← parms.objectName;
proj.file ← parms.objectFile;
proj.symbolPages ← [parms.symbolPages.base-1, parms.symbolPages.pages];
proj.cantOpen ← FALSE; proj.state ← $opened};