DIRECTORY
PrincOps USING[SD],
RTSD USING[sMapStiStd],
RTSymbolDefs USING[nullHandle],
RTTypesBasicPrivate USING[STDesc, SymbolTableIndex, InitialSTIRangeSize, MapStiStd, LOOPHOLEDTMapStiStd, RSTDesc, RMapStiStd],
SafeStorage USING[TypeIndex],
UnsafeStorage USING[GetSystemUZone];
SymbolAccessImpl:
MONITOR
-- protects MapStiStd
IMPORTS RTTypesBasicPrivate, UnsafeStorage
EXPORTS RTTypesBasicPrivate
lastSTIndex: TypeIndex ← 0;
TooManyTypes: ERROR = CODE;
Bless
MapStiStd:
PUBLIC
ENTRY
PROC = {
ENABLE UNWIND => NULL;
t: LOOPHOLEDTMapStiStd = LOOPHOLE[MapStiStd];
LOOPHOLE[MapStiStd, LOOPHOLEDTMapStiStd] ← NIL;
MapStiStd ← NEW[RMapStiStd[InitialSTIRangeSize]];
FOR i: SymbolTableIndex
IN [1..lastSTIndex]
DO MapStiStd[i] ← NEW[STDesc ← t[i]^] ENDLOOP;
LOOPHOLE[
LONG[@PrincOps
.SD[
RTSD.sMapStiStd]],
LONG
POINTER
TO
LONG
POINTER]^
← LOOPHOLE[MapStiStd, LONG POINTER];
};
FindSTI:
PUBLIC
ENTRY
PROC[std: STDesc, initializing:
BOOL]
RETURNS[i: SymbolTableIndex] = {
ENABLE UNWIND => NULL;
FOR i
IN [1..lastSTIndex]
DO
IF MapStiStd[i].symbolsStamp = std.symbolsStamp
AND (std.bcd =
NIL
OR std.sgi = MapStiStd[i].sgi)
THEN {
IF MapStiStd[i].sth = RTSymbolDefs.nullHandle
THEN {
IF initializing
THEN LOOPHOLE[MapStiStd, LOOPHOLEDTMapStiStd][i].sth ← std.sth
ELSE MapStiStd[i].sth ← std.sth;
};
RETURN[i];
};
ENDLOOP;
IF lastSTIndex = InitialSTIRangeSize - 1 THEN ERROR TooManyTypes;
i ← lastSTIndex ← lastSTIndex + 1;
IF initializing
THEN
LOOPHOLE[MapStiStd, LOOPHOLEDTMapStiStd][i]
← UnsafeStorage.GetSystemUZone[].NEW[STDesc ← std]
ELSE MapStiStd[i] ← NEW[STDesc ← std];
};