///users/koo.pa/RTTSupportImpl.tmp
RTTSupportImpl.mesa
Last Modified On October 18, 1983 2:49 pm by Paul Rovner
Last Modified On July 2, 1984 9:35:44 am PDT by Richard Koo
DIRECTORY
AMTypes USING[Error],
Atom USING[MakeAtom],
BcdDefs USING[VersionStamp, NullVersion],
BrandXSymbolDefs
USING[SymbolTableBase, SymbolIndex, SymbolContextIndex, nullHandle,
StandardSymbolContextIndex, contextLevelZero, PreDefinedSEI],
BrandYSymbolDefs
USING[SymbolTableBase, SymbolIndex, SymbolContextIndex, nullHandle,
StandardSymbolContextIndex, contextLevelZero, PreDefinedSEI],
ConvertUnsafe USING[SubString, SubStringToRope, EqualSubStrings],
RCMap USING[Index],
RCMapOps USING[Acquire],
Rope USING[ROPE],
RTSymbolDefs
USING[SymbolTableHandle, nullHandle, SymbolTableBase, SymbolIndex,
SymbolRecordIndex, SymbolNameIndex, nullBase,
SymbolConstructorIndex, nullSymbolIndex, SymbolIdIndex,
symbolIndexForANY],
RTSymbolOps
USING[EnumerateCtxIseis, PeelAllButLast, SEUnderType, SETagIDP, NullISEI,
SubStringForName, IsSequence, NullStb, NullSth, ISEName],
RTSymbols
USING[Outer, AcquireSTBFromMDI, AcquireSTB, ReleaseSTB, BaseToHandle,
GetSTHForModule],
RTSymbolsPrivate USING[AcquireSTHFromSTX],
RTTypesBasicPrivate
USING[UniqueTypeFinger, SymbolAccess,
STDesc, SymbolTableIndex, FindSTI, PTypeDesc, MakeNewType, MapTiTd, MapStiStd, GetLastTypeIndex, FindCanonicalPTD, Enter, FindPTD],
SafeStorage USING[TypeIndex, Type, nullType, unspecType, anyType],
TypeStrings USING[Create, TypeString],
UnsafeStorage USING[GetSystemUZone];
RTTSupportImpl:
PROGRAM
IMPORTS AMTypes, Atom, ConvertUnsafe, RCMapOps, RTSymbolOps,
RTSymbols, RTSymbolsPrivate, RTTypesBasicPrivate, TypeStrings, UnsafeStorage
EXPORTS RTSymbolOps, RTSymbols
=
BEGIN
OPEN bx: BrandXSymbolDefs, by: BrandYSymbolDefs,
XRCMapOps: RCMapOps, YRCMapOps: RCMapOps,
XTypeStrings: TypeStrings, YTypeStrings: TypeStrings,
Rope, RTSymbolDefs, RTSymbolOps, RTSymbols, RTSymbolsPrivate, SafeStorage, TypeStrings;
standardXSTH: SymbolTableHandle ← [x[bx.nullHandle]];
standardYSTH: SymbolTableHandle ← [y[by.nullHandle]];
typeStringZone: UNCOUNTED ZONE = UnsafeStorage.GetSystemUZone[];
*****************************
S U P P O R T F O R T H E D E B U G G E R
AcquireType:
PUBLIC
PROC[stb: SymbolTableBase,
seIndex: SymbolIndex,
canonicalize: BOOL ← FALSE,
rcmi: RCMap.Index ← LAST[RCMap.Index]]
RETURNS[type: Type] = {inner: PROC =
{ ptd: RTTypesBasicPrivate.PTypeDesc;
utf: RTTypesBasicPrivate.UniqueTypeFinger;
ustb: SymbolTableBase;
usei: SymbolIndex;
csei: SymbolConstructorIndex = SEUnderType[stb, seIndex];
isConsType: BOOL = NOT SETagIDP[stb, seIndex];
MakePredefinedType:
PROC[preType: Type] =
INLINE{utf: RTTypesBasicPrivate.UniqueTypeFinger;
ustb: SymbolTableBase;
usei: SymbolIndex;
std: RTTypesBasicPrivate.STDesc;
[utf, ustb, usei] ← ComputeUTF[stb, seIndex];
std ← STDescFromSTB[ustb];
IF stb # ustb THEN ReleaseSTB[ustb];
IF rcmi =
LAST[RCMap.Index]
THEN {rcmi ←
WITH stb
SELECT
FROM
t: SymbolTableBase.x =>
XRCMapOps.Acquire
[t.e,
NARROW[csei, SymbolConstructorIndex.x].e
! AMTypes.Error => REJECT;
UNWIND => NULL;
ANY => GOTO rcMapAcquisitionError],
t: SymbolTableBase.y =>
YRCMapOps.Acquire
[t.e,
NARROW[csei, SymbolConstructorIndex.y].e
! AMTypes.Error => REJECT;
UNWIND => NULL;
ANY => GOTO rcMapAcquisitionError],
ENDCASE => ERROR;
EXITS rcMapAcquisitionError =>
ERROR AMTypes.Error[reason: notImplemented,
msg: "RCMaps for this type"]};
[] ← RTTypesBasicPrivate.MakeNewType
[utf, std, usei,
WITH stb
SELECT
FROM
t: SymbolTableBase.x =>
XTypeStrings.Create
[t.e,
NARROW[csei, SymbolConstructorIndex.x].e,
typeStringZone],
t: SymbolTableBase.y =>
YTypeStrings.Create
[t.e,
NARROW[csei, SymbolConstructorIndex.y].e,
typeStringZone],
ENDCASE => ERROR,
rcmi, FALSE, FALSE, preType]};
IF NullISEI[LOOPHOLE[seIndex]] THEN ERROR;
IF csei = symbolIndexForANY
THEN
{
IF RTTypesBasicPrivate.MapTiTd[unspecType] =
NIL
THEN MakePredefinedType[unspecType];
type ← unspecType;
RETURN};
IF isConsType
THEN
{ isRefAny:
BOOL ←
FALSE;
isAny: BOOL ← FALSE;
WITH stb
SELECT
FROM
t: SymbolTableBase.x =>
WITH ser: t.e.seb[
NARROW[csei, SymbolConstructorIndex.x].e]
SELECT
FROM
any => isAny ← TRUE;
ENDCASE;
t: SymbolTableBase.y =>
WITH ser: t.e.seb[
NARROW[csei, SymbolConstructorIndex.y].e]
SELECT
FROM
any => isAny ← TRUE;
ENDCASE;
ENDCASE => ERROR;
IF isAny
THEN
{
IF RTTypesBasicPrivate.MapTiTd[anyType] =
NIL
THEN MakePredefinedType[anyType];
type ← anyType;
RETURN}};
IF canonicalize
THEN {ts: TypeString;
[ptd, ts, utf] ← FindCanonicalType[stb, csei]; -- ts new storage only if ptd = NIL
IF ptd #
NIL
THEN {type ← ptd.equivalentType; RETURN}
ELSE {std: RTTypesBasicPrivate.STDesc = STDescFromSTB[stb];
IF rcmi =
LAST[RCMap.Index]
THEN
{rcmi ←
WITH stb
SELECT
FROM
t: SymbolTableBase.x =>
XRCMapOps.Acquire
[t.e,
NARROW[csei, SymbolConstructorIndex.x].e
! AMTypes.Error => REJECT;
UNWIND => NULL;
ANY => GOTO rcMapAcquisitionError],
t: SymbolTableBase.y =>
YRCMapOps.Acquire
[t.e,
NARROW[csei, SymbolConstructorIndex.y].e
! AMTypes.Error => REJECT;
UNWIND => NULL;
ANY => GOTO rcMapAcquisitionError],
ENDCASE => ERROR;
EXITS rcMapAcquisitionError =>
ERROR AMTypes.Error[reason: notImplemented,
msg: "RCMaps for this type"]};
type ← RTTypesBasicPrivate.MakeNewType[utf, std,
LOOPHOLE[csei, SymbolIndex],
ts, rcmi, TRUE];
RETURN}}
ELSE {
IF
NOT isConsType
THEN seIndex ←
LOOPHOLE[PeelAllButLast[stb,
LOOPHOLE[seIndex,
SymbolIdIndex]],
SymbolIndex];
[ptd, utf, ustb, usei] ← FindUTF[stb, seIndex];
IF ptd # NIL
THEN {
IF stb # ustb
THEN ReleaseSTB[ustb];
type ← ptd.myType;
RETURN}
ELSE {std: RTTypesBasicPrivate.STDesc = STDescFromSTB[ustb];
IF stb # ustb THEN ReleaseSTB[ustb];
IF rcmi =
LAST[RCMap.Index]
THEN {rcmi ←
WITH stb
SELECT
FROM
t: SymbolTableBase.x =>
XRCMapOps.Acquire
[t.e,
NARROW[csei, SymbolConstructorIndex.x].e
! AMTypes.Error => REJECT;
UNWIND => NULL;
ANY => GOTO rcMapAcquisitionError],
t: SymbolTableBase.y =>
YRCMapOps.Acquire
[t.e,
NARROW[csei, SymbolConstructorIndex.y].e
! AMTypes.Error => REJECT;
UNWIND => NULL;
ANY => GOTO rcMapAcquisitionError],
ENDCASE => ERROR;
EXITS rcMapAcquisitionError =>
ERROR AMTypes.Error[reason: notImplemented,
msg: "RCMaps for this type"]};
type ← RTTypesBasicPrivate.MakeNewType
[utf, std, usei,
WITH stb
SELECT
FROM
t: SymbolTableBase.x =>
XTypeStrings.Create
[t.e,
NARROW[csei, SymbolConstructorIndex.x].e,
typeStringZone],
t: SymbolTableBase.y =>
YTypeStrings.Create
[t.e,
NARROW[csei, SymbolConstructorIndex.y].e,
typeStringZone],
ENDCASE => ERROR,
rcmi];
RETURN}}};
RTTypesBasicPrivate.Enter[inner ! AMTypes.Error => REJECT; UNWIND => NULL; ANY => GOTO unwind];
EXITS unwind => ERROR};
AcquireSequenceType:
PUBLIC
PROC[stb: SymbolTableBase,
sei: SymbolIndex, -- of sequence part
recordSTB: SymbolTableBase,
recordSEIndex: SymbolRecordIndex]
RETURNS[type: Type] = {inner: PROC =
{ ptd: RTTypesBasicPrivate.PTypeDesc;
utf: RTTypesBasicPrivate.UniqueTypeFinger;
ustb: SymbolTableBase;
usei: SymbolIndex;
csei: SymbolConstructorIndex = SEUnderType[stb, sei];
IF NOT IsSequence[stb, sei] THEN ERROR;
IF SETagIDP[stb, sei]
THEN sei ← LOOPHOLE[PeelAllButLast[stb, LOOPHOLE[sei, SymbolIdIndex]], SymbolIndex];
[ptd, utf, ustb, usei] ← FindUTF[stb, sei];
IF ptd #
NIL
THEN {
IF stb # ustb
THEN ReleaseSTB[ustb];
type ← ptd.myType}
ELSE {rcmi: RCMap.Index;
std: RTTypesBasicPrivate.STDesc = STDescFromSTB[ustb];
{rcmi ←
WITH recordSTB
SELECT
FROM
t: SymbolTableBase.x =>
XRCMapOps.Acquire
[t.e,
NARROW[recordSEIndex, SymbolRecordIndex.x].e
! AMTypes.Error => REJECT;
UNWIND => NULL;
ANY => GOTO rcMapAcquisitionError],
t: SymbolTableBase.y =>
YRCMapOps.Acquire
[t.e,
NARROW[recordSEIndex, SymbolRecordIndex.y].e
! AMTypes.Error => REJECT;
UNWIND => NULL;
ANY => GOTO rcMapAcquisitionError],
ENDCASE => ERROR;
EXITS rcMapAcquisitionError =>
ERROR AMTypes.Error[reason: notImplemented,
msg: "RCMaps for this type"]};
IF stb # ustb THEN ReleaseSTB[ustb];
type ← RTTypesBasicPrivate.MakeNewType
[utf,
std,
usei,
WITH recordSTB
SELECT
FROM
t: SymbolTableBase.x =>
XTypeStrings.Create
[t.e,
NARROW[recordSEIndex, SymbolRecordIndex.x].e,
typeStringZone],
t: SymbolTableBase.y =>
YTypeStrings.Create
[t.e,
NARROW[recordSEIndex, SymbolRecordIndex.y].e,
typeStringZone],
ENDCASE => ERROR,
rcmi]}};
RTTypesBasicPrivate.Enter[inner ! AMTypes.Error => REJECT; UNWIND => NULL; ANY => GOTO unwind];
EXITS unwind => ERROR};
AcquireRope:
PUBLIC
PROC[stb: SymbolTableBase, hti: SymbolNameIndex]
RETURNS[ROPE] = {RETURN[ConvertUnsafe.SubStringToRope[SubStringForName[stb, hti]]]};
AcquireAtom:
PUBLIC
PROC[stb: SymbolTableBase, hti: SymbolNameIndex]
RETURNS[atom: ATOM] ={RETURN[Atom.MakeAtom[AcquireRope[stb, hti]]]};
EnumerateTypes:
PROC[p:
PROC[Type]
RETURNS[stop:
BOOL]]
RETURNS[stopped: BOOL ← FALSE] =
{
FOR t: TypeIndex
IN [
FIRST[TypeIndex]..RTTypesBasicPrivate.GetLastTypeIndex[]]
DO IF p[[t]] THEN RETURN[TRUE] ENDLOOP};
GetTypeSymbols:
PUBLIC
PROC[type: Type]
RETURNS[stb: SymbolTableBase, sei: SymbolIndex] =
{ moduleName:
ROPE;
IF type = nullType THEN ERROR AMTypes.Error[reason: typeFault, type: type];
[stb, sei, moduleName] ← DoGetTypeSymbols[type];
IF NullStb[stb] THEN ERROR AMTypes.Error[reason: noSymbols, msg: moduleName]};
GetOriginalTypeSymbols:
PUBLIC
PROC[type: Type]
RETURNS[stb: SymbolTableBase, sei: SymbolIndex] =
{
IF type = nullType
THEN
ERROR AMTypes.Error[reason: typeFault, type: type];
[stb, sei,] ← DoGetTypeSymbols[type, TRUE];
IF NullStb[stb] THEN ERROR AMTypes.Error[reason: noSymbols]};
IsPreDefinedSEI:
PROC[sei: SymbolIndex]
RETURNS[
BOOL] =
{
RETURN[
WITH sei
SELECT
FROM
t: SymbolIndex.x => LOOPHOLE[t.e, CARDINAL] IN bx.PreDefinedSEI,
t: SymbolIndex.y => LOOPHOLE[t.e, CARDINAL] IN by.PreDefinedSEI,
ENDCASE => ERROR]};
DoGetTypeSymbols:
PROC[type: Type, originalOnly:
BOOL ←
FALSE]
RETURNS[stb: SymbolTableBase, sei: SymbolIndex, moduleName: ROPE ← NIL] = {
ptd: RTTypesBasicPrivate.PTypeDesc = RTTypesBasicPrivate.MapTiTd[type];
stInfo: RTTypesBasicPrivate.SymbolAccess ← ptd.symbolAccess;
sth: SymbolTableHandle ← IF originalOnly THEN nullHandle ELSE RTTypesBasicPrivate.MapStiStd[stInfo.sti].sth;
mn: ROPE ← NIL;
anySTHWillDo:
BOOL
← (ptd.utf.umid = BcdDefs.NullVersion AND IsPreDefinedSEI[ptd.utf.seIndex]);
originalUTF:
BOOL
← NOT(ptd.utf.umid = BcdDefs.NullVersion OR IsPreDefinedSEI[ptd.utf.seIndex]);
sei ← IF originalOnly AND originalUTF THEN ptd.utf.seIndex ELSE stInfo.sei;
IF NullSth[sth]
THEN
IF anySTHWillDo
THEN {
-- standard symbol; any table will do
IF
NOT (
IF sei.brand = x
THEN NullSth[standardXSTH]
ELSE NullSth[standardYSTH])
THEN sth ← (IF sei.brand = x THEN standardXSTH ELSE standardYSTH)
ELSE
FOR i: RTTypesBasicPrivate.SymbolTableIndex
IN [1..RTTypesBasicPrivate.MapStiStd.length)
DO
IF RTTypesBasicPrivate.MapStiStd[i] = NIL THEN LOOP
ELSE IF NOT NullSth[RTTypesBasicPrivate.MapStiStd[i].sth] THEN {sth ← RTTypesBasicPrivate.MapStiStd[i].sth; EXIT}
ELSE {
-- go find the symbol table bits
[sth: sth, moduleName: mn] ← AcquireSTHFromSTX[i];
IF moduleName = NIL THEN moduleName ← mn;
RTTypesBasicPrivate.MapStiStd[i].sth ← sth;
IF NOT NullSth[sth] THEN EXIT; -- found one
};
ENDLOOP;
}
ELSE {
-- go find the symbol table bits
IF originalOnly
AND originalUTF
THEN sth ← GetSTHForModule[ptd.utf.umid,
NIL,
NIL
! AMTypes.Error => CONTINUE]
ELSE {
[sth: sth, moduleName: moduleName] ← AcquireSTHFromSTX[stInfo.sti];
RTTypesBasicPrivate.MapStiStd[stInfo.sti].sth ← sth;
IF NullSth[sth]
AND originalUTF
THEN {
-- try for the original defining module
std: RTTypesBasicPrivate.STDesc = [symbolsStamp: ptd.utf.umid, bcd: RTTypesBasicPrivate.MapStiStd[stInfo.sti].bcd];
sei ← ptd.utf.seIndex;
IF anySTHWillDo
THEN {
IF
NOT (
IF sei.brand = x
THEN NullSth[standardXSTH]
ELSE NullSth[standardYSTH])
THEN sth ← (
IF sei.brand = x
THEN standardXSTH
ELSE standardYSTH)
ELSE
FOR i: RTTypesBasicPrivate.SymbolTableIndex
IN [1..RTTypesBasicPrivate.MapStiStd.length)
DO
IF RTTypesBasicPrivate.MapStiStd[i] = NIL THEN LOOP
ELSE IF NOT NullSth[RTTypesBasicPrivate.MapStiStd[i].sth]
THEN {sth ← RTTypesBasicPrivate.MapStiStd[i].sth; EXIT}
ELSE {
-- go find the symbol table bits
[sth: sth, moduleName: mn] ← AcquireSTHFromSTX[i];
IF moduleName = NIL THEN moduleName ← mn;
RTTypesBasicPrivate.MapStiStd[i].sth ← sth;
IF NOT NullSth[sth] THEN EXIT; -- found one
};
ENDLOOP;
}
ELSE {
[sth: sth, moduleName: mn] ← AcquireSTHFromSTX[RTTypesBasicPrivate.FindSTI[std]];
IF moduleName = NIL THEN moduleName ← mn;
};
};
};
};
IF NullSth[sth]
THEN stb ← nullBase
ELSE {
WITH sth
SELECT
FROM
t: SymbolTableHandle.x => IF NullSth[standardXSTH] THEN standardXSTH ← sth;
t: SymbolTableHandle.y => IF NullSth[standardYSTH] THEN standardYSTH ← sth;
ENDCASE => ERROR;
stb ← AcquireSTB[sth];
};
Creation of new runtime Type descriptors
ts new storage only if ptd = NIL
FindCanonicalType:
PROC[stb: SymbolTableBase, csei: SymbolConstructorIndex]
RETURNS[ptd: RTTypesBasicPrivate.PTypeDesc, ts: TypeString, utf: RTTypesBasicPrivate.UniqueTypeFinger] =
{ ts ←
WITH stb
SELECT
FROM
t: SymbolTableBase.x => XTypeStrings.Create
[t.e,
NARROW[csei, SymbolConstructorIndex.x].e,
typeStringZone],
t: SymbolTableBase.y => YTypeStrings.Create
[t.e,
NARROW[csei, SymbolConstructorIndex.y].e,
typeStringZone],
ENDCASE => ERROR;
ptd ← RTTypesBasicPrivate.FindCanonicalPTD[ts];
IF ptd #
NIL
THEN {typeStringZone.FREE[@ts]; RETURN[ptd, ts, ptd.utf]}
ELSE {[utf,,] ← ComputeUTF[stb, LOOPHOLE[csei, SymbolIndex]]; RETURN[NIL, ts, utf]}};
Recognize identical type previously entered
hash map: UniqueTypeFinger -> TypeIndex
FindUTF:
PROC [stb: SymbolTableBase, sei: SymbolIndex]
RETURNS[ptd: RTTypesBasicPrivate.PTypeDesc,
utf: RTTypesBasicPrivate.UniqueTypeFinger,
ustb: SymbolTableBase,
usei: SymbolIndex] =
{ [utf, ustb, usei] ← ComputeUTF[stb, sei];
RETURN[RTTypesBasicPrivate.FindPTD[utf], utf, ustb, usei]};
ComputeUTF might return a new (ustb, usei) only if sei is a SymbolIdIndex
ComputeUTF:
PROC [outerSTB: SymbolTableBase, sei: SymbolIndex]
RETURNS[utf: RTTypesBasicPrivate.UniqueTypeFinger, ustb: SymbolTableBase, usei: SymbolIndex] =
{
WITH outerSTB
SELECT
FROM
t: SymbolTableBase.x =>
[utf, ustb, usei] ← ComputeUTFX[t.e, NARROW[sei, SymbolIndex.x].e];
t: SymbolTableBase.y =>
[utf, ustb, usei] ← ComputeUTFY[t.e, NARROW[sei, SymbolIndex.y].e];
ENDCASE => ERROR};
ComputeUTFX:
PROC [outerSTB: bx.SymbolTableBase, sei: bx.SymbolIndex]
RETURNS[utf: RTTypesBasicPrivate.UniqueTypeFinger, ustb: SymbolTableBase, usei: SymbolIndex] =
{ ustb ← [x[outerSTB]];
usei ← [x[sei]];
WITH ser: outerSTB.seb[sei]
SELECT
FROM
id =>
IF ser.idCtx
IN bx.StandardSymbolContextIndex
THEN utf ← [umid: BcdDefs.NullVersion, seIndex: usei] -- a primitive type
ELSE
WITH ctxr: outerSTB.ctxb[ser.idCtx]
SELECT
FROM
included =>
IF ctxr.level # bx.contextLevelZero
THEN utf ← [umid: outerSTB.mdb[ctxr.module].stamp,
seIndex: [x[LOOPHOLE[ser.idValue, bx.SymbolIndex]]]]
ELSE
{ inner:
PROC[stb: SymbolTableBase] =
{ p:
PROC[stb: SymbolTableBase, isei: SymbolIdIndex]
RETURNS[stop: BOOL] =
{ ssd1: ConvertUnsafe.SubString
= SubStringForName[[x[outerSTB]], [x[ser.hash]]];
ssd2: ConvertUnsafe.SubString
= SubStringForName[stb, ISEName[stb, isei]];
IF ConvertUnsafe.EqualSubStrings[ssd1, ssd2]
THEN
{utf ← [umid:
NARROW[stb, SymbolTableBase.x].e.stHandle.version,
seIndex: LOOPHOLE[isei, SymbolIndex]];
usei ← LOOPHOLE[isei, SymbolIndex];
RETURN[TRUE]}
ELSE RETURN[FALSE];
};
IF
NOT EnumerateCtxIseis[stb: stb, ctx: [x[ctxr.map]], proc: p]
THEN ERROR;
};
Outer[stb: [x[outerSTB]], mdi: [x[ctxr.module]], inner: inner];
ustb ← AcquireSTBFromMDI[[x[outerSTB]], [x[ctxr.module]]];
RETURN
};
ENDCASE => utf ← [umid: outerSTB.stHandle.version, seIndex: [x[sei]]];
cons => utf ← [umid: (
IF IsPreDefinedSEI[[x[sei]]]
THEN BcdDefs.NullVersion
ELSE outerSTB.stHandle.version), -- NOTE
seIndex: [x[sei]]];
ENDCASE => ERROR};
ComputeUTFY:
PROC [outerSTB: by.SymbolTableBase, sei: by.SymbolIndex]
RETURNS[utf: RTTypesBasicPrivate.UniqueTypeFinger, ustb: SymbolTableBase, usei: SymbolIndex] =
{ ustb ← [y[outerSTB]];
usei ← [y[sei]];
WITH ser: outerSTB.seb[sei]
SELECT
FROM
id =>
IF ser.idCtx
IN by.StandardSymbolContextIndex
THEN utf ← [umid: BcdDefs.NullVersion, seIndex: usei] -- a primitive type
ELSE
WITH ctxr: outerSTB.ctxb[ser.idCtx]
SELECT
FROM
included =>
IF ctxr.level # by.contextLevelZero
THEN utf ← [umid: outerSTB.mdb[ctxr.module].stamp,
seIndex: [y[LOOPHOLE[ser.idValue, by.SymbolIndex]]]]
ELSE
{ inner:
PROC[stb: SymbolTableBase] =
{ p:
PROC[stb: SymbolTableBase, isei: SymbolIdIndex]
RETURNS[stop: BOOL] =
{ ssd1: ConvertUnsafe.SubString
= SubStringForName[[y[outerSTB]], [y[ser.hash]]];
ssd2: ConvertUnsafe.SubString
= SubStringForName[stb, ISEName[stb, isei]];
IF ConvertUnsafe.EqualSubStrings[ssd1, ssd2]
THEN
{utf ← [umid:
NARROW[stb, SymbolTableBase.y].e.stHandle.version,
seIndex: LOOPHOLE[isei, SymbolIndex]];
usei ← LOOPHOLE[isei, SymbolIndex];
RETURN[TRUE]}
ELSE RETURN[FALSE];
};
IF
NOT EnumerateCtxIseis[stb: stb, ctx: [y[ctxr.map]], proc: p]
THEN ERROR;
};
Outer[stb: [y[outerSTB]], mdi: [y[ctxr.module]], inner: inner];
ustb ← AcquireSTBFromMDI[[y[outerSTB]], [y[ctxr.module]]];
RETURN
};
ENDCASE => utf ← [umid: outerSTB.stHandle.version, seIndex: [y[sei]]];
cons => utf ← [umid: (
IF IsPreDefinedSEI[[y[sei]]]
THEN BcdDefs.NullVersion
ELSE outerSTB.stHandle.version), -- NOTE
seIndex: [y[sei]]];
ENDCASE => ERROR};
STDescFromSTB:
PROC[stb: SymbolTableBase]
RETURNS[RTTypesBasicPrivate.STDesc] =
{ version: BcdDefs.VersionStamp =
(
WITH stb
SELECT
FROM
t: SymbolTableBase.x => t.e.stHandle.version,
t: SymbolTableBase.y => t.e.stHandle.version
ENDCASE => ERROR);
RETURN[[symbolsStamp: version, sth: RTSymbols.BaseToHandle[stb]]]};
END.