RTTSupportImpl.mesa
Copyright © 1984, 1985 by Xerox Corporation. All rights reserved.
designed by Paul Rovner
Richard Koo, July 2, 1984 9:35:44 am PDT
Russ Atkinson (RRA) August 28, 1985 3:06:25 pm PDT
DIRECTORY
AMTypes USING [Error],
Atom USING [MakeAtom],
BcdDefs USING [NullVersion, VersionStamp],
BrandXSymbolDefs USING [contextLevelZero, nullHandle, PreDefinedSEI, StandardSymbolContextIndex, SymbolContextIndex, SymbolIndex, SymbolTableBase],
BrandYSymbolDefs USING [contextLevelZero, nullHandle, PreDefinedSEI, StandardSymbolContextIndex, SymbolContextIndex, SymbolIndex, SymbolTableBase],
ConvertUnsafe USING [EqualSubStrings, SubString, SubStringToRope],
RCMap USING [Index],
RCMapOps USING [Acquire],
Rope USING [ROPE],
RTSymbolDefs USING [nullBase, nullHandle, SymbolConstructorIndex, SymbolIdIndex, SymbolIndex, symbolIndexForANY, SymbolNameIndex, SymbolRecordIndex, SymbolTableBase, SymbolTableHandle],
RTSymbolOps USING [EnumerateCtxIseis, PeelAllButLast, SEUnderType, SETagIDP, NullISEI, SubStringForName, IsSequence, NullStb, NullSth, ISEName],
RTSymbols USING [AcquireSTB, AcquireSTBFromMDI, BaseToHandle, GetSTHForModule, OuterFromMDI, ReleaseSTB],
RTSymbolsPrivate USING [AcquireSTHFromSTX],
RTTypesBasicPrivate USING [Enter, FindCanonicalPTD, FindPTD, FindSTI, GetLastTypeIndex, MakeNewType, MapStiStd, MapTiTd, PTypeDesc, STDesc, SymbolAccess, SymbolTableIndex, UniqueTypeFinger],
RuntimeError USING [UNCAUGHT],
SafeStorage USING [anyType, nullType, Type, TypeIndex, unspecType],
TypeStrings USING [Create, TypeString],
UnsafeStorage USING [GetSystemUZone];
RTTSupportImpl: PROGRAM
IMPORTS AMTypes, Atom, ConvertUnsafe, RCMapOps, RTSymbolOps, RTSymbols, RTSymbolsPrivate, RTTypesBasicPrivate, RuntimeError, TypeStrings, UnsafeStorage
EXPORTS RTSymbolOps, RTSymbols
= BEGIN OPEN bx: BrandXSymbolDefs, by: BrandYSymbolDefs, XRCMapOps: RCMapOps, YRCMapOps: RCMapOps, XTypeStrings: TypeStrings, YTypeStrings: TypeStrings, RTSymbolDefs, RTSymbolOps, RTSymbols, RTSymbolsPrivate, RuntimeError, SafeStorage, TypeStrings;
ROPE: TYPE = Rope.ROPE;
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: BOOLFALSE, 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] = {
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],
t: SymbolTableBase.y =>
YRCMapOps.Acquire[t.e, NARROW[csei, SymbolConstructorIndex.y].e],
ENDCASE => ERROR;
};
[] ← 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 {
WITH stb SELECT FROM
t: SymbolTableBase.x =>
WITH ser: t.e.seb[NARROW[csei, SymbolConstructorIndex.x].e] SELECT FROM
any => GO TO isAny;
ENDCASE;
t: SymbolTableBase.y =>
WITH ser: t.e.seb[NARROW[csei, SymbolConstructorIndex.y].e] SELECT FROM
any => GO TO isAny;
ENDCASE;
ENDCASE => ERROR;
EXITS isAny => {
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],
t: SymbolTableBase.y =>
YRCMapOps.Acquire[t.e, NARROW[csei, SymbolConstructorIndex.y].e],
ENDCASE => ERROR;
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],
t: SymbolTableBase.y =>
YRCMapOps.Acquire[t.e, NARROW[csei, SymbolConstructorIndex.y].e],
ENDCASE => ERROR;
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; UNCAUGHT => GOTO unwind];
EXITS unwind => ERROR;
};
AcquireSequenceType: PUBLIC PROC [stb: SymbolTableBase, sei: SymbolIndex, 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 {
std: RTTypesBasicPrivate.STDesc = STDescFromSTB[ustb];
rcmi: RCMap.Index ← WITH recordSTB SELECT FROM
t: SymbolTableBase.x =>
XRCMapOps.Acquire[t.e, NARROW[recordSEIndex, SymbolRecordIndex.x].e],
t: SymbolTableBase.y =>
YRCMapOps.Acquire[t.e, NARROW[recordSEIndex, SymbolRecordIndex.y].e],
ENDCASE => ERROR;
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; UNCAUGHT => 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: BOOLFALSE] = {
FOR t: TypeIndex IN [FIRST[TypeIndex]..RTTypesBasicPrivate.GetLastTypeIndex[]] DO
IF p[[t]] THEN RETURN[TRUE];
ENDLOOP;
};
ErrorRecord: TYPE = RECORD [type: Type, name: ROPE];
errList: LIST OF ErrorRecord ← NIL;
GetTypeSymbols: PUBLIC PROC [type: Type] RETURNS [stb: SymbolTableBase, sei: SymbolIndex] = {
IF type = nullType THEN ERROR AMTypes.Error[reason: typeFault, type: type];
[stb, sei,] ← DoGetTypeSymbols[type];
};
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];
};
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: BOOLFALSE] RETURNS [stb: SymbolTableBase, sei: SymbolIndex, moduleName: ROPENIL] = {
ptd: RTTypesBasicPrivate.PTypeDesc = RTTypesBasicPrivate.MapTiTd[type];
stInfo: RTTypesBasicPrivate.SymbolAccess ← ptd.symbolAccess;
sth: SymbolTableHandle ← IF originalOnly THEN nullHandle ELSE RTTypesBasicPrivate.MapStiStd[stInfo.sti].sth;
mn: ROPENIL;
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;
IF NOT NullSth[RTTypesBasicPrivate.MapStiStd[i].sth] THEN {
sth ← RTTypesBasicPrivate.MapStiStd[i].sth; EXIT};
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;
IF NOT NullSth[RTTypesBasicPrivate.MapStiStd[i].sth] THEN {
sth ← RTTypesBasicPrivate.MapStiStd[i].sth; EXIT};
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];
};
IF NullStb[stb] THEN {
FOR each: LIST OF ErrorRecord ← errList, each.rest WHILE each # NIL DO
IF each.first.type = type THEN GO TO gleep;
ENDLOOP;
errList ← CONS[[type, moduleName], errList];
GO TO gleep;
EXITS gleep => ERROR AMTypes.Error[reason: noSymbols, msg: moduleName];
};
};
Creation of new runtime Type descriptors
FindCanonicalType: PROC [stb: SymbolTableBase, csei: SymbolConstructorIndex] RETURNS [ptd: RTTypesBasicPrivate.PTypeDesc, ts: TypeString, utf: RTTypesBasicPrivate.UniqueTypeFinger] = {
ts new storage only if ptd = NIL
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, NIL, 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: PROC [outerSTB: SymbolTableBase, sei: SymbolIndex] RETURNS [utf: RTTypesBasicPrivate.UniqueTypeFinger, ustb: SymbolTableBase, usei: SymbolIndex] = {
ComputeUTF might return a new (ustb, usei) only if sei is a SymbolIdIndex
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 (stop ← ConvertUnsafe.EqualSubStrings[ssd1, ssd2]) THEN {
utf ← [umid: NARROW[stb, SymbolTableBase.x].e.stHandle.version, seIndex: LOOPHOLE[isei, SymbolIndex]];
usei ← LOOPHOLE[isei, SymbolIndex];
}
};
IF NOT EnumerateCtxIseis[stb: stb, ctx: [x[ctxr.map]], proc: p] THEN ERROR;
};
OuterFromMDI[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 (stop ← ConvertUnsafe.EqualSubStrings[ssd1, ssd2]) THEN {
utf ← [umid: NARROW[stb, SymbolTableBase.y].e.stHandle.version, seIndex: LOOPHOLE[isei, SymbolIndex]];
usei ← LOOPHOLE[isei, SymbolIndex];
}
};
IF NOT EnumerateCtxIseis[stb: stb, ctx: [y[ctxr.map]], proc: p] THEN ERROR;
};
OuterFromMDI[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.